diff options
83 files changed, 1650 insertions, 733 deletions
@@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -197,7 +197,19 @@ BL_COMMON_SOURCES += common/bl_common.c \ lib/aarch64/cache_helpers.S \ lib/aarch64/misc_helpers.S \ lib/aarch64/xlat_helpers.c \ - lib/stdlib/std.c \ + lib/stdlib/abort.c \ + lib/stdlib/assert.c \ + lib/stdlib/exit.c \ + lib/stdlib/mem.c \ + lib/stdlib/printf.c \ + lib/stdlib/putchar.c \ + lib/stdlib/puts.c \ + lib/stdlib/sscanf.c \ + lib/stdlib/strchr.c \ + lib/stdlib/strcmp.c \ + lib/stdlib/strlen.c \ + lib/stdlib/strncmp.c \ + lib/stdlib/subr_prf.c \ plat/common/aarch64/platform_helpers.S INCLUDES += -Iinclude/bl1 \ @@ -294,9 +306,9 @@ ifneq (${ENABLE_PLAT_COMPAT}, 0) include plat/compat/plat_compat.mk endif -# Include the CPU specific operations makefile. By default all CPU errata -# workarounds and CPU specific optimisations are disabled. This can be -# overridden by the platform. +# Include the CPU specific operations makefile, which provides default +# values for all CPU errata workarounds and CPU specific optimisations. +# This can be overridden by the platform. include lib/cpus/cpu-ops.mk diff --git a/bl1/bl1_context_mgmt.c b/bl1/bl1_context_mgmt.c index 6355190e..bd40608b 100644 --- a/bl1/bl1_context_mgmt.c +++ b/bl1/bl1_context_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -74,7 +74,7 @@ void bl1_prepare_next_image(unsigned int image_id) next_bl_ep = &image_desc->ep_info; /* Get the image security state. */ - security_state = GET_SEC_STATE(next_bl_ep->h.attr); + security_state = GET_SECURITY_STATE(next_bl_ep->h.attr); /* Setup the Secure/Non-Secure context if not done already. */ if (!cm_get_context(security_state)) diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c index 80ce831a..f3338051 100644 --- a/bl1/bl1_fwu.c +++ b/bl1/bl1_fwu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -135,8 +135,8 @@ static int bl1_fwu_image_copy(unsigned int image_id, } /* Only Normal world is allowed to copy a Secure image. */ - if ((GET_SEC_STATE(flags) == SECURE) || - (GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE)) { + if ((GET_SECURITY_STATE(flags) == SECURE) || + (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == NON_SECURE)) { WARN("BL1-FWU: Copy not allowed for Non-Secure " "image from Secure-world\n"); return -EPERM; @@ -156,10 +156,10 @@ static int bl1_fwu_image_copy(unsigned int image_id, * If last block is more than expected then * clip the block to the required image size. */ - if (image_desc->image_info.copied_size + block_size > + if (image_desc->copied_size + block_size > image_desc->image_info.image_size) { block_size = image_desc->image_info.image_size - - image_desc->image_info.copied_size; + image_desc->copied_size; WARN("BL1-FWU: Copy argument block_size > remaining image size." " Clipping block_size\n"); } @@ -173,13 +173,13 @@ static int bl1_fwu_image_copy(unsigned int image_id, INFO("BL1-FWU: Continuing image copy in blocks\n"); /* Copy image for given block size. */ - base_addr += image_desc->image_info.copied_size; - image_desc->image_info.copied_size += block_size; + base_addr += image_desc->copied_size; + image_desc->copied_size += block_size; memcpy((void *)base_addr, (const void *)image_src, block_size); flush_dcache_range(base_addr, block_size); /* Update the state if last block. */ - if (image_desc->image_info.copied_size == + if (image_desc->copied_size == image_desc->image_info.image_size) { image_desc->state = IMAGE_STATE_COPIED; INFO("BL1-FWU: Image copy in blocks completed\n"); @@ -234,7 +234,7 @@ static int bl1_fwu_image_copy(unsigned int image_id, INFO("BL1-FWU: Started image copy in blocks\n"); } - image_desc->image_info.copied_size = block_size; + image_desc->copied_size = block_size; } return 0; @@ -257,14 +257,14 @@ static int bl1_fwu_image_auth(unsigned int image_id, if (!image_desc) return -EPERM; - if (GET_SEC_STATE(flags) == SECURE) { + if (GET_SECURITY_STATE(flags) == SECURE) { if (image_desc->state != IMAGE_STATE_RESET) { WARN("BL1-FWU: Authentication from secure world " "while in invalid state\n"); return -EPERM; } } else { - if (GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE) { + if (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE) { if (image_desc->state != IMAGE_STATE_COPIED) { WARN("BL1-FWU: Authentication of secure image " "from non-secure world while not in copied state\n"); @@ -369,10 +369,10 @@ static int bl1_fwu_image_execute(unsigned int image_id, * Image is NOT in AUTHENTICATED state. */ if ((!image_desc) || - (GET_SEC_STATE(flags) == SECURE) || - (GET_SEC_STATE(image_desc->ep_info.h.attr) == NON_SECURE) || - (GET_EXEC_STATE(image_desc->image_info.h.attr) == NON_EXECUTABLE) || - (image_desc->state != IMAGE_STATE_AUTHENTICATED)) { + (GET_SECURITY_STATE(flags) == SECURE) || + (GET_SECURITY_STATE(image_desc->ep_info.h.attr) == NON_SECURE) || + (EP_GET_EXE(image_desc->ep_info.h.attr) == NON_EXECUTABLE) || + (image_desc->state != IMAGE_STATE_AUTHENTICATED)) { WARN("BL1-FWU: Execution not allowed due to invalid state/args\n"); return -EPERM; } @@ -402,7 +402,7 @@ static register_t bl1_fwu_image_resume(register_t image_param, { image_desc_t *image_desc; unsigned int resume_sec_state; - unsigned int caller_sec_state = GET_SEC_STATE(flags); + unsigned int caller_sec_state = GET_SECURITY_STATE(flags); /* Get the image descriptor for last executed secure image id. */ image_desc = bl1_plat_get_image_desc(sec_exec_image_id); @@ -417,8 +417,8 @@ static register_t bl1_fwu_image_resume(register_t image_param, assert(image_desc); } - assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE); - assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE); + assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE); + assert(EP_GET_EXE(image_desc->ep_info.h.attr) == EXECUTABLE); if (caller_sec_state == SECURE) { assert(image_desc->state == IMAGE_STATE_EXECUTED); @@ -458,7 +458,7 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) image_desc_t *image_desc; /* Make sure caller is from the secure world */ - if (GET_SEC_STATE(flags) == NON_SECURE) { + if (GET_SECURITY_STATE(flags) == NON_SECURE) { WARN("BL1-FWU: Image done not allowed from normal world\n"); return -EPERM; } @@ -468,8 +468,8 @@ static int bl1_fwu_sec_image_done(void **handle, unsigned int flags) /* image_desc must correspond to a valid secure executing image */ assert(image_desc); - assert(GET_SEC_STATE(image_desc->ep_info.h.attr) == SECURE); - assert(GET_EXEC_STATE(image_desc->image_info.h.attr) == EXECUTABLE); + assert(GET_SECURITY_STATE(image_desc->ep_info.h.attr) == SECURE); + assert(EP_GET_EXE(image_desc->ep_info.h.attr) == EXECUTABLE); assert(image_desc->state == IMAGE_STATE_EXECUTED); /* Update the flags. */ diff --git a/bl1/tbbr/tbbr_img_desc.c b/bl1/tbbr/tbbr_img_desc.c index 42de8517..7651f1c0 100644 --- a/bl1/tbbr/tbbr_img_desc.c +++ b/bl1/tbbr/tbbr_img_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,42 +35,46 @@ image_desc_t bl1_tbbr_image_descs[] = { { .image_id = FWU_CERT_ID, - .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_1, image_info_t, 0), .image_info.image_base = BL2_BASE, - .ep_info.h.attr = SET_SEC_STATE(SECURE), + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_1, entry_point_info_t, SECURE), }, #if NS_BL1U_BASE { .image_id = NS_BL1U_IMAGE_ID, - .image_info.h.attr = SET_EXEC_STATE(EXECUTABLE), - .image_info.image_base = NS_BL1U_BASE, - .ep_info.h.attr = SET_SEC_STATE(NON_SECURE), + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_1, entry_point_info_t, NON_SECURE | EXECUTABLE), .ep_info.pc = NS_BL1U_BASE, }, #endif #if SCP_BL2U_BASE { .image_id = SCP_BL2U_IMAGE_ID, - .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY, + VERSION_1, image_info_t, 0), .image_info.image_base = SCP_BL2U_BASE, - .ep_info.h.attr = SET_SEC_STATE(SECURE), + SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY, + VERSION_1, entry_point_info_t, SECURE), }, #endif #if BL2U_BASE { .image_id = BL2U_IMAGE_ID, - .image_info.h.attr = SET_EXEC_STATE(EXECUTABLE), + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, + VERSION_1, image_info_t, 0), .image_info.image_base = BL2U_BASE, - .ep_info.h.attr = SET_SEC_STATE(SECURE), + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_1, entry_point_info_t, SECURE | EXECUTABLE), .ep_info.pc = BL2U_BASE, }, #endif #if NS_BL2U_BASE { .image_id = NS_BL2U_IMAGE_ID, - .image_info.h.attr = SET_EXEC_STATE(NON_EXECUTABLE), - .image_info.image_base = NS_BL2U_BASE, - .ep_info.h.attr = SET_SEC_STATE(NON_SECURE), + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, + VERSION_1, entry_point_info_t, NON_SECURE), }, #endif BL2_IMAGE_DESC, diff --git a/bl31/runtime_svc.c b/bl31/runtime_svc.c index 5b7a21cd..f011f112 100644 --- a/bl31/runtime_svc.c +++ b/bl31/runtime_svc.c @@ -103,8 +103,8 @@ void runtime_svc_init(void) */ rc = validate_rt_svc_desc(&rt_svc_descs[index]); if (rc) { - ERROR("Invalid runtime service descriptor 0x%lx (%s)\n", - (uintptr_t) &rt_svc_descs[index], + ERROR("Invalid runtime service descriptor %p (%s)\n", + (void *) &rt_svc_descs[index], rt_svc_descs[index].name); goto error; } diff --git a/common/bl_common.c b/common/bl_common.c index 0eeef83f..d5b095aa 100644 --- a/common/bl_common.c +++ b/common/bl_common.c @@ -229,7 +229,8 @@ int load_image(meminfo_t *mem_layout, return io_result; } - INFO("Loading image id=%u at address 0x%lx\n", image_id, image_base); + INFO("Loading image id=%u at address %p\n", image_id, + (void *) image_base); /* Find the size of the image */ io_result = io_size(image_handle, &image_size); @@ -242,8 +243,8 @@ int load_image(meminfo_t *mem_layout, /* Check that the memory where the image will be loaded is free */ if (!is_mem_free(mem_layout->free_base, mem_layout->free_size, image_base, image_size)) { - WARN("Failed to reserve memory: 0x%lx - 0x%lx\n", - image_base, image_base + image_size); + WARN("Failed to reserve memory: %p - %p\n", (void *) image_base, + (void *) (image_base + image_size)); dump_load_info(image_base, image_size, mem_layout); io_result = -ENOMEM; goto exit; @@ -268,8 +269,8 @@ int load_image(meminfo_t *mem_layout, reserve_mem(&mem_layout->free_base, &mem_layout->free_size, image_base, image_size); } else { - INFO("Skip reserving memory: 0x%lx - 0x%lx\n", - image_base, image_base + image_size); + INFO("Skip reserving memory: %p - %p\n", (void *) image_base, + (void *) (image_base + image_size)); } image_data->image_base = image_base; @@ -284,8 +285,8 @@ int load_image(meminfo_t *mem_layout, */ flush_dcache_range(image_base, image_size); - INFO("Image id=%u loaded: 0x%lx - 0x%lx\n", image_id, image_base, - image_base + image_size); + INFO("Image id=%u loaded: %p - %p\n", image_id, (void *) image_base, + (void *) (image_base + image_size)); exit: io_close(image_handle); diff --git a/common/tf_printf.c b/common/tf_printf.c index c68b9904..c1d41889 100644 --- a/common/tf_printf.c +++ b/common/tf_printf.c @@ -68,6 +68,7 @@ static void string_print(const char *str) * %u - unsigned 32 bit decimal format * %ld and %lld - signed 64 bit decimal format * %lu and %llu - unsigned 64 bit decimal format + * %p - pointer format * Exits on all other formats. *******************************************************************/ @@ -107,6 +108,14 @@ loop: str = va_arg(args, char *); string_print(str); break; + case 'p': + unum = (uint64_t)va_arg(args, void *); + + if (unum) + string_print("0x"); + + unsigned_num_print(unum, 16); + break; case 'x': if (bit64) unum = va_arg(args, uint64_t); diff --git a/docs/cpu-specific-build-macros.md b/docs/cpu-specific-build-macros.md index d9b7108c..c57dc7ee 100644 --- a/docs/cpu-specific-build-macros.md +++ b/docs/cpu-specific-build-macros.md @@ -26,8 +26,8 @@ by ARM. The errata workarounds are implemented for a particular revision or a set of processor revisions. This is checked by reset handler at runtime. Each errata workaround is identified by its `ID` as specified in the processor's errata notice document. The format of the define used to enable/disable the -errata is `ERRATA_<Processor name>_<ID>` where the `Processor name` -is either `A57` for the `Cortex_A57` CPU or `A53` for `Cortex_A53` CPU. +errata workaround is `ERRATA_<Processor name>_<ID>`, where the `Processor name` +is for example `A57` for the `Cortex_A57` CPU. All workarounds are disabled by default. The platform is reponsible for enabling these workarounds according to its requirement by defining the @@ -74,6 +74,23 @@ architecture that can be enabled by the platform as desired. sequence. Each Cortex-A57 based platform must make its own decision on whether to use the optimization. +* `A53_DISABLE_NON_TEMPORAL_HINT`: This flag disables the cache non-temporal + hint. The LDNP/STNP instructions as implemented on Cortex-A53 do not behave + in a way most programmers expect, and will most probably result in a + significant speed degradation to any code that employs them. The ARMv8-A + architecture (see ARM DDI 0487A.h, section D3.4.3) allows cores to ignore + the non-temporal hint and treat LDNP/STNP as LDP/STP instead. Enabling this + flag enforces this behaviour. This needs to be enabled only for revisions + <= r0p3 of the CPU and is enabled by default. + +* `A57_DISABLE_NON_TEMPORAL_HINT`: This flag has the same behaviour as + `A53_DISABLE_NON_TEMPORAL_HINT` but for Cortex-A57. This needs to be + enabled only for revisions <= r1p2 of the CPU and is enabled by default, + as recommended in section "4.7 Non-Temporal Loads/Stores" of the + [Cortex-A57 Software Optimization Guide][A57 SW Optimization Guide]. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -_Copyright (c) 2014, ARM Limited and Contributors. All rights reserved._ +_Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved._ + +[A57 SW Optimization Guide]: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf diff --git a/docs/firmware-design.md b/docs/firmware-design.md index d0cb3994..cd8c7aaa 100644 --- a/docs/firmware-design.md +++ b/docs/firmware-design.md @@ -1194,6 +1194,72 @@ Additionally, if the platform memory layout implies some image overlaying like on FVP, BL31 and TSP need to know the limit address that their PROGBITS sections must not overstep. The platform code must provide those. +Trusted Firmware provides a mechanism to verify at boot time that the memory +to load a new image is free to prevent overwriting a previously loaded image. +For this mechanism to work, the platform must specify the memory available in +the system as regions, where each region consists of base address, total size +and the free area within it (as defined in the `meminfo_t` structure). Trusted +Firmware retrieves these memory regions by calling the corresponding platform +API: + +* `meminfo_t *bl1_plat_sec_mem_layout(void)` +* `meminfo_t *bl2_plat_sec_mem_layout(void)` +* `void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)` +* `void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)` +* `void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)` + +For example, in the case of BL1 loading BL2, `bl1_plat_sec_mem_layout()` will +return the region defined by the platform where BL1 intends to load BL2. The +`load_image()` function will check that the memory where BL2 will be loaded is +within the specified region and marked as free. + +The actual number of regions and their base addresses and sizes is platform +specific. The platform may return the same region or define a different one for +each API. However, the overlap verification mechanism applies only to a single +region. Hence, it is the platform responsibility to guarantee that different +regions do not overlap, or that if they do, the overlapping images are not +accessed at the same time. This could be used, for example, to load temporary +images (e.g. certificates) or firmware images prior to being transfered to its +corresponding processor (e.g. the SCP BL2 image). + +To reduce fragmentation and simplify the tracking of free memory, all the free +memory within a region is always located in one single buffer defined by its +base address and size. Trusted Firmware implements a top/bottom load approach: +after a new image is loaded, it checks how much memory remains free above and +below the image. The smallest area is marked as unavailable, while the larger +area becomes the new free memory buffer. Platforms should take this behaviour +into account when defining the base address for each of the images. For example, +if an image is loaded near the middle of the region, small changes in image size +could cause a flip between a top load and a bottom load, which may result in an +unexpected memory layout. + +The following diagram is an example of an image loaded in the bottom part of +the memory region. The region is initially free (nothing has been loaded yet): + + Memory region + +----------+ + | | + | | <<<<<<<<<<<<< Free + | | + |----------| +------------+ + | image | <<<<<<<<<<<<< | image | + |----------| +------------+ + | xxxxxxxx | <<<<<<<<<<<<< Marked as unavailable + +----------+ + +And the following diagram is an example of an image loaded in the top part: + + Memory region + +----------+ + | xxxxxxxx | <<<<<<<<<<<<< Marked as unavailable + |----------| +------------+ + | image | <<<<<<<<<<<<< | image | + |----------| +------------+ + | | + | | <<<<<<<<<<<<< Free + | | + +----------+ + #### Memory layout on ARM development platforms @@ -1229,9 +1295,47 @@ The following list describes the memory layout on the ARM development platforms: * Secure region of DRAM (top 16MB of DRAM configured by the TrustZone controller) -When BL32 is loaded into Trusted SRAM, its NOBITS sections are allowed to -overlay BL2. This memory layout is designed to give the BL32 image as much -memory as possible when it is loaded into Trusted SRAM. + When BL32 is loaded into Trusted SRAM, its NOBITS sections are allowed to + overlay BL2. This memory layout is designed to give the BL32 image as much + memory as possible when it is loaded into Trusted SRAM. + +The memory regions for the overlap detection mechanism at boot time are +defined as follows (shown per API): + +* `meminfo_t *bl1_plat_sec_mem_layout(void)` + + This region corresponds to the whole Trusted SRAM except for the shared + memory at the base. This region is initially free. At boot time, BL1 will + mark the BL1(rw) section within this region as occupied. The BL1(rw) section + is placed at the top of Trusted SRAM. + +* `meminfo_t *bl2_plat_sec_mem_layout(void)` + + This region corresponds to the whole Trusted SRAM as defined by + `bl1_plat_sec_mem_layout()`, but with the BL1(rw) section marked as + occupied. This memory region is used to check that BL2 and BL31 do not + overlap with each other. BL2_BASE and BL1_RW_BASE are carefully chosen so + that the memory for BL31 is top loaded above BL2. + +* `void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)` + + This region is an exact copy of the region defined by + `bl2_plat_sec_mem_layout()`. Being a disconnected copy means that all the + changes made to this region by the Trusted Firmware will not be propagated. + This approach is valid because the SCP BL2 image is loaded temporarily + while it is being transferred to the SCP, so this memory is reused + afterwards. + +* `void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)` + + This region depends on the location of the BL32 image. Currently, ARM + platforms support three different locations (detailed below): Trusted SRAM, + Trusted DRAM and the TZC-Secured DRAM. + +* `void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)` + + This region corresponds to the Non-Secure DDR-DRAM, excluding the + TZC-Secured area. The location of the BL32 image will result in different memory maps. This is illustrated for both FVP and Juno in the following diagrams, using the TSP as diff --git a/docs/porting-guide.md b/docs/porting-guide.md index d19811d1..741ee207 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -476,6 +476,18 @@ memory layout implies some image overlaying like in ARM standard platforms. Defines the maximum address that the TSP's progbits sections can occupy. +If the platform port uses the PL061 GPIO driver, the following constant may +optionally be defined: + +* **PLAT_PL061_MAX_GPIOS** + Maximum number of GPIOs required by the platform. This allows control how + much memory is allocated for PL061 GPIO controllers. The default value is + 32. + [For example, define the build flag in platform.mk]: + PLAT_PL061_MAX_GPIOS := 160 + $(eval $(call add_define,PLAT_PL061_MAX_GPIOS)) + + ### File : plat_macros.S [mandatory] Each platform must ensure a file of this name is in the system include path with diff --git a/docs/user-guide.md b/docs/user-guide.md index e6929134..9c17e353 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -413,6 +413,25 @@ performed. any register that is not part of the SBSA generic UART specification. Default value is 0 (a full PL011 compliant UART is present). +* `CTX_INCLUDE_FPREGS`: Boolean option that, when set to 1, will cause the FP + registers to be included when saving and restoring the CPU context. Default + is 0. + +* `DISABLE_PEDANTIC`: When set to 1 it will disable the -pedantic option in + the GCC command line. Default is 0. + +* `BUILD_STRING`: Input string for VERSION_STRING, which allows the TF build + to be uniquely identified. Defaults to the current git commit id. + +* `VERSION_STRING`: String used in the log output for each TF image. Defaults + to a string formed by concatenating the version number, build type and build + string. + +* `BUILD_MESSAGE_TIMESTAMP`: String used to identify the time and date of the + compilation of each build. It must be set to a C string (including quotes + where applicable). Defaults to a string that contains the time and date of + the compilation. + #### ARM development platform specific build options * `ARM_TSP_RAM_LOCATION`: location of the TSP binary. Options: @@ -462,6 +481,13 @@ map is explained in the [Firmware Design]. match the frame used by the Non-Secure image (normally the Linux kernel). Default is true (access to the frame is allowed). +* `ARM_BOARD_OPTIMISE_MMAP`: Boolean option to enable or disable optimisation + of page table and MMU related macros `PLAT_ARM_MMAP_ENTRIES` and + `MAX_XLAT_TABLES`. By default this flag is 0, which means it uses the + default unoptimised values for these macros. ARM development platforms + that wish to optimise memory usage for page tables need to set this flag to 1 + and must override the related macros. + #### ARM CSS platform specific build options * `CSS_DETECT_PRE_1_7_0_SCP`: Boolean flag to detect SCP version @@ -471,6 +497,10 @@ map is explained in the [Firmware Design]. set to 1 then Trusted Firmware will detect if an earlier version is in use. Default is 1. +* `CSS_LOAD_SCP_IMAGES`: Boolean flag, which when set, adds SCP_BL2 and + SCP_BL2U to the FIP and FWU_FIP respectively, and enables them to be loaded + during boot. Default is 1. + #### ARM FVP platform specific build options * `FVP_USE_GIC_DRIVER` : Selects the GIC driver to be built. Options: @@ -482,6 +512,11 @@ map is explained in the [Firmware Design]. Trusted Firmware must be compiled with GICv2 only driver using `FVP_USE_GIC_DRIVER=FVP_GICV2` build option. +* `FVP_CLUSTER_COUNT` : Configures the cluster count to be used to + build the topology tree within Trusted Firmware. By default the + Trusted Firmware is configured for dual cluster topology and this option + can be used to override the default value. + ### Creating a Firmware Image Package FIPs are automatically created as part of the build instructions described in @@ -997,14 +1032,15 @@ which the FVP is launched. Alternatively a symbolic link may be used. This version of the ARM Trusted Firmware has been tested on the following ARM FVPs (64-bit versions only). -* `Foundation_Platform` (Version 9.4, Build 9.4.59) -* `FVP_Base_AEMv8A-AEMv8A` (Version 7.0, Build 0.8.7004) -* `FVP_Base_Cortex-A57x4-A53x4` (Version 7.0, Build 0.8.7004) -* `FVP_Base_Cortex-A57x1-A53x1` (Version 7.0, Build 0.8.7004) -* `FVP_Base_Cortex-A57x2-A53x4` (Version 7.0, Build 0.8.7004) +* `Foundation_Platform` (Version 9.5, Build 9.5.40) +* `FVP_Base_AEMv8A-AEMv8A` (Version 7.2, Build 0.8.7202) +* `FVP_Base_Cortex-A57x4-A53x4` (Version 7.2, Build 0.8.7202) +* `FVP_Base_Cortex-A57x1-A53x1` (Version 7.2, Build 0.8.7202) +* `FVP_Base_Cortex-A57x2-A53x4` (Version 7.2, Build 0.8.7202) NOTE: The build numbers quoted above are those reported by launching the FVP -with the `--version` parameter. +with the `--version` parameter. `Foundation_Platform` tarball for `--version` +9.5.40 is labeled as version 9.5.41. NOTE: The software will not work on Version 1.0 of the Foundation FVP. The commands below would report an `unhandled argument` error in this case. diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index aef891b2..28d27098 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -268,7 +268,7 @@ static unsigned long long ccn_master_to_rn_id_map(unsigned long long master_map) /******************************************************************************* * This function executes the necessary operations to add or remove Request node * IDs specified in the 'rn_id_map' bitmap from the snoop/DVM domains specified - * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/HN-I + * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/MN * on which the operation should be performed. 'op_reg_offset' specifies the * type of operation (add/remove). 'stat_reg_offset' specifies the register * which should be polled to determine if the operation has completed or not. @@ -310,35 +310,6 @@ static void ccn_snoop_dvm_do_op(unsigned long long rn_id_map, } /******************************************************************************* - * This function reads the bitmap of Home nodes on the basis of the - * 'mn_hn_id_reg_offset' parameter from the Miscellaneous node's (MN) - * programmer's view. The MN has a register which carries the bitmap of present - * Home nodes of each type i.e. HN-Fs, HN-Is & HN-Ds. It calls - * 'ccn_snoop_dvm_do_op()' with this information to perform the actual - * operation. - ******************************************************************************/ -static void ccn_snoop_dvm_domain_common(unsigned long long rn_id_map, - unsigned int hn_op_reg_offset, - unsigned int hn_stat_reg_offset, - unsigned int mn_hn_id_reg_offset, - unsigned int hn_region_id) -{ - unsigned long long mn_hn_id_map; - - assert(ccn_plat_desc); - assert(ccn_plat_desc->periphbase); - - mn_hn_id_map = ccn_reg_read(ccn_plat_desc->periphbase, - MN_REGION_ID, - mn_hn_id_reg_offset); - ccn_snoop_dvm_do_op(rn_id_map, - mn_hn_id_map, - hn_region_id, - hn_op_reg_offset, - hn_stat_reg_offset); -} - -/******************************************************************************* * The following functions provide the boot and runtime API to the platform for * adding and removing master interfaces from the snoop/DVM domains. A bitmap of * master interfaces IDs is passed as a parameter. It is converted into a bitmap @@ -357,17 +328,18 @@ void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map) unsigned long long rn_id_map; rn_id_map = ccn_master_to_rn_id_map(master_iface_map); - ccn_snoop_dvm_domain_common(rn_id_map, - HNF_SDC_SET_OFFSET, - HNF_SDC_STAT_OFFSET, - MN_HNF_NODEID_OFFSET, - HNF_REGION_ID_START); - - ccn_snoop_dvm_domain_common(rn_id_map, - MN_DDC_SET_OFF, - MN_DDC_STAT_OFFSET, - MN_HNI_NODEID_OFFSET, - MN_REGION_ID); + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase, + MN_HNF_NODEID_OFFSET), + HNF_REGION_ID_START, + HNF_SDC_SET_OFFSET, + HNF_SDC_STAT_OFFSET); + + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase), + MN_REGION_ID, + MN_DDC_SET_OFFSET, + MN_DDC_STAT_OFFSET); } void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map) @@ -375,17 +347,18 @@ void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map) unsigned long long rn_id_map; rn_id_map = ccn_master_to_rn_id_map(master_iface_map); - ccn_snoop_dvm_domain_common(rn_id_map, - HNF_SDC_CLR_OFFSET, - HNF_SDC_STAT_OFFSET, - MN_HNF_NODEID_OFFSET, - HNF_REGION_ID_START); - - ccn_snoop_dvm_domain_common(rn_id_map, - MN_DDC_CLR_OFFSET, - MN_DDC_STAT_OFFSET, - MN_HNI_NODEID_OFFSET, - MN_REGION_ID); + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase, + MN_HNF_NODEID_OFFSET), + HNF_REGION_ID_START, + HNF_SDC_CLR_OFFSET, + HNF_SDC_STAT_OFFSET); + + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase), + MN_REGION_ID, + MN_DDC_CLR_OFFSET, + MN_DDC_STAT_OFFSET); } void ccn_enter_dvm_domain(unsigned long long master_iface_map) @@ -393,11 +366,11 @@ void ccn_enter_dvm_domain(unsigned long long master_iface_map) unsigned long long rn_id_map; rn_id_map = ccn_master_to_rn_id_map(master_iface_map); - ccn_snoop_dvm_domain_common(rn_id_map, - MN_DDC_SET_OFF, - MN_DDC_STAT_OFFSET, - MN_HNI_NODEID_OFFSET, - MN_REGION_ID); + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase), + MN_REGION_ID, + MN_DDC_SET_OFFSET, + MN_DDC_STAT_OFFSET); } void ccn_exit_dvm_domain(unsigned long long master_iface_map) @@ -405,11 +378,11 @@ void ccn_exit_dvm_domain(unsigned long long master_iface_map) unsigned long long rn_id_map; rn_id_map = ccn_master_to_rn_id_map(master_iface_map); - ccn_snoop_dvm_domain_common(rn_id_map, - MN_DDC_CLR_OFFSET, - MN_DDC_STAT_OFFSET, - MN_HNI_NODEID_OFFSET, - MN_REGION_ID); + ccn_snoop_dvm_do_op(rn_id_map, + CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase), + MN_REGION_ID, + MN_DDC_CLR_OFFSET, + MN_DDC_STAT_OFFSET); } /******************************************************************************* diff --git a/drivers/arm/ccn/ccn_private.h b/drivers/arm/ccn/ccn_private.h index e92e8702..8b154725 100644 --- a/drivers/arm/ccn/ccn_private.h +++ b/drivers/arm/ccn/ccn_private.h @@ -147,7 +147,7 @@ typedef enum rn_types { #define MN_HNI_NODEID_OFFSET 0x01C0 #define MN_SN_NODEID_OFFSET 0x01D0 #define MN_DDC_STAT_OFFSET DOMAIN_CTRL_STAT_OFFSET -#define MN_DDC_SET_OFF DOMAIN_CTRL_SET_OFFSET +#define MN_DDC_SET_OFFSET DOMAIN_CTRL_SET_OFFSET #define MN_DDC_CLR_OFFSET DOMAIN_CTRL_CLR_OFFSET #define MN_ID_OFFSET REGION_ID_OFFSET @@ -236,4 +236,21 @@ static inline unsigned int count_set_bits(uint64_t bitmap) */ #define FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, bit_map) \ FOR_EACH_BIT(iface_id, bit_map) + +/* + * Macro that returns the node id bit map for the Miscellaneous Node + */ +#define CCN_GET_MN_NODEID_MAP(periphbase) \ + (1 << get_node_id(ccn_reg_read(periphbase, MN_REGION_ID, \ + REGION_ID_OFFSET))) + +/* + * This macro returns the bitmap of Home nodes on the basis of the + * 'mn_hn_id_reg_offset' parameter from the Miscellaneous node's (MN) + * programmer's view. The MN has a register which carries the bitmap of present + * Home nodes of each type i.e. HN-Fs, HN-Is & HN-Ds. + */ +#define CCN_GET_HN_NODEID_MAP(periphbase, mn_hn_id_reg_offset) \ + ccn_reg_read(periphbase, MN_REGION_ID, mn_hn_id_reg_offset) + #endif /* __CCN_PRIVATE_H__ */ diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c index 17be61d5..cfa0d23e 100644 --- a/drivers/arm/gic/common/gic_common.c +++ b/drivers/arm/gic/common/gic_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,6 +31,7 @@ #include <assert.h> #include <gic_common.h> #include <mmio.h> +#include "gic_common_private.h" /******************************************************************************* * GIC Distributor interface accessors for reading entire registers @@ -239,7 +240,10 @@ void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val) } /******************************************************************************* - * GIC Distributor interface accessors for individual interrupt manipulation + * GIC Distributor functions for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. ******************************************************************************/ unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id) { @@ -306,3 +310,8 @@ void gicd_set_icactiver(uintptr_t base, unsigned int id) gicd_write_icactiver(base, id, (1 << 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); +} diff --git a/drivers/arm/gic/common/gic_common_private.h b/drivers/arm/gic/common/gic_common_private.h new file mode 100644 index 00000000..2919b7f8 --- /dev/null +++ b/drivers/arm/gic/common/gic_common_private.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GIC_COMMON_PRIVATE_H_ +#define GIC_COMMON_PRIVATE_H_ + +#include <gic_common.h> +#include <mmio.h> +#include <stdint.h> + +/******************************************************************************* + * GIC Distributor interface register accessors that are common to GICv3 & GICv2 + ******************************************************************************/ +static inline unsigned int gicd_read_ctlr(uintptr_t base) +{ + return mmio_read_32(base + GICD_CTLR); +} + +static inline unsigned int gicd_read_typer(uintptr_t base) +{ + return mmio_read_32(base + GICD_TYPER); +} + +static inline unsigned int gicd_read_iidr(uintptr_t base) +{ + return mmio_read_32(base + GICD_IIDR); +} + +static inline void gicd_write_ctlr(uintptr_t base, unsigned int val) +{ + mmio_write_32(base + GICD_CTLR, val); +} + +/******************************************************************************* + * GIC Distributor function prototypes for accessing entire registers. + * Note: The raw register values correspond to multiple interrupt IDs and + * the number of interrupt IDs involved depends on the register accessed. + ******************************************************************************/ +unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id); +unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id); +unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id); +unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id); +unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id); +unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id); +unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id); +unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id); +unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id); +unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id); +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); +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); +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); +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); +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); + +/******************************************************************************* + * GIC Distributor function prototypes for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. + ******************************************************************************/ +unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id); +void gicd_set_igroupr(uintptr_t base, unsigned int id); +void gicd_clr_igroupr(uintptr_t base, unsigned int id); +void gicd_set_isenabler(uintptr_t base, unsigned int id); +void gicd_set_icenabler(uintptr_t base, unsigned int id); +void gicd_set_ispendr(uintptr_t base, unsigned int id); +void gicd_set_icpendr(uintptr_t base, unsigned int id); +void gicd_set_isactiver(uintptr_t base, unsigned int id); +void gicd_set_icactiver(uintptr_t base, unsigned int id); +void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); + +#endif /* GIC_COMMON_PRIVATE_H_ */ diff --git a/drivers/arm/gic/gic_v2.c b/drivers/arm/gic/gic_v2.c index dc5dc08c..05399c3a 100644 --- a/drivers/arm/gic/gic_v2.c +++ b/drivers/arm/gic/gic_v2.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -261,10 +261,6 @@ void gicd_set_icactiver(uintptr_t base, unsigned int id) */ void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) { - unsigned int reg = base + GICD_IPRIORITYR + (id & ~3); - unsigned int shift = (id & 3) << 3; - unsigned int reg_val = mmio_read_32(reg); - /* * Enforce ARM recommendation to manage priority values such * that group1 interrupts always have a lower priority than @@ -278,17 +274,12 @@ void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) pri >= GIC_HIGHEST_SEC_PRIORITY && pri <= GIC_LOWEST_SEC_PRIORITY); - reg_val &= ~(GIC_PRI_MASK << shift); - reg_val |= (pri & GIC_PRI_MASK) << shift; - mmio_write_32(reg, reg_val); + mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK); } void gicd_set_itargetsr(uintptr_t base, unsigned int id, unsigned int target) { - unsigned byte_off = id & ((1 << ITARGETSR_SHIFT) - 1); - unsigned int reg_val = gicd_read_itargetsr(base, id); - - gicd_write_itargetsr(base, id, reg_val | (target << (byte_off << 3))); + mmio_write_8(base + GICD_ITARGETSR + id, target & GIC_TARGET_CPU_MASK); } /******************************************************************************* diff --git a/drivers/arm/gic/gic_v3.c b/drivers/arm/gic/gic_v3.c index f4296629..11185b2e 100644 --- a/drivers/arm/gic/gic_v3.c +++ b/drivers/arm/gic/gic_v3.c @@ -60,8 +60,8 @@ uintptr_t gicv3_get_rdist(uintptr_t gicr_base, uint64_t mpidr) /* Disable this print for now as it appears every time * when using PSCI CPU_SUSPEND. * TODO: Print this only the first time for each CPU. - * INFO("GICv3 - Found RDIST for MPIDR(0x%lx) at 0x%lx\n", - * mpidr, addr); + * INFO("GICv3 - Found RDIST for MPIDR(0x%lx) at %p\n", + * mpidr, (void *) addr); */ return addr; } diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c index 1f904c51..b60a5cd9 100644 --- a/drivers/arm/gic/v2/gicv2_helpers.c +++ b/drivers/arm/gic/v2/gicv2_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +33,7 @@ #include <assert.h> #include <debug.h> #include <gic_common.h> +#include "../common/gic_common_private.h" #include "gicv2_private.h" /* @@ -101,10 +102,7 @@ void gicd_write_spendsgir(uintptr_t base, unsigned int id, unsigned int val) */ void gicd_set_itargetsr(uintptr_t base, unsigned int id, unsigned int target) { - unsigned byte_off = id & ((1 << ITARGETSR_SHIFT) - 1); - unsigned int reg_val = gicd_read_itargetsr(base, id); - - gicd_write_itargetsr(base, id, reg_val | (target << (byte_off << 3))); + mmio_write_8(base + GICD_ITARGETSR + id, target & GIC_TARGET_CPU_MASK); } /******************************************************************************* @@ -166,7 +164,7 @@ void gicv2_secure_spis_configure(uintptr_t gicd_base, gicd_clr_igroupr(gicd_base, irq_num); /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); @@ -213,7 +211,7 @@ void gicv2_secure_ppi_sgi_setup(uintptr_t gicd_base, sec_ppi_sgi_mask |= 1U << irq_num; /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); } diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c index cf939261..305a8b07 100644 --- a/drivers/arm/gic/v2/gicv2_main.c +++ b/drivers/arm/gic/v2/gicv2_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,6 +34,7 @@ #include <debug.h> #include <gic_common.h> #include <gicv2.h> +#include "../common/gic_common_private.h" #include "gicv2_private.h" static const gicv2_driver_data_t *driver_data; diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 2fb98cbb..07ae54c4 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +33,7 @@ #include <assert.h> #include <debug.h> #include <gic_common.h> +#include "../common/gic_common_private.h" #include "gicv3_private.h" /* @@ -194,6 +195,15 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id) gicr_write_isenabler0(base, (1 << bit_num)); } +/* + * Accessor to set the byte corresponding to interrupt ID + * in GIC Re-distributor IPRIORITYR. + */ +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK); +} + /****************************************************************************** * This function marks the core as awake in the re-distributor and * ensures that the interface is active. @@ -330,7 +340,7 @@ void gicv3_secure_spis_configure(uintptr_t gicd_base, gicd_clr_igrpmodr(gicd_base, irq_num); /* Set the priority of this interrupt */ - gicd_write_ipriorityr(gicd_base, + gicd_set_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); @@ -404,7 +414,7 @@ void gicv3_secure_ppi_sgi_configure(uintptr_t gicr_base, gicr_clr_igrpmodr0(gicr_base, irq_num); /* Set the priority of this interrupt */ - gicr_write_ipriorityr(gicr_base, + gicr_set_ipriorityr(gicr_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index d5cd0ed9..6c6c7af9 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,6 +34,7 @@ #include <debug.h> #include <gic_common.h> #include <gicv3.h> +#include "../common/gic_common_private.h" #include "gicv3_private.h" static const gicv3_driver_data_t *driver_data; diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index c8b311a1..5e2409fc 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -84,16 +84,24 @@ ((typer_val >> 32) & 0xffffff)) /******************************************************************************* - * Private function prototypes + * Private GICv3 function prototypes for accessing entire registers. + * Note: The raw register values correspond to multiple interrupt IDs and + * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); + +/******************************************************************************* + * Private GICv3 function prototypes for accessing the GIC registers + * corresponding to a single interrupt ID. These functions use bitwise + * operations or appropriate register accesses to modify or return + * the bit-field corresponding the single interrupt ID. + ******************************************************************************/ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id); unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id); unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id); -unsigned int gicv3_get_pending_grp1_interrupt_id(unsigned int pending_grp); -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); void gicd_set_igrpmodr(uintptr_t base, unsigned int id); void gicr_set_igrpmodr0(uintptr_t base, unsigned int id); void gicr_set_isenabler0(uintptr_t base, unsigned int id); @@ -101,6 +109,11 @@ void gicr_set_igroupr0(uintptr_t base, unsigned int id); void gicd_clr_igrpmodr(uintptr_t base, unsigned int id); void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id); void gicr_clr_igroupr0(uintptr_t base, unsigned int id); +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri); + +/******************************************************************************* + * Private GICv3 helper function prototypes + ******************************************************************************/ void gicv3_spis_configure_defaults(uintptr_t gicd_base); void gicv3_ppi_sgi_configure_defaults(uintptr_t gicr_base); void gicv3_secure_spis_configure(uintptr_t gicd_base, @@ -179,6 +192,11 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val) mmio_write_32(base + GICR_WAKER, val); } +/******************************************************************************* + * GIC Re-distributor functions for accessing entire registers. + * Note: The raw register values correspond to multiple interrupt IDs and + * the number of interrupt IDs involved depends on the register accessed. + ******************************************************************************/ static inline unsigned int gicr_read_icenabler0(uintptr_t base) { return mmio_read_32(base + GICR_ICENABLER0); diff --git a/drivers/arm/pl011/pl011_console.S b/drivers/arm/pl011/pl011_console.S index f29f895b..5e97e911 100644 --- a/drivers/arm/pl011/pl011_console.S +++ b/drivers/arm/pl011/pl011_console.S @@ -69,15 +69,6 @@ func console_core_init mov w4, #PL011_UARTCR_UARTEN bic w3, w3, w4 str w3, [x0, #UARTCR] - /* Flush the transmit FIFO */ - ldr w3, [x0, #UARTLCR_H] - mov w4, #PL011_UARTLCR_H_FEN - bic w3, w3, w4 - str w3, [x0, #UARTLCR_H] - /* Wait for the end of Tx of current character */ -busy_loop: - ldr w3, [x0, #UARTFR] - tbnz w3, #PL011_UARTFR_BUSY_BIT, busy_loop /* Program the baudrate */ /* Divisor = (Uart clock * 4) / baudrate */ lsl w1, w1, #2 diff --git a/drivers/arm/pl061/pl061_gpio.c b/drivers/arm/pl061/pl061_gpio.c new file mode 100644 index 00000000..fca00565 --- /dev/null +++ b/drivers/arm/pl061/pl061_gpio.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * ARM PL061 GPIO Driver. + * Reference to ARM DDI 0190B document. + * + */ + +#include <assert.h> +#include <cassert.h> +#include <debug.h> +#include <errno.h> +#include <gpio.h> +#include <mmio.h> +#include <pl061_gpio.h> + +#if !PLAT_PL061_MAX_GPIOS +# define PLAT_PL061_MAX_GPIOS 32 +#endif /* PLAT_PL061_MAX_GPIOS */ + +CASSERT(PLAT_PL061_MAX_GPIOS > 0, assert_plat_pl061_max_gpios); + +#define MAX_GPIO_DEVICES ((PLAT_PL061_MAX_GPIOS + \ + (GPIOS_PER_PL061 - 1)) / GPIOS_PER_PL061) + +#define PL061_GPIO_DIR 0x400 + +#define GPIOS_PER_PL061 8 +#define BIT(nr) (1UL << (nr)) + +static int pl061_get_direction(int gpio); +static void pl061_set_direction(int gpio, int direction); +static int pl061_get_value(int gpio); +static void pl061_set_value(int gpio, int value); + +static uintptr_t pl061_reg_base[MAX_GPIO_DEVICES]; + +static const gpio_ops_t pl061_gpio_ops = { + .get_direction = pl061_get_direction, + .set_direction = pl061_set_direction, + .get_value = pl061_get_value, + .set_value = pl061_set_value, +}; + +static int pl061_get_direction(int gpio) +{ + uintptr_t base_addr; + unsigned int data, offset; + + assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); + + base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; + offset = gpio % GPIOS_PER_PL061; + data = mmio_read_8(base_addr + PL061_GPIO_DIR); + if (data & BIT(offset)) + return GPIO_DIR_OUT; + return GPIO_DIR_IN; +} + +static void pl061_set_direction(int gpio, int direction) +{ + uintptr_t base_addr; + unsigned int data, offset; + + assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); + + base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; + offset = gpio % GPIOS_PER_PL061; + if (direction == GPIO_DIR_OUT) { + data = mmio_read_8(base_addr + PL061_GPIO_DIR) | BIT(offset); + mmio_write_8(base_addr + PL061_GPIO_DIR, data); + } else { + data = mmio_read_8(base_addr + PL061_GPIO_DIR) & ~BIT(offset); + mmio_write_8(base_addr + PL061_GPIO_DIR, data); + } +} + +/* + * The offset of GPIODATA register is 0. + * The values read from GPIODATA are determined for each bit, by the mask bit + * derived from the address used to access the data register, PADDR[9:2]. + * Bits that are 1 in the address mask cause the corresponding bits in GPIODATA + * to be read, and bits that are 0 in the address mask cause the corresponding + * bits in GPIODATA to be read as 0, regardless of their value. + */ +static int pl061_get_value(int gpio) +{ + uintptr_t base_addr; + unsigned int offset; + + assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); + + base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; + offset = gpio % GPIOS_PER_PL061; + if (mmio_read_8(base_addr + BIT(offset + 2))) + return GPIO_LEVEL_HIGH; + return GPIO_LEVEL_LOW; +} + +/* + * In order to write GPIODATA, the corresponding bits in the mask, resulting + * from the address bus, PADDR[9:2], must be HIGH. Otherwise the bit values + * remain unchanged by the write. + */ +static void pl061_set_value(int gpio, int value) +{ + uintptr_t base_addr; + int offset; + + assert((gpio >= 0) && (gpio < PLAT_PL061_MAX_GPIOS)); + + base_addr = pl061_reg_base[gpio / GPIOS_PER_PL061]; + offset = gpio % GPIOS_PER_PL061; + if (value == GPIO_LEVEL_HIGH) + mmio_write_8(base_addr + BIT(offset + 2), BIT(offset)); + else + mmio_write_8(base_addr + BIT(offset + 2), 0); +} + + +/* + * Register the PL061 GPIO controller with a base address and the offset + * of start pin in this GPIO controller. + * This function is called after pl061_gpio_ops_init(). + */ +void pl061_gpio_register(uintptr_t base_addr, int gpio_dev) +{ + assert((gpio_dev >= 0) && (gpio_dev < MAX_GPIO_DEVICES)); + + pl061_reg_base[gpio_dev] = base_addr; +} + +/* + * Initialize PL061 GPIO controller with the total GPIO numbers in SoC. + */ +void pl061_gpio_init(void) +{ + gpio_init(&pl061_gpio_ops); +} diff --git a/drivers/gpio/gpio.c b/drivers/gpio/gpio.c new file mode 100644 index 00000000..c06172fc --- /dev/null +++ b/drivers/gpio/gpio.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * GPIO -- General Purpose Input/Output + * + * Defines a simple and generic interface to access GPIO device. + * + */ + +#include <assert.h> +#include <errno.h> +#include <gpio.h> + +/* + * The gpio implementation + */ +static const gpio_ops_t *ops; + +int gpio_get_direction(int gpio) +{ + assert(ops); + assert(ops->get_direction != 0); + assert(gpio >= 0); + + return ops->get_direction(gpio); +} + +void gpio_set_direction(int gpio, int direction) +{ + assert(ops); + assert(ops->set_direction != 0); + assert((direction == GPIO_DIR_OUT) || (direction == GPIO_DIR_IN)); + assert(gpio >= 0); + + ops->set_direction(gpio, direction); +} + +int gpio_get_value(int gpio) +{ + assert(ops); + assert(ops->get_value != 0); + assert(gpio >= 0); + + return ops->get_value(gpio); +} + +void gpio_set_value(int gpio, int value) +{ + assert(ops); + assert(ops->set_value != 0); + assert((value == GPIO_LEVEL_LOW) || (value == GPIO_LEVEL_HIGH)); + assert(gpio >= 0); + + ops->set_value(gpio, value); +} + +/* + * Initialize the gpio. The fields in the provided gpio + * ops pointer must be valid. + */ +void gpio_init(const gpio_ops_t *ops_ptr) +{ + assert(ops_ptr != 0 && + (ops_ptr->get_direction != 0) && + (ops_ptr->set_direction != 0) && + (ops_ptr->get_value != 0) && + (ops_ptr->set_value != 0)); + + ops = ops_ptr; +} diff --git a/include/common/bl_common.h b/include/common/bl_common.h index e5e6717b..f13dc316 100644 --- a/include/common/bl_common.h +++ b/include/common/bl_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -53,28 +53,12 @@ #define ENTRY_POINT_INFO_ARGS_OFFSET 0x18 /* The following are used to set/get image attributes. */ -#define EXECUTABLE (0x1) -#define NON_EXECUTABLE (0x0) -#define PARAM_EP_EXECUTE_MASK (0x1) -#define PARAM_EP_EXECUTE_SHIFT (0x1) #define PARAM_EP_SECURITY_MASK (0x1) -#define PARAM_EP_SECURITY_SHIFT (0x0) #define GET_SECURITY_STATE(x) (x & PARAM_EP_SECURITY_MASK) #define SET_SECURITY_STATE(x, security) \ ((x) = ((x) & ~PARAM_EP_SECURITY_MASK) | (security)) -#define GET_EXEC_STATE(x) \ - (((x) >> PARAM_EP_EXECUTE_SHIFT) & PARAM_EP_EXECUTE_MASK) - -#define SET_EXEC_STATE(x) \ - (((x) & PARAM_EP_EXECUTE_MASK) << PARAM_EP_EXECUTE_SHIFT) - -#define GET_SEC_STATE(x) \ - (((x) >> PARAM_EP_SECURITY_SHIFT) & PARAM_EP_SECURITY_MASK) - -#define SET_SEC_STATE(x) \ - (((x) & PARAM_EP_SECURITY_MASK) << PARAM_EP_SECURITY_SHIFT) /* * The following are used for image state attributes. @@ -99,11 +83,17 @@ #define EP_GET_ST(x) (x & EP_ST_MASK) #define EP_SET_ST(x, ee) ((x) = ((x) & ~EP_ST_MASK) | (ee)) -#define PARAM_EP 0x01 -#define PARAM_IMAGE_BINARY 0x02 -#define PARAM_BL31 0x03 +#define EP_EXE_MASK 0x8 +#define NON_EXECUTABLE 0x0 +#define EXECUTABLE 0x8 +#define EP_GET_EXE(x) (x & EP_EXE_MASK) +#define EP_SET_EXE(x, ee) ((x) = ((x) & ~EP_EXE_MASK) | (ee)) + +#define PARAM_EP 0x01 +#define PARAM_IMAGE_BINARY 0x02 +#define PARAM_BL31 0x03 -#define VERSION_1 0x01 +#define VERSION_1 0x01 #define INVALID_IMAGE_ID (0xFFFFFFFF) @@ -114,6 +104,14 @@ (_p)->h.attr = (uint32_t)(_attr) ; \ } while (0) +/* Following is used for populating structure members statically. */ +#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \ + ._p.h.type = (uint8_t)(_type), \ + ._p.h.version = (uint8_t)(_ver), \ + ._p.h.size = (uint16_t)sizeof(_p_type), \ + ._p.h.attr = (uint32_t)(_attr) + + /******************************************************************************* * Constants to indicate type of exception to the common exception handler. ******************************************************************************/ @@ -224,7 +222,6 @@ typedef struct image_info { param_header_t h; uintptr_t image_base; /* physical address of base of image */ uint32_t image_size; /* bytes read from image file */ - uint32_t copied_size; /* image size copied in blocks */ } image_info_t; /***************************************************************************** @@ -238,6 +235,7 @@ typedef struct image_desc { * Refer IMAGE_STATE_XXX defined above. */ unsigned int state; + uint32_t copied_size; /* image size copied in blocks */ image_info_t image_info; entry_point_info_t ep_info; } image_desc_t; diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h index 6a322a22..dd8efdc7 100644 --- a/include/drivers/arm/gic_common.h +++ b/include/drivers/arm/gic_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -107,67 +107,4 @@ (GIC_HIGHEST_NS_PRIORITY << 16) | \ (GIC_HIGHEST_NS_PRIORITY << 24)) -#ifndef __ASSEMBLY__ - -#include <mmio.h> -#include <stdint.h> - -/******************************************************************************* - * GIC Distributor interface register accessors that are common to GICv3 & GICv2 - ******************************************************************************/ -static inline unsigned int gicd_read_ctlr(uintptr_t base) -{ - return mmio_read_32(base + GICD_CTLR); -} - -static inline unsigned int gicd_read_typer(uintptr_t base) -{ - return mmio_read_32(base + GICD_TYPER); -} - -static inline unsigned int gicd_read_iidr(uintptr_t base) -{ - return mmio_read_32(base + GICD_IIDR); -} - -static inline void gicd_write_ctlr(uintptr_t base, unsigned int val) -{ - mmio_write_32(base + GICD_CTLR, val); -} - -/******************************************************************************* - * GIC Distributor function prototypes - ******************************************************************************/ -unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id); -unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id); -unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id); -unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id); -unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id); -unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id); -unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id); -unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id); -unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id); -unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id); -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); -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); -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); -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); -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 int gicd_get_igroupr(uintptr_t base, unsigned int id); -void gicd_set_igroupr(uintptr_t base, unsigned int id); -void gicd_clr_igroupr(uintptr_t base, unsigned int id); -void gicd_set_isenabler(uintptr_t base, unsigned int id); -void gicd_set_icenabler(uintptr_t base, unsigned int id); -void gicd_set_ispendr(uintptr_t base, unsigned int id); -void gicd_set_icpendr(uintptr_t base, unsigned int id); -void gicd_set_isactiver(uintptr_t base, unsigned int id); -void gicd_set_icactiver(uintptr_t base, unsigned int id); - - -#endif /* __ASSEMBLY__ */ #endif /* __GIC_COMMON_H__ */ diff --git a/lib/stdlib/std.c b/include/drivers/arm/pl061_gpio.h index 5f6ef752..ca796303 100644 --- a/lib/stdlib/std.c +++ b/include/drivers/arm/pl061_gpio.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -28,18 +28,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef __PL061_GPIO_H__ +#define __PL061_GPIO_H__ -/* Include the various implemented functions */ -#include "abort.c" -#include "assert.c" -#include "exit.c" -#include "mem.c" -#include "printf.c" -#include "putchar.c" -#include "puts.c" -#include "sscanf.c" -#include "strchr.c" -#include "strcmp.c" -#include "strlen.c" -#include "strncmp.c" -#include "subr_prf.c" +#include <gpio.h> + +void pl061_gpio_register(uintptr_t base_addr, int gpio_dev); +void pl061_gpio_init(void); + +#endif /* __PL061_GPIO_H__ */ diff --git a/include/drivers/gpio.h b/include/drivers/gpio.h new file mode 100644 index 00000000..a5cb5c7f --- /dev/null +++ b/include/drivers/gpio.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#define GPIO_DIR_OUT 0 +#define GPIO_DIR_IN 1 + +#define GPIO_LEVEL_LOW 0 +#define GPIO_LEVEL_HIGH 1 + +typedef struct gpio_ops { + int (*get_direction)(int gpio); + void (*set_direction)(int gpio, int direction); + int (*get_value)(int gpio); + void (*set_value)(int gpio, int value); +} gpio_ops_t; + +int gpio_get_direction(int gpio); +void gpio_set_direction(int gpio, int direction); +int gpio_get_value(int gpio); +void gpio_set_value(int gpio, int value); +void gpio_init(const gpio_ops_t *ops); + +#endif /* __GPIO_H__ */ diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h index 067b8302..d1ad31dc 100644 --- a/include/lib/aarch64/arch_helpers.h +++ b/include/lib/aarch64/arch_helpers.h @@ -194,6 +194,8 @@ DEFINE_SYSOP_FUNC(wfe) DEFINE_SYSOP_FUNC(sev) DEFINE_SYSOP_TYPE_FUNC(dsb, sy) DEFINE_SYSOP_TYPE_FUNC(dmb, sy) +DEFINE_SYSOP_TYPE_FUNC(dmb, st) +DEFINE_SYSOP_TYPE_FUNC(dmb, ld) DEFINE_SYSOP_TYPE_FUNC(dsb, ish) DEFINE_SYSOP_TYPE_FUNC(dmb, ish) DEFINE_SYSOP_FUNC(isb) diff --git a/include/lib/cpus/aarch64/cortex_a57.h b/include/lib/cpus/aarch64/cortex_a57.h index c81259c8..c512129a 100644 --- a/include/lib/cpus/aarch64/cortex_a57.h +++ b/include/lib/cpus/aarch64/cortex_a57.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -61,8 +61,9 @@ ******************************************************************************/ #define CPUACTLR_EL1 S3_1_C15_C2_0 /* Instruction def. */ -#define CPUACTLR_NO_ALLOC_WBWA (1 << 49) -#define CPUACTLR_DCC_AS_DCCI (1 << 44) +#define CPUACTLR_DIS_OVERREAD (1 << 52) +#define CPUACTLR_NO_ALLOC_WBWA (1 << 49) +#define CPUACTLR_DCC_AS_DCCI (1 << 44) /******************************************************************************* * L2 Control register specific definitions. diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h index db2a8dfb..b065537d 100644 --- a/include/plat/arm/board/common/board_arm_def.h +++ b/include/plat/arm/board/common/board_arm_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -60,80 +60,28 @@ #endif /* - * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the - * plat_arm_mmap array defined for each BL stage. + * The constants below are not optimised for memory usage. Platforms that wish + * to optimise these constants should set `ARM_BOARD_OPTIMISE_MMAP` to 1 and + * provide there own values. */ -#if IMAGE_BL1 -# if PLAT_fvp -# if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MMAP_ENTRIES 8 -# else -# define PLAT_ARM_MMAP_ENTRIES 7 -# endif /* TRUSTED_BOARD_BOOT */ -# else -# if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MMAP_ENTRIES 7 -# else -# define PLAT_ARM_MMAP_ENTRIES 6 -# endif /* TRUSTED_BOARD_BOOT */ -# endif /* PLAT_ */ -#endif -#if IMAGE_BL2 -# if PLAT_fvp -# define PLAT_ARM_MMAP_ENTRIES 9 -# else -# define PLAT_ARM_MMAP_ENTRIES 8 -# endif -#endif -#if IMAGE_BL2U -# if PLAT_fvp -# define PLAT_ARM_MMAP_ENTRIES 3 -# else -# define PLAT_ARM_MMAP_ENTRIES 4 -#endif -#endif -#if IMAGE_BL31 -#define PLAT_ARM_MMAP_ENTRIES 5 -#endif -#if IMAGE_BL32 -#define PLAT_ARM_MMAP_ENTRIES 4 -#endif - +#if !ARM_BOARD_OPTIMISE_MMAP /* - * Platform specific page table and MMU setup constants + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + * + * Provide relatively optimised values for the runtime images (BL31 and BL32). + * Optimisation is less important for the other, transient boot images so a + * common, maximum value is used across these images. */ -#if IMAGE_BL1 -# if TRUSTED_BOARD_BOOT -# define MAX_XLAT_TABLES 4 -# else -# if PLAT_juno -# define MAX_XLAT_TABLES 2 -# else -# define MAX_XLAT_TABLES 3 -# endif /* PLAT_ */ -# endif /* TRUSTED_BOARD_BOOT */ -#elif IMAGE_BL2 -# if PLAT_juno -# define MAX_XLAT_TABLES 3 -# else -# define MAX_XLAT_TABLES 4 -# endif /* PLAT_ */ -#elif IMAGE_BL2U -# if PLAT_juno -# define MAX_XLAT_TABLES 3 -# else -# define MAX_XLAT_TABLES 4 -# endif /* PLAT_ */ -#elif IMAGE_BL31 -# define MAX_XLAT_TABLES 2 -#elif IMAGE_BL32 -# if ARM_TSP_RAM_LOCATION_ID == ARM_DRAM_ID -# define MAX_XLAT_TABLES 3 -# else -# define MAX_XLAT_TABLES 2 -# endif +#if IMAGE_BL31 || IMAGE_BL32 +# define PLAT_ARM_MMAP_ENTRIES 6 +# define MAX_XLAT_TABLES 3 +#else +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 4 #endif +#endif /* ARM_BOARD_OPTIMISE_MMAP */ #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 @@ -143,5 +91,8 @@ #define PLAT_ARM_FIP_BASE V2M_FLASH0_BASE #define PLAT_ARM_FIP_MAX_SIZE V2M_FLASH0_SIZE +#define PLAT_ARM_NVM_BASE V2M_FLASH0_BASE +#define PLAT_ARM_NVM_SIZE V2M_FLASH0_SIZE + #endif /* __BOARD_ARM_DEF_H__ */ diff --git a/include/plat/arm/common/aarch64/arm_macros.S b/include/plat/arm/common/aarch64/arm_macros.S index 384bb514..3b19a7d0 100644 --- a/include/plat/arm/common/aarch64/arm_macros.S +++ b/include/plat/arm/common/aarch64/arm_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,7 +30,6 @@ #ifndef __ARM_MACROS_S__ #define __ARM_MACROS_S__ -#include <cci.h> #include <gic_common.h> #include <gicv2.h> #include <gicv3.h> @@ -117,31 +116,4 @@ gicd_ispendr_loop: exit_print_gic_regs: .endm - -.section .rodata.cci_reg_name, "aS" -cci_iface_regs: - .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" - - /* ------------------------------------------------ - * The below required platform porting macro prints - * out relevant interconnect registers whenever an - * unhandled exception is taken in BL31. - * Clobbers: x0 - x9, sp - * ------------------------------------------------ - */ - .macro plat_print_interconnect_regs - adr x6, cci_iface_regs - /* Store in x7 the base address of the first interface */ - mov_imm x7, (PLAT_ARM_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX)) - ldr w8, [x7, #SNOOP_CTRL_REG] - /* Store in x7 the base address of the second interface */ - mov_imm x7, (PLAT_ARM_CCI_BASE + SLAVE_IFACE_OFFSET( \ - PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX)) - ldr w9, [x7, #SNOOP_CTRL_REG] - /* Store to the crash buf and print to console */ - bl str_in_crash_buf_print - .endm - - #endif /* __ARM_MACROS_S__ */ diff --git a/include/plat/arm/common/aarch64/cci_macros.S b/include/plat/arm/common/aarch64/cci_macros.S new file mode 100644 index 00000000..40f9d7e0 --- /dev/null +++ b/include/plat/arm/common/aarch64/cci_macros.S @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __CCI_MACROS_S__ +#define __CCI_MACROS_S__ + +#include <cci.h> +#include <platform_def.h> + +.section .rodata.cci_reg_name, "aS" +cci_iface_regs: + .asciz "cci_snoop_ctrl_cluster0", "cci_snoop_ctrl_cluster1" , "" + + /* ------------------------------------------------ + * The below required platform porting macro prints + * out relevant interconnect registers whenever an + * unhandled exception is taken in BL31. + * Clobbers: x0 - x9, sp + * ------------------------------------------------ + */ + .macro plat_print_interconnect_regs + adr x6, cci_iface_regs + /* Store in x7 the base address of the first interface */ + mov_imm x7, (PLAT_ARM_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX)) + ldr w8, [x7, #SNOOP_CTRL_REG] + /* Store in x7 the base address of the second interface */ + mov_imm x7, (PLAT_ARM_CCI_BASE + SLAVE_IFACE_OFFSET( \ + PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX)) + ldr w9, [x7, #SNOOP_CTRL_REG] + /* Store to the crash buf and print to console */ + bl str_in_crash_buf_print + .endm + +#endif /* __CCI_MACROS_S__ */ diff --git a/include/plat/arm/common/arm_config.h b/include/plat/arm/common/arm_config.h index 24c1f0a1..03808498 100644 --- a/include/plat/arm/common/arm_config.h +++ b/include/plat/arm/common/arm_config.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -35,8 +35,8 @@ enum arm_config_flags { /* Whether Base memory map is in use */ ARM_CONFIG_BASE_MMAP = 0x1, - /* Whether CCI should be enabled */ - ARM_CONFIG_HAS_CCI = 0x2, + /* Whether interconnect should be enabled */ + ARM_CONFIG_HAS_INTERCONNECT = 0x2, /* Whether TZC should be configured */ ARM_CONFIG_HAS_TZC = 0x4 }; diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index b2db6160..d04f9d6f 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,7 +44,6 @@ /* Special value used to verify platform parameters from BL2 to BL31 */ #define ARM_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL -#define ARM_CLUSTER_COUNT 2 #define ARM_SYSTEM_COUNT 1 #define ARM_CACHE_WRITEBACK_SHIFT 6 @@ -151,14 +150,10 @@ #define ARM_G0_IRQS ARM_IRQ_SEC_SGI_0, \ ARM_IRQ_SEC_SGI_6 -#define ARM_SHARED_RAM_ATTR ((PLAT_ARM_SHARED_RAM_CACHED ? \ - MT_MEMORY : MT_DEVICE) \ - | MT_RW | MT_SECURE) - #define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ ARM_SHARED_RAM_BASE, \ ARM_SHARED_RAM_SIZE, \ - ARM_SHARED_RAM_ATTR) + MT_DEVICE | MT_RW | MT_SECURE) #define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ ARM_NS_DRAM1_BASE, \ @@ -218,10 +213,6 @@ */ #define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF - -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER0_CORE_COUNT + \ - PLAT_ARM_CLUSTER1_CORE_COUNT) - /* * Some data must be aligned on the biggest cache line size in the platform. * This is known only to the platform as it might have a combination of @@ -239,44 +230,31 @@ #define BL1_RO_LIMIT (PLAT_ARM_TRUSTED_ROM_BASE \ + PLAT_ARM_TRUSTED_ROM_SIZE) /* - * Put BL1 RW at the top of the Trusted SRAM. BL1_RW_BASE is calculated using - * the current BL1 RW debug size plus a little space for growth. + * Put BL1 RW at the top of the Trusted SRAM. */ -#if TRUSTED_BOARD_BOOT #define BL1_RW_BASE (ARM_BL_RAM_BASE + \ ARM_BL_RAM_SIZE - \ - 0x9000) -#else -#define BL1_RW_BASE (ARM_BL_RAM_BASE + \ - ARM_BL_RAM_SIZE - \ - 0x6000) -#endif + PLAT_ARM_MAX_BL1_RW_SIZE) #define BL1_RW_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) /******************************************************************************* * BL2 specific defines. ******************************************************************************/ /* - * Put BL2 just below BL31. BL2_BASE is calculated using the current BL2 debug - * size plus a little space for growth. + * Put BL2 just below BL31. */ -#if TRUSTED_BOARD_BOOT -#define BL2_BASE (BL31_BASE - 0x1D000) -#else -#define BL2_BASE (BL31_BASE - 0xC000) -#endif +#define BL2_BASE (BL31_BASE - PLAT_ARM_MAX_BL2_SIZE) #define BL2_LIMIT BL31_BASE /******************************************************************************* * BL31 specific defines. ******************************************************************************/ /* - * Put BL31 at the top of the Trusted SRAM. BL31_BASE is calculated using the - * current BL31 debug size plus a little space for growth. + * Put BL31 at the top of the Trusted SRAM. */ #define BL31_BASE (ARM_BL_RAM_BASE + \ ARM_BL_RAM_SIZE - \ - 0x1D000) + PLAT_ARM_MAX_BL31_SIZE) #define BL31_PROGBITS_LIMIT BL1_RW_BASE #define BL31_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) @@ -316,7 +294,7 @@ #define BL2U_BASE BL2_BASE #define BL2U_LIMIT BL31_BASE #define NS_BL2U_BASE ARM_NS_DRAM1_BASE -#define NS_BL1U_BASE (V2M_FLASH0_BASE + 0x03EB8000) +#define NS_BL1U_BASE (PLAT_ARM_NVM_BASE + 0x03EB8000) /* * ID of the secure physical generic timer interrupt used by the TSP. diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index 3b6a04ba..e9eebaa0 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,11 +37,6 @@ #include <stdint.h> #include <xlat_tables.h> -/* - * Extern declarations common to ARM standard platforms - */ -extern const mmap_region_t plat_arm_mmap[]; - #define ARM_CASSERT_MMAP \ CASSERT((ARRAY_SIZE(plat_arm_mmap) + ARM_BL_REGIONS) \ <= MAX_MMAP_REGIONS, \ @@ -131,9 +126,6 @@ void arm_configure_mmu_el3(unsigned long total_base, #endif /* __ARM_RECOM_STATE_ID_ENC__ */ -/* CCI utility functions */ -void arm_cci_init(void); - /* IO storage utility functions */ void arm_io_setup(void); @@ -187,6 +179,7 @@ int arm_io_is_toc_valid(void); /* * Mandatory functions required in ARM standard platforms */ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr); void plat_arm_gic_driver_init(void); void plat_arm_gic_init(void); void plat_arm_gic_cpuif_enable(void); @@ -194,6 +187,9 @@ void plat_arm_gic_cpuif_disable(void); void plat_arm_gic_pcpu_init(void); void plat_arm_security_setup(void); void plat_arm_pwrc_setup(void); +void plat_arm_interconnect_init(void); +void plat_arm_interconnect_enter_coherency(void); +void plat_arm_interconnect_exit_coherency(void); /* * Optional functions required in ARM standard platforms @@ -204,6 +200,6 @@ int plat_arm_get_alt_image_source( uintptr_t *dev_handle, uintptr_t *image_spec); unsigned int plat_arm_calc_core_pos(u_register_t mpidr); - +const mmap_region_t *plat_arm_get_mmap(void); #endif /* __PLAT_ARM_H__ */ diff --git a/include/plat/arm/css/common/css_def.h b/include/plat/arm/css/common/css_def.h index c900278b..f92126ba 100644 --- a/include/plat/arm/css/common/css_def.h +++ b/include/plat/arm/css/common/css_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,15 +37,12 @@ /************************************************************************* * Definitions common to all ARM Compute SubSystems (CSS) *************************************************************************/ -#define MHU_PAYLOAD_CACHED 0 - #define NSROM_BASE 0x1f000000 #define NSROM_SIZE 0x00001000 /* Following covers CSS Peripherals excluding NSROM and NSRAM */ #define CSS_DEVICE_BASE 0x20000000 #define CSS_DEVICE_SIZE 0x0e000000 -#define MHU_BASE 0x2b1f0000 #define NSRAM_BASE 0x2e000000 #define NSRAM_SIZE 0x00008000 @@ -78,31 +75,47 @@ * SCP <=> AP boot configuration * * The SCP/AP boot configuration is a 32-bit word located at a known offset from - * the start of the Trusted SRAM. Part of this configuration is which CPU is the - * primary, according to the shift and mask definitions below. + * the start of the Trusted SRAM. * * Note that the value stored at this address is only valid at boot time, before * the SCP_BL2 image is transferred to SCP. */ -#define SCP_BOOT_CFG_ADDR (ARM_TRUSTED_SRAM_BASE + 0x80) -#define PRIMARY_CPU_SHIFT 8 -#define PRIMARY_CPU_BIT_WIDTH 4 - -/* - * Base address of the first memory region used for communication between AP - * and SCP. Used by the BOM and SCPI protocols. - * - * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which - * means the SCP/AP configuration data gets overwritten when the AP initiates - * communication with the SCP. - */ -#define SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + 0x80) +#define SCP_BOOT_CFG_ADDR PLAT_CSS_SCP_COM_SHARED_MEM_BASE #define CSS_MAP_DEVICE MAP_REGION_FLAT( \ CSS_DEVICE_BASE, \ CSS_DEVICE_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +/* Platform ID address */ +#define SSC_VERSION_OFFSET 0x040 + +#define SSC_VERSION_CONFIG_SHIFT 28 +#define SSC_VERSION_MAJOR_REV_SHIFT 24 +#define SSC_VERSION_MINOR_REV_SHIFT 20 +#define SSC_VERSION_DESIGNER_ID_SHIFT 12 +#define SSC_VERSION_PART_NUM_SHIFT 0x0 +#define SSC_VERSION_CONFIG_MASK 0xf +#define SSC_VERSION_MAJOR_REV_MASK 0xf +#define SSC_VERSION_MINOR_REV_MASK 0xf +#define SSC_VERSION_DESIGNER_ID_MASK 0xff +#define SSC_VERSION_PART_NUM_MASK 0xfff + +#ifndef __ASSEMBLY__ + +/* SSC_VERSION related accessors */ + +/* Returns the part number of the platform */ +#define GET_SSC_VERSION_PART_NUM(val) \ + (((val) >> SSC_VERSION_PART_NUM_SHIFT) & \ + SSC_VERSION_PART_NUM_MASK) + +/* Returns the configuration number of the platform */ +#define GET_SSC_VERSION_CONFIG(val) \ + (((val) >> SSC_VERSION_CONFIG_SHIFT) & \ + SSC_VERSION_CONFIG_MASK) + +#endif /* __ASSEMBLY__ */ /************************************************************************* * Required platform porting definitions common to all @@ -110,6 +123,13 @@ ************************************************************************/ /* + * The loading of SCP images(SCP_BL2 or SCP_BL2U) is done if there + * respective base addresses are defined (i.e SCP_BL2_BASE, SCP_BL2U_BASE). + * Hence, `CSS_LOAD_SCP_IMAGES` needs to be set to 1 if BL2 needs to load + * an SCP_BL2/SCP_BL2U image. + */ +#if CSS_LOAD_SCP_IMAGES +/* * Load address of SCP_BL2 in CSS platform ports * SCP_BL2 is loaded to the same place as BL31. Once SCP_BL2 is transferred to the * SCP, it is discarded and BL31 is loaded over the top. @@ -117,18 +137,13 @@ #define SCP_BL2_BASE BL31_BASE #define SCP_BL2U_BASE BL31_BASE - -#define PLAT_ARM_SHARED_RAM_CACHED MHU_PAYLOAD_CACHED +#endif /* CSS_LOAD_SCP_IMAGES */ /* Load address of Non-Secure Image for CSS platform ports */ #define PLAT_ARM_NS_IMAGE_OFFSET 0xE0000000 /* TZC related constants */ #define PLAT_ARM_TZC_FILTERS REG_ATTR_FILTER_BIT_ALL -#define PLAT_ARM_TZC_BASE 0x2a4a0000 - -/* System timer related constants */ -#define PLAT_ARM_NSTIMER_FRAME_ID 1 /* Trusted mailbox base address common to all CSS */ #define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h index 916720c5..9fac9fa2 100644 --- a/include/plat/common/common_def.h +++ b/include/plat/common/common_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -72,11 +72,12 @@ #define BL2_IMAGE_DESC { \ .image_id = BL2_IMAGE_ID, \ - .image_info.h.version = VERSION_1, \ - .image_info.h.attr = SET_EXEC_STATE(EXECUTABLE),\ + SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, \ + VERSION_1, image_info_t, 0), \ .image_info.image_base = BL2_BASE, \ - .ep_info.h.attr = SET_SEC_STATE(SECURE), \ - .ep_info.pc = BL2_BASE \ + SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, \ + VERSION_1, entry_point_info_t, SECURE | EXECUTABLE),\ + .ep_info.pc = BL2_BASE, \ } #endif /* __COMMON_DEF_H__ */ diff --git a/lib/cpus/aarch64/cortex_a35.S b/lib/cpus/aarch64/cortex_a35.S index 6a447c01..ba29d6d4 100644 --- a/lib/cpus/aarch64/cortex_a35.S +++ b/lib/cpus/aarch64/cortex_a35.S @@ -67,16 +67,12 @@ endfunc cortex_a35_disable_smp */ func cortex_a35_reset_func /* --------------------------------------------- - * As a bare minimum enable the SMP bit if it is - * not already set. + * Enable the SMP bit. * --------------------------------------------- */ mrs x0, CORTEX_A35_CPUECTLR_EL1 - tst x0, #CORTEX_A35_CPUECTLR_SMPEN_BIT - b.ne skip_smp_setup orr x0, x0, #CORTEX_A35_CPUECTLR_SMPEN_BIT msr CORTEX_A35_CPUECTLR_EL1, x0 -skip_smp_setup: isb ret endfunc cortex_a35_reset_func diff --git a/lib/cpus/aarch64/cortex_a53.S b/lib/cpus/aarch64/cortex_a53.S index e4b94e80..c33ba571 100644 --- a/lib/cpus/aarch64/cortex_a53.S +++ b/lib/cpus/aarch64/cortex_a53.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -86,33 +86,40 @@ apply_826319: ret endfunc errata_a53_826319_wa - /* -------------------------------------------------- - * Errata Workaround for Cortex A53 Errata #836870. - * This applies only to revision <= r0p3 of Cortex A53. - * From r0p4 and onwards, this errata is enabled by - * default. + /* --------------------------------------------------------------------- + * Disable the cache non-temporal hint. + * + * This ignores the Transient allocation hint in the MAIR and treats + * allocations the same as non-transient allocation types. As a result, + * the LDNP and STNP instructions in AArch64 behave the same as the + * equivalent LDP and STP instructions. + * + * This is relevant only for revisions <= r0p3 of Cortex-A53. + * From r0p4 and onwards, the bit to disable the hint is enabled by + * default at reset. + * * Inputs: * x0: variant[4:7] and revision[0:3] of current cpu. * Clobbers : x0 - x5 - * -------------------------------------------------- + * --------------------------------------------------------------------- */ -func errata_a53_836870_wa +func a53_disable_non_temporal_hint /* * Compare x0 against revision r0p3 */ cmp x0, #3 - b.ls apply_836870 + b.ls disable_hint #if DEBUG b print_revision_warning #else ret #endif -apply_836870: +disable_hint: mrs x1, CPUACTLR_EL1 orr x1, x1, #CPUACTLR_DTAH msr CPUACTLR_EL1, x1 ret -endfunc errata_a53_836870_wa +endfunc a53_disable_non_temporal_hint /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A53. @@ -138,22 +145,18 @@ func cortex_a53_reset_func bl errata_a53_826319_wa #endif -#if ERRATA_A53_836870 +#if ERRATA_A53_836870 || A53_DISABLE_NON_TEMPORAL_HINT mov x0, x15 - bl errata_a53_836870_wa + bl a53_disable_non_temporal_hint #endif /* --------------------------------------------- - * As a bare minimum enable the SMP bit if it is - * not already set. + * Enable the SMP bit. * --------------------------------------------- */ mrs x0, CPUECTLR_EL1 - tst x0, #CPUECTLR_SMP_BIT - b.ne skip_smp_setup orr x0, x0, #CPUECTLR_SMP_BIT msr CPUECTLR_EL1, x0 -skip_smp_setup: isb ret x19 endfunc cortex_a53_reset_func diff --git a/lib/cpus/aarch64/cortex_a57.S b/lib/cpus/aarch64/cortex_a57.S index 05799d61..99db25b8 100644 --- a/lib/cpus/aarch64/cortex_a57.S +++ b/lib/cpus/aarch64/cortex_a57.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -105,17 +105,9 @@ func errata_a57_806969_wa ret #endif apply_806969: - /* - * Test if errata has already been applied in an earlier - * invocation of the reset handler and does not need to - * be applied again. - */ mrs x1, CPUACTLR_EL1 - tst x1, #CPUACTLR_NO_ALLOC_WBWA - b.ne skip_806969 orr x1, x1, #CPUACTLR_NO_ALLOC_WBWA msr CPUACTLR_EL1, x1 -skip_806969: ret endfunc errata_a57_806969_wa @@ -139,20 +131,41 @@ func errata_a57_813420_wa ret #endif apply_813420: - /* - * Test if errata has already been applied in an earlier - * invocation of the reset handler and does not need to - * be applied again. - */ mrs x1, CPUACTLR_EL1 - tst x1, #CPUACTLR_DCC_AS_DCCI - b.ne skip_813420 orr x1, x1, #CPUACTLR_DCC_AS_DCCI msr CPUACTLR_EL1, x1 -skip_813420: ret endfunc errata_a57_813420_wa + /* -------------------------------------------------------------------- + * Disable the over-read from the LDNP instruction. + * + * This applies to all revisions <= r1p2. The performance degradation + * observed with LDNP/STNP has been fixed on r1p3 and onwards. + * + * Inputs: + * x0: variant[4:7] and revision[0:3] of current cpu. + * Clobbers : x0 - x5, x30 + * --------------------------------------------------------------------- + */ +func a57_disable_ldnp_overread + /* + * Compare x0 against revision r1p2 + */ + cmp x0, #0x12 + b.ls disable_hint +#if DEBUG + b print_revision_warning +#else + ret +#endif +disable_hint: + mrs x1, CPUACTLR_EL1 + orr x1, x1, #CPUACTLR_DIS_OVERREAD + msr CPUACTLR_EL1, x1 + ret +endfunc a57_disable_ldnp_overread + /* ------------------------------------------------- * The CPU Ops reset function for Cortex-A57. * Clobbers: x0-x5, x15, x19, x30 @@ -181,17 +194,18 @@ func cortex_a57_reset_func bl errata_a57_813420_wa #endif +#if A57_DISABLE_NON_TEMPORAL_HINT + mov x0, x15 + bl a57_disable_ldnp_overread +#endif + /* --------------------------------------------- - * As a bare minimum enable the SMP bit if it is - * not already set. + * Enable the SMP bit. * --------------------------------------------- */ mrs x0, CPUECTLR_EL1 - tst x0, #CPUECTLR_SMP_BIT - b.ne skip_smp_setup orr x0, x0, #CPUECTLR_SMP_BIT msr CPUECTLR_EL1, x0 -skip_smp_setup: isb ret x19 endfunc cortex_a57_reset_func diff --git a/lib/cpus/aarch64/cpu_helpers.S b/lib/cpus/aarch64/cpu_helpers.S index e8a13929..e41d95ba 100644 --- a/lib/cpus/aarch64/cpu_helpers.S +++ b/lib/cpus/aarch64/cpu_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -205,16 +205,17 @@ error_exit: endfunc get_cpu_ops_ptr #if DEBUG - /* - * This function prints a warning message to the crash console - * if the CPU revision/part number does not match the errata - * workaround enabled in the build. - * Clobber: x30, x0 - x5 - */ .section .rodata.rev_warn_str, "aS" rev_warn_str: - .asciz "Warning: Skipping Errata workaround for non matching CPU revision number.\n" + .asciz "Warning: Skipping CPU specific reset operation for non-matching CPU revision number.\n" + /* + * This function prints the above warning message to the crash console. + * It should be called when a CPU specific operation is enabled in the + * build but doesn't apply to this CPU revision/part number. + * + * Clobber: x30, x0 - x5 + */ .globl print_revision_warning func print_revision_warning mov x5, x30 diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk index a872360e..a3a08e15 100644 --- a/lib/cpus/cpu-ops.mk +++ b/lib/cpus/cpu-ops.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -32,10 +32,26 @@ # cluster is powered down. SKIP_A57_L1_FLUSH_PWR_DWN ?=0 +# Flag to disable the cache non-temporal hint. +# It is enabled by default. +A53_DISABLE_NON_TEMPORAL_HINT ?=1 + +# Flag to disable the cache non-temporal hint. +# It is enabled by default. +A57_DISABLE_NON_TEMPORAL_HINT ?=1 + # Process SKIP_A57_L1_FLUSH_PWR_DWN flag $(eval $(call assert_boolean,SKIP_A57_L1_FLUSH_PWR_DWN)) $(eval $(call add_define,SKIP_A57_L1_FLUSH_PWR_DWN)) +# Process A53_DISABLE_NON_TEMPORAL_HINT flag +$(eval $(call assert_boolean,A53_DISABLE_NON_TEMPORAL_HINT)) +$(eval $(call add_define,A53_DISABLE_NON_TEMPORAL_HINT)) + +# Process A57_DISABLE_NON_TEMPORAL_HINT flag +$(eval $(call assert_boolean,A57_DISABLE_NON_TEMPORAL_HINT)) +$(eval $(call add_define,A57_DISABLE_NON_TEMPORAL_HINT)) + # CPU Errata Build flags. These should be enabled by the # platform if the errata needs to be applied. diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk index d6a4e3ab..b22eaf90 100644 --- a/make_helpers/build_macros.mk +++ b/make_helpers/build_macros.mk @@ -290,6 +290,10 @@ define MAKE_TOOL_ARGS $(if $(3),$(eval $(call FIP_ADD_PAYLOAD,$(2),--$(3),bl$(1)))) endef +# Allow overriding the timestamp, for example for reproducible builds, or to +# synchronize timestamps across multiple projects. +# This must be set to a C string (including quotes where applicable). +BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__ # MAKE_BL macro defines the targets and options to build each BL image. # Arguments: @@ -315,7 +319,7 @@ $(BUILD_DIR): $(ELF): $(OBJS) $(LINKERFILE) @echo " LD $$@" - @echo 'const char build_message[] = "Built : "__TIME__", "__DATE__; \ + @echo 'const char build_message[] = "Built : "$(BUILD_MESSAGE_TIMESTAMP); \ const char version_string[] = "${VERSION_STRING}";' | \ $$(CC) $$(CFLAGS) -xc - -o $(BUILD_DIR)/build_message.o $$(Q)$$(LD) -o $$@ $$(LDFLAGS) -Map=$(MAPFILE) --script $(LINKERFILE) \ diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk index 9e0c8484..da6beec6 100644 --- a/plat/arm/board/common/board_common.mk +++ b/plat/arm/board/common/board_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -54,3 +54,10 @@ ifneq (${TRUSTED_BOARD_BOOT},0) BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c endif + +# This flag controls whether memory usage needs to be optimised +ARM_BOARD_OPTIMISE_MMAP ?= 0 + +# Process flags +$(eval $(call assert_boolean,ARM_BOARD_OPTIMISE_MMAP)) +$(eval $(call add_define,ARM_BOARD_OPTIMISE_MMAP)) diff --git a/plat/arm/board/fvp/aarch64/fvp_common.c b/plat/arm/board/fvp/aarch64/fvp_common.c index 305505d3..f684d977 100644 --- a/plat/arm/board/fvp/aarch64/fvp_common.c +++ b/plat/arm/board/fvp/aarch64/fvp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,7 +30,6 @@ #include <arm_config.h> #include <arm_def.h> -#include <cci.h> #include <debug.h> #include <gicv2.h> #include <mmio.h> @@ -50,9 +49,9 @@ extern gicv2_driver_data_t arm_gic_data; /******************************************************************************* * arm_config holds the characteristics of the differences between the three FVP * platforms (Base, A53_A57 & Foundation). It will be populated during cold boot - * at each boot stage by the primary before enabling the MMU (to allow cci - * configuration) & used thereafter. Each BL will have its own copy to allow - * independent operation. + * at each boot stage by the primary before enabling the MMU (to allow + * interconnect configuration) & used thereafter. Each BL will have its own copy + * to allow independent operation. ******************************************************************************/ arm_config_t arm_config; @@ -209,7 +208,7 @@ void fvp_config_setup(void) break; case HBI_BASE_FVP: arm_config.flags |= ARM_CONFIG_BASE_MMAP | - ARM_CONFIG_HAS_CCI | ARM_CONFIG_HAS_TZC; + ARM_CONFIG_HAS_INTERCONNECT | ARM_CONFIG_HAS_TZC; /* * Check for supported revisions @@ -230,23 +229,20 @@ void fvp_config_setup(void) } -void fvp_cci_init(void) +void fvp_interconnect_init(void) { - /* - * Initialize CCI-400 driver - */ - if (arm_config.flags & ARM_CONFIG_HAS_CCI) - arm_cci_init(); + if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) + plat_arm_interconnect_init(); } -void fvp_cci_enable(void) +void fvp_interconnect_enable(void) { - if (arm_config.flags & ARM_CONFIG_HAS_CCI) - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) + plat_arm_interconnect_enter_coherency(); } -void fvp_cci_disable(void) +void fvp_interconnect_disable(void) { - if (arm_config.flags & ARM_CONFIG_HAS_CCI) - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) + plat_arm_interconnect_exit_coherency(); } diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index 91bc9c4e..cc7feae7 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,14 +44,14 @@ void bl1_early_platform_setup(void) fvp_config_setup(); /* - * Initialize CCI for this cluster during cold boot. + * Initialize Interconnect for this cluster during cold boot. * No need for locks as no other CPU is active. */ - fvp_cci_init(); + fvp_interconnect_init(); /* - * Enable CCI coherency for the primary CPU's cluster. + * Enable coherency in Interconnect for the primary CPU's cluster. */ - fvp_cci_enable(); + fvp_interconnect_enable(); } /******************************************************************************* diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index f29af647..2ee3ba56 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,17 +41,17 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, fvp_config_setup(); /* - * Initialize CCI for this cluster during cold boot. - * No need for locks as no other CPU is active. + * Initialize the correct interconnect for this cluster during cold + * boot. No need for locks as no other CPU is active. */ - fvp_cci_init(); + fvp_interconnect_init(); /* - * Enable CCI coherency for the primary CPU's cluster. + * Enable coherency in interconnect for the primary CPU's cluster. * Earlier bootloader stages might already do this (e.g. Trusted * Firmware's BL1 does it) but we can't assume so. There is no harm in * executing this code twice anyway. * FVP PSCI code will enable coherency for other clusters. */ - fvp_cci_enable(); + fvp_interconnect_enable(); } diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 41b872af..dbca280c 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,9 @@ #include <arm_def.h> - +#ifndef FVP_CLUSTER_COUNT +#define FVP_CLUSTER_COUNT 2 +#endif #define FVP_MAX_CPUS_PER_CLUSTER 4 #define FVP_PRIMARY_CPU 0x0 diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index f959fab5..3976ef2b 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -86,7 +86,7 @@ static void fvp_cluster_pwrdwn_common(void) uint64_t mpidr = read_mpidr_el1(); /* Disable coherency if this cluster is to be turned off */ - fvp_cci_disable(); + fvp_interconnect_disable(); /* Program the power controller to turn the cluster off */ fvp_pwrc_write_pcoffr(mpidr); @@ -117,7 +117,7 @@ static void fvp_power_domain_on_finish_common(const psci_power_state_t *target_s fvp_pwrc_write_pponr(mpidr); /* Enable coherency if this cluster was off */ - fvp_cci_enable(); + fvp_interconnect_enable(); } /* diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h index e88a45ef..bb115e17 100644 --- a/plat/arm/board/fvp/fvp_private.h +++ b/plat/arm/board/fvp/fvp_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,9 +39,9 @@ void fvp_config_setup(void); -void fvp_cci_init(void); -void fvp_cci_enable(void); -void fvp_cci_disable(void); +void fvp_interconnect_init(void); +void fvp_interconnect_enable(void); +void fvp_interconnect_disable(void); #endif /* __FVP_PRIVATE_H__ */ diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index a212eda7..741aad64 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,27 +29,47 @@ */ #include <arch.h> +#include <cassert.h> #include <plat_arm.h> #include <platform_def.h> #include "drivers/pwrc/fvp_pwrc.h" -/* - * The FVP power domain tree does not have a single system level power domain - * i.e. a single root node. The first entry in the power domain descriptor - * specifies the number of power domains at the highest power level. For the FVP - * this is 2 i.e. the number of cluster power domains. - */ -#define FVP_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_CLUSTER_COUNT - /* The FVP power domain tree descriptor */ -const unsigned char arm_power_domain_tree_desc[] = { - /* No of root nodes */ - FVP_PWR_DOMAINS_AT_MAX_PWR_LVL, - /* No of children for the first node */ - PLAT_ARM_CLUSTER0_CORE_COUNT, - /* No of children for the second node */ - PLAT_ARM_CLUSTER1_CORE_COUNT -}; +unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 1]; + + +CASSERT(FVP_CLUSTER_COUNT && FVP_CLUSTER_COUNT <= 256, assert_invalid_fvp_cluster_count); + +/******************************************************************************* + * This function dynamically constructs the topology according to + * FVP_CLUSTER_COUNT and returns it. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + /* + * The FVP power domain tree does not have a single system level power domain + * i.e. a single root node. The first entry in the power domain descriptor + * specifies the number of power domains at the highest power level. For the FVP + * this is the number of cluster power domains. + */ + fvp_power_domain_tree_desc[0] = FVP_CLUSTER_COUNT; + + for (i = 0; i < FVP_CLUSTER_COUNT; i++) + fvp_power_domain_tree_desc[i + 1] = FVP_MAX_CPUS_PER_CLUSTER; + + return fvp_power_domain_tree_desc; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return FVP_MAX_CPUS_PER_CLUSTER; +} /******************************************************************************* * This function implements a part of the critical interface between the psci diff --git a/plat/arm/board/fvp/include/plat_macros.S b/plat/arm/board/fvp/include/plat_macros.S index 2117843d..df66a520 100644 --- a/plat/arm/board/fvp/include/plat_macros.S +++ b/plat/arm/board/fvp/include/plat_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,6 +31,7 @@ #define __PLAT_MACROS_S__ #include <arm_macros.S> +#include <cci_macros.S> #include <v2m_def.h> #include "../fvp_def.h" diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 0d671dc0..a8267dec 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -39,9 +39,10 @@ #include "../fvp_def.h" /* Required platform porting definitions */ -#define PLAT_NUM_PWR_DOMAINS (ARM_CLUSTER_COUNT + \ +#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) #define PLAT_MAX_PWR_LVL ARM_PWR_LVL1 +#define PLATFORM_CORE_COUNT (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER) /* * Other platform porting definitions are provided by included headers @@ -50,8 +51,7 @@ /* * Required ARM standard platform porting definitions */ -#define PLAT_ARM_CLUSTER0_CORE_COUNT 4 -#define PLAT_ARM_CLUSTER1_CORE_COUNT 4 +#define PLAT_ARM_CLUSTER_COUNT FVP_CLUSTER_COUNT #define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000 #define PLAT_ARM_TRUSTED_ROM_SIZE 0x04000000 /* 64 MB */ @@ -64,8 +64,6 @@ #define PLAT_ARM_DRAM2_SIZE MAKE_ULL(0x780000000) -#define PLAT_ARM_SHARED_RAM_CACHED 1 - /* * Load address of BL33 for this platform port */ @@ -144,4 +142,30 @@ #define PLAT_ARM_G0_IRQS ARM_G0_IRQS +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL1_RW_SIZE 0x9000 +#else +# define PLAT_ARM_MAX_BL1_RW_SIZE 0x6000 +#endif + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL2_SIZE 0x1D000 +#else +# define PLAT_ARM_MAX_BL2_SIZE 0xC000 +#endif + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_ARM_MAX_BL31_SIZE 0x1D000 + #endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index ed4c8984..aad2e2ef 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -34,6 +34,11 @@ FVP_USE_GIC_DRIVER := FVP_GICV3_LEGACY # The FVP platform depends on this macro to build with correct GIC driver. $(eval $(call add_define,FVP_USE_GIC_DRIVER)) +# If FVP_CLUSTER_COUNT has been defined, pass it into the build system. +ifdef FVP_CLUSTER_COUNT +$(eval $(call add_define,FVP_CLUSTER_COUNT)) +endif + # Choose the GIC sources depending upon the how the FVP will be invoked ifeq (${FVP_USE_GIC_DRIVER}, FVP_GICV3) FVP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ @@ -57,6 +62,14 @@ else $(error "Incorrect GIC driver chosen on FVP port") endif +FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \ + plat/arm/common/arm_cci.c + +FVP_SECURITY_SOURCES := drivers/arm/tzc400/tzc400.c \ + plat/arm/board/fvp/fvp_security.c \ + plat/arm/common/arm_tzc400.c + + PLAT_INCLUDES := -Iplat/arm/board/fvp/include @@ -69,13 +82,15 @@ FVP_CPU_LIBS := lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a72.S BL1_SOURCES += drivers/io/io_semihosting.c \ - ${FVP_CPU_LIBS} \ lib/semihosting/semihosting.c \ lib/semihosting/aarch64/semihosting_call.S \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ plat/arm/board/fvp/fvp_bl1_setup.c \ plat/arm/board/fvp/fvp_err.c \ - plat/arm/board/fvp/fvp_io_storage.c + plat/arm/board/fvp/fvp_io_storage.c \ + ${FVP_CPU_LIBS} \ + ${FVP_INTERCONNECT_SOURCES} + BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c \ drivers/io/io_semihosting.c \ @@ -85,19 +100,20 @@ BL2_SOURCES += drivers/arm/sp804/sp804_delay_timer.c \ plat/arm/board/fvp/fvp_bl2_setup.c \ plat/arm/board/fvp/fvp_err.c \ plat/arm/board/fvp/fvp_io_storage.c \ - plat/arm/board/fvp/fvp_security.c + ${FVP_SECURITY_SOURCES} BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ - plat/arm/board/fvp/fvp_security.c + ${FVP_SECURITY_SOURCES} -BL31_SOURCES += ${FVP_CPU_LIBS} \ - plat/arm/board/fvp/fvp_bl31_setup.c \ +BL31_SOURCES += plat/arm/board/fvp/fvp_bl31_setup.c \ plat/arm/board/fvp/fvp_pm.c \ - plat/arm/board/fvp/fvp_security.c \ plat/arm/board/fvp/fvp_topology.c \ plat/arm/board/fvp/aarch64/fvp_helpers.S \ plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \ - ${FVP_GIC_SOURCES} + ${FVP_CPU_LIBS} \ + ${FVP_GIC_SOURCES} \ + ${FVP_INTERCONNECT_SOURCES} \ + ${FVP_SECURITY_SOURCES} # Disable the PSCI platform compatibility layer ENABLE_PLAT_COMPAT := 0 diff --git a/plat/arm/board/juno/include/plat_macros.S b/plat/arm/board/juno/include/plat_macros.S index db0c1d20..d2a88edb 100644 --- a/plat/arm/board/juno/include/plat_macros.S +++ b/plat/arm/board/juno/include/plat_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,6 +30,7 @@ #ifndef __PLAT_MACROS_S__ #define __PLAT_MACROS_S__ +#include <cci_macros.S> #include <css_macros.S> /* diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 924eb0ab..a2cf0368 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -41,11 +41,15 @@ #include <v2m_def.h> #include "../juno_def.h" +/* Required platform porting definitions */ /* Juno supports system power domain */ #define PLAT_MAX_PWR_LVL ARM_PWR_LVL2 #define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \ - ARM_CLUSTER_COUNT + \ + JUNO_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) +#define PLATFORM_CORE_COUNT (JUNO_CLUSTER0_CORE_COUNT + \ + JUNO_CLUSTER1_CORE_COUNT) + /* * Other platform porting definitions are provided by included headers */ @@ -53,8 +57,7 @@ /* * Required ARM standard platform porting definitions */ -#define PLAT_ARM_CLUSTER0_CORE_COUNT 2 -#define PLAT_ARM_CLUSTER1_CORE_COUNT 4 +#define PLAT_ARM_CLUSTER_COUNT JUNO_CLUSTER_COUNT /* Use the bypass address */ #define PLAT_ARM_TRUSTED_ROM_BASE V2M_FLASH0_BASE + BL1_ROM_BYPASS_OFFSET @@ -70,13 +73,52 @@ #define PLAT_ARM_TRUSTED_ROM_SIZE 0x00010000 #endif /* TRUSTED_BOARD_BOOT */ +/* + * If ARM_BOARD_OPTIMISE_MMAP=0 then Juno uses the default, unoptimised values + * defined for ARM development platforms. + */ +#if ARM_BOARD_OPTIMISE_MMAP +/* + * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the + * plat_arm_mmap array defined for each BL stage. + */ +#if IMAGE_BL1 +# define PLAT_ARM_MMAP_ENTRIES 7 +# define MAX_XLAT_TABLES 4 +#endif + +#if IMAGE_BL2 +# define PLAT_ARM_MMAP_ENTRIES 8 +# define MAX_XLAT_TABLES 3 +#endif + +#if IMAGE_BL2U +# define PLAT_ARM_MMAP_ENTRIES 4 +# define MAX_XLAT_TABLES 3 +#endif + +#if IMAGE_BL31 +# define PLAT_ARM_MMAP_ENTRIES 5 +# define MAX_XLAT_TABLES 2 +#endif + +#if IMAGE_BL32 +# define PLAT_ARM_MMAP_ENTRIES 4 +# define MAX_XLAT_TABLES 3 +#endif + +#endif /* ARM_BOARD_OPTIMISE_MMAP */ /* CCI related constants */ #define PLAT_ARM_CCI_BASE 0x2c090000 #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 4 #define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 3 +/* System timer related constants */ +#define PLAT_ARM_NSTIMER_FRAME_ID 1 + /* TZC related constants */ +#define PLAT_ARM_TZC_BASE 0x2a4a0000 #define PLAT_ARM_TZC_NS_DEV_ACCESS ( \ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_CCI400) | \ TZC_REGION_ACCESS_RDWR(TZC400_NSAID_PCIE) | \ @@ -99,6 +141,23 @@ #define PLAT_ARM_GICH_BASE 0x2c04f000 #define PLAT_ARM_GICV_BASE 0x2c06f000 +/* MHU related constants */ +#define PLAT_CSS_MHU_BASE 0x2b1f0000 + +/* + * Base address of the first memory region used for communication between AP + * and SCP. Used by the BOM and SCPI protocols. + * + * Note that this is located at the same address as SCP_BOOT_CFG_ADDR, which + * means the SCP/AP configuration data gets overwritten when the AP initiates + * communication with the SCP. The configuration data is expected to be a + * 32-bit word on all CSS platforms. On Juno, part of this configuration is + * which CPU is the primary, according to the shift and mask definitions below. + */ +#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE (ARM_TRUSTED_SRAM_BASE + 0x80) +#define PLAT_CSS_PRIMARY_CPU_SHIFT 8 +#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 4 + /* * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 * terminology. On a GICv2 system or mode, the lists will be merged and treated @@ -124,5 +183,30 @@ /* CSS SoC NIC-400 Global Programmers View (GPV) */ #define PLAT_SOC_CSS_NIC400_BASE 0x2a000000 +/* + * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size + * plus a little space for growth. + */ +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL1_RW_SIZE 0x9000 +#else +# define PLAT_ARM_MAX_BL1_RW_SIZE 0x6000 +#endif + +/* + * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a + * little space for growth. + */ +#if TRUSTED_BOARD_BOOT +# define PLAT_ARM_MAX_BL2_SIZE 0x1D000 +#else +# define PLAT_ARM_MAX_BL2_SIZE 0xC000 +#endif + +/* + * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a + * little space for growth. + */ +#define PLAT_ARM_MAX_BL31_SIZE 0x1D000 #endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index 1f367f27..f27bbb22 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -50,6 +50,14 @@ #define PSRAM_BASE 0x14000000 #define PSRAM_SIZE 0x02000000 +#define JUNO_SSC_VER_PART_NUM 0x030 + +/******************************************************************************* + * Juno topology related constants + ******************************************************************************/ +#define JUNO_CLUSTER_COUNT 2 +#define JUNO_CLUSTER0_CORE_COUNT 2 +#define JUNO_CLUSTER1_CORE_COUNT 4 /******************************************************************************* * TZC-400 related constants diff --git a/plat/arm/board/juno/juno_topology.c b/plat/arm/board/juno/juno_topology.c new file mode 100644 index 00000000..ee4ec441 --- /dev/null +++ b/plat/arm/board/juno/juno_topology.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arm_def.h> +#include <plat_arm.h> +#include "juno_def.h" + +/* + * On Juno, the system power level is the highest power level. + * The first entry in the power domain descriptor specifies the + * number of system power domains i.e. 1. + */ +#define JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT + +/* + * The Juno power domain tree descriptor. The cluster power domains + * are arranged so that when the PSCI generic code creates the power + * domain tree, the indices of the CPU power domain nodes it allocates + * match the linear indices returned by plat_core_pos_by_mpidr() + * i.e. CLUSTER1 CPUs are allocated indices from 0 to 3 and the higher + * indices for CLUSTER0 CPUs. + */ +const unsigned char juno_power_domain_tree_desc[] = { + /* No of root nodes */ + JUNO_PWR_DOMAINS_AT_MAX_PWR_LVL, + /* No of children for the root node */ + JUNO_CLUSTER_COUNT, + /* No of children for the first cluster node */ + JUNO_CLUSTER1_CORE_COUNT, + /* No of children for the second cluster node */ + JUNO_CLUSTER0_CORE_COUNT +}; + +/******************************************************************************* + * This function returns the Juno topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return juno_power_domain_tree_desc; +} + +/******************************************************************************* + * This function returns the core count within the cluster corresponding to + * `mpidr`. + ******************************************************************************/ +unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) +{ + return (((mpidr) & 0x100) ? JUNO_CLUSTER1_CORE_COUNT :\ + JUNO_CLUSTER0_CORE_COUNT); +} diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index fae30e7e..0a2244d5 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -34,6 +34,14 @@ JUNO_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv2.c \ plat/arm/common/arm_gicv2.c +JUNO_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \ + plat/arm/common/arm_cci.c + +JUNO_SECURITY_SOURCES := drivers/arm/tzc400/tzc400.c \ + plat/arm/board/juno/juno_security.c \ + plat/arm/common/arm_tzc400.c + + PLAT_INCLUDES := -Iplat/arm/board/juno/include PLAT_BL_COMMON_SOURCES := plat/arm/board/juno/aarch64/juno_helpers.S @@ -42,30 +50,36 @@ BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ plat/arm/board/juno/juno_bl1_setup.c \ - plat/arm/board/juno/juno_err.c + plat/arm/board/juno/juno_err.c \ + ${JUNO_INTERCONNECT_SOURCES} -BL2_SOURCES += plat/arm/board/juno/juno_security.c \ - plat/arm/board/juno/juno_err.c +BL2_SOURCES += plat/arm/board/juno/juno_err.c \ + ${JUNO_SECURITY_SOURCES} -BL2U_SOURCES += plat/arm/board/juno/juno_security.c +BL2U_SOURCES += ${JUNO_SECURITY_SOURCES} BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ plat/arm/board/juno/juno_pm.c \ - plat/arm/board/juno/juno_security.c \ - ${JUNO_GIC_SOURCES} + plat/arm/board/juno/juno_topology.c \ + ${JUNO_GIC_SOURCES} \ + ${JUNO_INTERCONNECT_SOURCES} \ + ${JUNO_SECURITY_SOURCES} # Enable workarounds for selected Cortex-A57 erratas. -ERRATA_A57_806969 := 0 -ERRATA_A57_813420 := 1 +ERRATA_A57_806969 := 0 +ERRATA_A57_813420 := 1 # Enable option to skip L1 data cache flush during the Cortex-A57 cluster # power down sequence SKIP_A57_L1_FLUSH_PWR_DWN := 1 # Disable the PSCI platform compatibility layer -ENABLE_PLAT_COMPAT := 0 +ENABLE_PLAT_COMPAT := 0 + +# Enable memory map related constants optimisation +ARM_BOARD_OPTIMISE_MMAP := 1 include plat/arm/board/common/board_css.mk include plat/arm/common/arm_common.mk diff --git a/plat/arm/board/juno/tsp/tsp-juno.mk b/plat/arm/board/juno/tsp/tsp-juno.mk index 2ef964e8..4e806078 100644 --- a/plat/arm/board/juno/tsp/tsp-juno.mk +++ b/plat/arm/board/juno/tsp/tsp-juno.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -28,7 +28,8 @@ # POSSIBILITY OF SUCH DAMAGE. # -BL32_SOURCES += plat/arm/css/common/css_topology.c \ +BL32_SOURCES += plat/arm/board/juno/juno_topology.c \ + plat/arm/css/common/css_topology.c \ ${JUNO_GIC_SOURCES} include plat/arm/common/tsp/arm_tsp.mk diff --git a/plat/arm/common/aarch64/arm_common.c b/plat/arm/common/aarch64/arm_common.c index a211f16d..c84a65b3 100644 --- a/plat/arm/common/aarch64/arm_common.c +++ b/plat/arm/common/aarch64/arm_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,20 +29,16 @@ */ #include <arch.h> #include <arch_helpers.h> -#include <cci.h> #include <mmio.h> #include <plat_arm.h> #include <platform_def.h> #include <xlat_tables.h> - -static const int cci_map[] = { - PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX, - PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX -}; +extern const mmap_region_t plat_arm_mmap[]; /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint +#pragma weak plat_arm_get_mmap /******************************************************************************* @@ -67,7 +63,7 @@ static const int cci_map[] = { mmap_add_region(coh_start, coh_start, \ coh_limit - coh_start, \ MT_DEVICE | MT_RW | MT_SECURE); \ - mmap_add(plat_arm_mmap); \ + mmap_add(plat_arm_get_mmap()); \ init_xlat_tables(); \ \ enable_mmu_el##_el(0); \ @@ -85,7 +81,7 @@ static const int cci_map[] = { mmap_add_region(ro_start, ro_start, \ ro_limit - ro_start, \ MT_MEMORY | MT_RO | MT_SECURE); \ - mmap_add(plat_arm_mmap); \ + mmap_add(plat_arm_get_mmap()); \ init_xlat_tables(); \ \ enable_mmu_el##_el(0); \ @@ -138,12 +134,6 @@ uint32_t arm_get_spsr_for_bl33_entry(void) return spsr; } - -void arm_cci_init(void) -{ - cci_init(PLAT_ARM_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); -} - /******************************************************************************* * Configures access to the system counter timer module. ******************************************************************************/ @@ -161,3 +151,11 @@ void arm_configure_sys_timer(void) reg_val = (1 << CNTNSAR_NS_SHIFT(PLAT_ARM_NSTIMER_FRAME_ID)); mmio_write_32(ARM_SYS_TIMCTL_BASE + CNTNSAR, reg_val); } + +/******************************************************************************* + * Returns ARM platform specific memory map regions. + ******************************************************************************/ +const mmap_region_t *plat_arm_get_mmap(void) +{ + return plat_arm_mmap; +} diff --git a/plat/arm/common/arm_bl1_fwu.c b/plat/arm/common/arm_bl1_fwu.c index 9a0d93ad..2a18d341 100644 --- a/plat/arm/common/arm_bl1_fwu.c +++ b/plat/arm/common/arm_bl1_fwu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,11 +33,12 @@ #include <debug.h> #include <errno.h> #include <plat_arm.h> +#include <platform_def.h> #include <tbbr_img_desc.h> /* Struct to keep track of usable memory */ -typedef struct bl1_mem_info{ +typedef struct bl1_mem_info { uintptr_t mem_base; unsigned int mem_size; } bl1_mem_info_t; @@ -58,8 +59,8 @@ bl1_mem_info_t fwu_addr_map_non_secure[] = { .mem_size = ARM_NS_DRAM1_SIZE }, { - .mem_base = V2M_FLASH0_BASE, - .mem_size = V2M_FLASH0_SIZE + .mem_base = PLAT_ARM_NVM_BASE, + .mem_size = PLAT_ARM_NVM_SIZE }, { .mem_size = 0 @@ -79,7 +80,7 @@ int bl1_plat_mem_check(uintptr_t mem_base, /* * Check the given image source and size. */ - if (GET_SEC_STATE(flags) == SECURE) + if (GET_SECURITY_STATE(flags) == SECURE) mmap = fwu_addr_map_secure; else mmap = fwu_addr_map_non_secure; diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c index d0a4c0b2..951f48a5 100644 --- a/plat/arm/common/arm_bl1_setup.c +++ b/plat/arm/common/arm_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,7 +31,6 @@ #include <arch.h> #include <arm_def.h> #include <bl_common.h> -#include <cci.h> #include <console.h> #include <platform_def.h> #include <plat_arm.h> @@ -101,14 +100,14 @@ void bl1_early_platform_setup(void) arm_bl1_early_platform_setup(); /* - * Initialize CCI for this cluster during cold boot. + * Initialize Interconnect for this cluster during cold boot. * No need for locks as no other CPU is active. */ - arm_cci_init(); + plat_arm_interconnect_init(); /* - * Enable CCI coherency for the primary CPU's cluster. + * Enable Interconnect coherency for the primary CPU's cluster. */ - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + plat_arm_interconnect_enter_coherency(); } /****************************************************************************** diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index 6c58ff1d..5cc8bfb1 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,7 +33,6 @@ #include <arm_def.h> #include <assert.h> #include <bl_common.h> -#include <cci.h> #include <console.h> #include <debug.h> #include <mmio.h> @@ -178,20 +177,20 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2, arm_bl31_early_platform_setup(from_bl2, plat_params_from_bl2); /* - * Initialize CCI for this cluster during cold boot. + * Initialize Interconnect for this cluster during cold boot. * No need for locks as no other CPU is active. */ - arm_cci_init(); + plat_arm_interconnect_init(); /* - * Enable CCI coherency for the primary CPU's cluster. + * Enable Interconnect coherency for the primary CPU's cluster. * Earlier bootloader stages might already do this (e.g. Trusted * Firmware's BL1 does it) but we can't assume so. There is no harm in * executing this code twice anyway. * Platform specific PSCI code will enable coherency for other * clusters. */ - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + plat_arm_interconnect_enter_coherency(); } /******************************************************************************* diff --git a/plat/arm/common/arm_cci.c b/plat/arm/common/arm_cci.c new file mode 100644 index 00000000..41054c24 --- /dev/null +++ b/plat/arm/common/arm_cci.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arch.h> +#include <cci.h> +#include <plat_arm.h> +#include <platform_def.h> + +static const int cci_map[] = { + PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX +}; + +/****************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way ARM CCI driver is initialised and used. + *****************************************************************************/ +#pragma weak plat_arm_interconnect_init +#pragma weak plat_arm_interconnect_enter_coherency +#pragma weak plat_arm_interconnect_exit_coherency + + +/****************************************************************************** + * Helper function to initialize ARM CCI driver. + *****************************************************************************/ +void plat_arm_interconnect_init(void) +{ + cci_init(PLAT_ARM_CCI_BASE, cci_map, ARRAY_SIZE(cci_map)); +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ + cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ + cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c new file mode 100644 index 00000000..5cb443aa --- /dev/null +++ b/plat/arm/common/arm_ccn.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <arch.h> +#include <ccn.h> +#include <plat_arm.h> +#include <platform_def.h> + +static const unsigned char master_to_rn_id_map[] = { + PLAT_ARM_CLUSTER_TO_CCN_ID_MAP +}; + +static const ccn_desc_t arm_ccn_desc = { + .periphbase = PLAT_ARM_CCN_BASE, + .num_masters = ARRAY_SIZE(master_to_rn_id_map), + .master_to_rn_id_map = master_to_rn_id_map +}; + +/****************************************************************************** + * The following functions are defined as weak to allow a platform to override + * the way ARM CCN driver is initialised and used. + *****************************************************************************/ +#pragma weak plat_arm_interconnect_init +#pragma weak plat_arm_interconnect_enter_coherency +#pragma weak plat_arm_interconnect_exit_coherency + + +/****************************************************************************** + * Helper function to initialize ARM CCN driver. + *****************************************************************************/ +void plat_arm_interconnect_init(void) +{ + ccn_init(&arm_ccn_desc); +} + +/****************************************************************************** + * Helper function to place current master into coherency + *****************************************************************************/ +void plat_arm_interconnect_enter_coherency(void) +{ + ccn_enter_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} + +/****************************************************************************** + * Helper function to remove current master from coherency + *****************************************************************************/ +void plat_arm_interconnect_exit_coherency(void) +{ + ccn_exit_snoop_dvm_domain(1 << MPIDR_AFFLVL1_VAL(read_mpidr_el1())); +} diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 32027355..425e0d36 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -87,9 +87,7 @@ PLAT_BL_COMMON_SOURCES += lib/aarch64/xlat_tables.c \ plat/arm/common/aarch64/arm_helpers.S \ plat/common/aarch64/plat_common.c -BL1_SOURCES += drivers/arm/cci/cci.c \ - drivers/arm/ccn/ccn.c \ - drivers/arm/sp805/sp805.c \ +BL1_SOURCES += drivers/arm/sp805/sp805.c \ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ @@ -102,26 +100,18 @@ ifdef EL3_PAYLOAD_BASE BL1_SOURCES += plat/arm/common/arm_pm.c endif -BL2_SOURCES += drivers/arm/tzc400/tzc400.c \ - drivers/io/io_fip.c \ +BL2_SOURCES += drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ plat/arm/common/arm_bl2_setup.c \ plat/arm/common/arm_io_storage.c \ - plat/arm/common/arm_security.c \ plat/common/aarch64/platform_up_stack.S -BL2U_SOURCES += drivers/arm/tzc400/tzc400.c \ - plat/arm/common/arm_bl2u_setup.c \ - plat/arm/common/arm_security.c \ +BL2U_SOURCES += plat/arm/common/arm_bl2u_setup.c \ plat/common/aarch64/platform_up_stack.S -BL31_SOURCES += drivers/arm/cci/cci.c \ - drivers/arm/ccn/ccn.c \ - drivers/arm/tzc400/tzc400.c \ - plat/arm/common/arm_bl31_setup.c \ +BL31_SOURCES += plat/arm/common/arm_bl31_setup.c \ plat/arm/common/arm_pm.c \ - plat/arm/common/arm_security.c \ plat/arm/common/arm_topology.c \ plat/common/aarch64/platform_mp_stack.S \ plat/common/aarch64/plat_psci_common.c @@ -139,8 +129,8 @@ ifneq (${TRUSTED_BOARD_BOOT},0) PLAT_INCLUDES += -Iinclude/bl1/tbbr - BL1_SOURCES += ${AUTH_SOURCES} \ - bl1/tbbr/tbbr_img_desc.c \ + BL1_SOURCES += ${AUTH_SOURCES} \ + bl1/tbbr/tbbr_img_desc.c \ plat/arm/common/arm_bl1_fwu.c BL2_SOURCES += ${AUTH_SOURCES} diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c index 2ddc5833..1e756a9e 100644 --- a/plat/arm/common/arm_pm.c +++ b/plat/arm/common/arm_pm.c @@ -192,11 +192,6 @@ void arm_program_trusted_mailbox(uintptr_t address) assert((PLAT_ARM_TRUSTED_MAILBOX_BASE >= ARM_SHARED_RAM_BASE) && ((PLAT_ARM_TRUSTED_MAILBOX_BASE + sizeof(*mailbox)) <= \ (ARM_SHARED_RAM_BASE + ARM_SHARED_RAM_SIZE))); - - /* Flush data cache if the mail box shared RAM is cached */ -#if PLAT_ARM_SHARED_RAM_CACHED - flush_dcache_range((uintptr_t) mailbox, sizeof(*mailbox)); -#endif } /******************************************************************************* diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c index cb0bb9c9..4430b139 100644 --- a/plat/arm/common/arm_topology.c +++ b/plat/arm/common/arm_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -29,26 +29,9 @@ */ #include <arch.h> -#include <psci.h> #include <plat_arm.h> #include <platform_def.h> -#define get_arm_cluster_core_count(mpidr)\ - (((mpidr) & 0x100) ? PLAT_ARM_CLUSTER1_CORE_COUNT :\ - PLAT_ARM_CLUSTER0_CORE_COUNT) - -/* The power domain tree descriptor which need to be exported by ARM platforms */ -extern const unsigned char arm_power_domain_tree_desc[]; - - -/******************************************************************************* - * This function returns the ARM default topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - return arm_power_domain_tree_desc; -} - /******************************************************************************* * This function validates an MPIDR by checking whether it falls within the * acceptable bounds. An error code (-1) is returned if an incorrect mpidr @@ -66,12 +49,12 @@ int arm_check_mpidr(u_register_t mpidr) cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; - if (cluster_id >= ARM_CLUSTER_COUNT) + if (cluster_id >= PLAT_ARM_CLUSTER_COUNT) return -1; /* Validate cpu_id by checking whether it represents a CPU in one of the two clusters present on the platform. */ - if (cpu_id >= get_arm_cluster_core_count(mpidr)) + if (cpu_id >= plat_arm_get_cluster_core_count(mpidr)) return -1; return 0; diff --git a/plat/arm/common/arm_security.c b/plat/arm/common/arm_tzc400.c index 8b46aaed..8b46aaed 100644 --- a/plat/arm/common/arm_security.c +++ b/plat/arm/common/arm_tzc400.c diff --git a/plat/arm/css/common/aarch64/css_helpers.S b/plat/arm/css/common/aarch64/css_helpers.S index 27476186..0763a3ec 100644 --- a/plat/arm/css/common/aarch64/css_helpers.S +++ b/plat/arm/css/common/aarch64/css_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -117,7 +117,8 @@ func plat_is_my_cpu_primary bl plat_my_core_pos ldr x1, =SCP_BOOT_CFG_ADDR ldr x1, [x1] - ubfx x1, x1, #PRIMARY_CPU_SHIFT, #PRIMARY_CPU_BIT_WIDTH + ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \ + #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH cmp x0, x1 cset w0, eq ret x9 diff --git a/plat/arm/css/common/css_common.mk b/plat/arm/css/common/css_common.mk index 6a8773dd..65e125ea 100644 --- a/plat/arm/css/common/css_common.mk +++ b/plat/arm/css/common/css_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -28,6 +28,10 @@ # POSSIBILITY OF SUCH DAMAGE. # + +# By default, SCP images are needed by CSS platforms. +CSS_LOAD_SCP_IMAGES ?= 1 + PLAT_INCLUDES += -Iinclude/plat/arm/css/common \ -Iinclude/plat/arm/css/common/aarch64 @@ -38,12 +42,10 @@ BL1_SOURCES += plat/arm/css/common/css_bl1_setup.c BL2_SOURCES += plat/arm/css/common/css_bl2_setup.c \ plat/arm/css/common/css_mhu.c \ - plat/arm/css/common/css_scp_bootloader.c \ plat/arm/css/common/css_scpi.c BL2U_SOURCES += plat/arm/css/common/css_bl2u_setup.c \ plat/arm/css/common/css_mhu.c \ - plat/arm/css/common/css_scp_bootloader.c \ plat/arm/css/common/css_scpi.c BL31_SOURCES += plat/arm/css/common/css_mhu.c \ @@ -51,17 +53,25 @@ BL31_SOURCES += plat/arm/css/common/css_mhu.c \ plat/arm/css/common/css_scpi.c \ plat/arm/css/common/css_topology.c -ifneq (${TRUSTED_BOARD_BOOT},0) -$(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg)) -endif ifneq (${RESET_TO_BL31},0) $(error "Using BL31 as the reset vector is not supported on CSS platforms. \ Please set RESET_TO_BL31 to 0.") endif -# Subsystems require a SCP_BL2 image -$(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw)) +# Process CSS_LOAD_SCP_IMAGES flag +$(eval $(call assert_boolean,CSS_LOAD_SCP_IMAGES)) +$(eval $(call add_define,CSS_LOAD_SCP_IMAGES)) + +ifeq (${CSS_LOAD_SCP_IMAGES},1) + $(eval $(call FIP_ADD_IMG,SCP_BL2,--scp-fw)) + ifneq (${TRUSTED_BOARD_BOOT},0) + $(eval $(call FWU_FIP_ADD_IMG,SCP_BL2U,--scp-fwu-cfg)) + endif + + BL2U_SOURCES += plat/arm/css/common/css_scp_bootloader.c + BL2_SOURCES += plat/arm/css/common/css_scp_bootloader.c +endif # Enable option to detect whether the SCP ROM firmware in use predates version # 1.7.0 and therefore, is incompatible. diff --git a/plat/arm/css/common/css_mhu.c b/plat/arm/css/common/css_mhu.c index b1714e22..265d6c25 100644 --- a/plat/arm/css/common/css_mhu.c +++ b/plat/arm/css/common/css_mhu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -33,6 +33,7 @@ #include <bakery_lock.h> #include <css_def.h> #include <mmio.h> +#include <platform_def.h> #include <plat_arm.h> #include "css_mhu.h" @@ -66,24 +67,26 @@ void mhu_secure_message_start(unsigned int slot_id) arm_lock_get(); /* Make sure any previous command has finished */ - while (mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) & (1 << slot_id)) + while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id)) ; } void mhu_secure_message_send(unsigned int slot_id) { assert(slot_id <= MHU_MAX_SLOT_ID); - assert(!(mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) & (1 << slot_id))); + assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) & + (1 << slot_id))); /* Send command to SCP */ - mmio_write_32(MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); + mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id); } uint32_t mhu_secure_message_wait(void) { /* Wait for response from SCP */ uint32_t response; - while (!(response = mmio_read_32(MHU_BASE + SCP_INTR_S_STAT))) + while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT))) ; return response; @@ -97,7 +100,7 @@ void mhu_secure_message_end(unsigned int slot_id) * Clear any response we got by writing one in the relevant slot bit to * the CLEAR register */ - mmio_write_32(MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); + mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id); arm_lock_release(); } @@ -111,7 +114,7 @@ void mhu_secure_init(void) * as a stale or garbage value would make us think it's a message we've * already sent. */ - assert(mmio_read_32(MHU_BASE + CPU_INTR_S_STAT) == 0); + assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0); } void plat_arm_pwrc_setup(void) diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index 6d6646e0..b6f94ac2 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -31,7 +31,6 @@ #include <arch_helpers.h> #include <assert.h> #include <cassert.h> -#include <cci.h> #include <css_pm.h> #include <debug.h> #include <errno.h> @@ -108,7 +107,7 @@ static void css_pwr_domain_on_finisher_common( * if this cluster was off. */ if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) - cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1())); + plat_arm_interconnect_enter_coherency(); } /******************************************************************************* @@ -153,7 +152,7 @@ static void css_power_down_common(const psci_power_state_t *target_state) /* Cluster is to be turned off, so disable coherency */ if (CSS_CLUSTER_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF) { - cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr())); + plat_arm_interconnect_exit_coherency(); cluster_state = scpi_power_off; } diff --git a/plat/arm/css/common/css_scp_bootloader.c b/plat/arm/css/common/css_scp_bootloader.c index c01f42fb..d3f671e2 100644 --- a/plat/arm/css/common/css_scp_bootloader.c +++ b/plat/arm/css/common/css_scp_bootloader.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -60,7 +60,7 @@ typedef struct { * Unlike the SCPI protocol, the boot protocol uses the same memory region * for both AP -> SCP and SCP -> AP transfers; define the address of this... */ -#define BOM_SHARED_MEM SCP_COM_SHARED_MEM_BASE +#define BOM_SHARED_MEM PLAT_CSS_SCP_COM_SHARED_MEM_BASE #define BOM_CMD_HEADER ((bom_cmd_t *) BOM_SHARED_MEM) #define BOM_CMD_PAYLOAD ((void *) (BOM_SHARED_MEM + sizeof(bom_cmd_t))) @@ -77,10 +77,10 @@ static void scp_boot_message_start(void) static void scp_boot_message_send(size_t payload_size) { - /* Make sure payload can be seen by SCP */ - if (MHU_PAYLOAD_CACHED) - flush_dcache_range(BOM_SHARED_MEM, - sizeof(bom_cmd_t) + payload_size); + /* Ensure that any write to the BOM payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data */ + dmbst(); /* Send command to SCP */ mhu_secure_message_send(BOM_MHU_SLOT_ID); @@ -99,9 +99,10 @@ static uint32_t scp_boot_message_wait(size_t size) panic(); } - /* Make sure we see the reply from the SCP and not any stale data */ - if (MHU_PAYLOAD_CACHED) - inv_dcache_range(BOM_SHARED_MEM, size); + /* Ensure that any read to the BOM payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data */ + dmbld(); return *(uint32_t *) BOM_SHARED_MEM; } diff --git a/plat/arm/css/common/css_scpi.c b/plat/arm/css/common/css_scpi.c index 0a4eafe0..02d573c9 100644 --- a/plat/arm/css/common/css_scpi.c +++ b/plat/arm/css/common/css_scpi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,8 +37,9 @@ #include "css_mhu.h" #include "css_scpi.h" -#define SCPI_SHARED_MEM_SCP_TO_AP SCP_COM_SHARED_MEM_BASE -#define SCPI_SHARED_MEM_AP_TO_SCP (SCP_COM_SHARED_MEM_BASE + 0x100) +#define SCPI_SHARED_MEM_SCP_TO_AP PLAT_CSS_SCP_COM_SHARED_MEM_BASE +#define SCPI_SHARED_MEM_AP_TO_SCP (PLAT_CSS_SCP_COM_SHARED_MEM_BASE \ + + 0x100) #define SCPI_CMD_HEADER_AP_TO_SCP \ ((scpi_cmd_t *) SCPI_SHARED_MEM_AP_TO_SCP) @@ -55,10 +56,10 @@ static void scpi_secure_message_start(void) static void scpi_secure_message_send(size_t payload_size) { - /* Make sure payload can be seen by SCP */ - if (MHU_PAYLOAD_CACHED) - flush_dcache_range(SCPI_SHARED_MEM_AP_TO_SCP, - sizeof(scpi_cmd_t) + payload_size); + /* Ensure that any write to the SCPI payload area is seen by SCP before + * we write to the MHU register. If these 2 writes were reordered by + * the CPU then SCP would read stale payload data */ + dmbst(); mhu_secure_message_send(SCPI_MHU_SLOT_ID); } @@ -78,9 +79,10 @@ static void scpi_secure_message_receive(scpi_cmd_t *cmd) panic(); } - /* Make sure we don't read stale data */ - if (MHU_PAYLOAD_CACHED) - inv_dcache_range(SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); + /* Ensure that any read to the SCPI payload area is done after reading + * the MHU register. If these 2 reads were reordered then the CPU would + * read invalid payload data */ + dmbld(); memcpy(cmd, (void *) SCPI_SHARED_MEM_SCP_TO_AP, sizeof(*cmd)); } diff --git a/plat/arm/css/common/css_scpi.h b/plat/arm/css/common/css_scpi.h index 379a8219..4a601f3e 100644 --- a/plat/arm/css/common/css_scpi.h +++ b/plat/arm/css/common/css_scpi.h @@ -45,7 +45,7 @@ typedef struct { uint32_t set : 1; /* Sender ID to match a reply. The value is sender specific. */ uint32_t sender : 8; - /* Size of the payload in bytes (0 – 511) */ + /* Size of the payload in bytes (0 - 511) */ uint32_t size : 9; uint32_t reserved : 7; /* diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c index 03f81e61..d5f0275a 100644 --- a/plat/arm/css/common/css_topology.c +++ b/plat/arm/css/common/css_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -30,33 +30,6 @@ #include <plat_arm.h> -/* - * On ARM CSS platforms, by default, the system power level is treated as the - * highest. The first entry in the power domain descriptor specifies the - * number of system power domains i.e. 1. - */ -#define CSS_PWR_DOMAINS_AT_MAX_PWR_LVL ARM_SYSTEM_COUNT - -/* - * The CSS power domain tree descriptor for dual cluster CSS platforms. - * The cluster power domains are arranged so that when the PSCI generic - * code creates the power domain tree, the indices of the CPU power - * domain nodes it allocates match the linear indices returned by - * plat_core_pos_by_mpidr() i.e. CLUSTER1 CPUs are allocated indices - * from 0 to 3 and the higher indices for CLUSTER0 CPUs. - */ -const unsigned char arm_power_domain_tree_desc[] = { - /* No of root nodes */ - CSS_PWR_DOMAINS_AT_MAX_PWR_LVL, - /* No of children for the root node */ - ARM_CLUSTER_COUNT, - /* No of children for the first cluster node */ - PLAT_ARM_CLUSTER1_CORE_COUNT, - /* No of children for the second cluster node */ - PLAT_ARM_CLUSTER0_CORE_COUNT -}; - - /****************************************************************************** * This function implements a part of the critical interface between the psci * generic layer and the platform that allows the former to query the platform diff --git a/plat/mediatek/mt8173/drivers/gpio/gpio.c b/plat/mediatek/mt8173/drivers/gpio/gpio.c index 20473b91..f19c9315 100644 --- a/plat/mediatek/mt8173/drivers/gpio/gpio.c +++ b/plat/mediatek/mt8173/drivers/gpio/gpio.c @@ -28,10 +28,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <debug.h> -#include <gpio.h> #include <mmio.h> #include <mt8173_def.h> #include <pmic_wrap_init.h> +#include "gpio.h" enum { MAX_GPIO_REG_BITS = 16, diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c index f28f8edc..be33c911 100644 --- a/plat/mediatek/mt8173/plat_pm.c +++ b/plat/mediatek/mt8173/plat_pm.c @@ -36,7 +36,6 @@ #include <console.h> #include <debug.h> #include <errno.h> -#include <gpio.h> #include <mcucfg.h> #include <mmio.h> #include <mt8173_def.h> @@ -49,6 +48,7 @@ #include <spm_hotplug.h> #include <spm_mcdi.h> #include <spm_suspend.h> +#include "drivers/gpio/gpio.h" struct core_context { unsigned long timer_data[8]; diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c index 465c5fd9..8a2b81c3 100644 --- a/services/std_svc/psci/psci_common.c +++ b/services/std_svc/psci/psci_common.c @@ -393,6 +393,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl, unsigned int start_idx, ncpus; plat_local_state_t target_state, *req_states; + assert(end_pwrlvl <= PLAT_MAX_PWR_LVL); parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node; /* For level 0, the requested state will be equivalent |