diff options
-rw-r--r-- | bl1/aarch64/bl1_exceptions.S | 61 | ||||
-rw-r--r-- | bl31/aarch64/runtime_exceptions.S | 59 | ||||
-rw-r--r-- | bl32/tsp/aarch64/tsp_exceptions.S | 66 | ||||
-rw-r--r-- | common/aarch64/early_exceptions.S | 72 | ||||
-rw-r--r-- | docs/porting-guide.md | 16 | ||||
-rw-r--r-- | docs/user-guide.md | 8 | ||||
-rw-r--r-- | drivers/arm/ccn/ccn.c | 13 | ||||
-rw-r--r-- | drivers/arm/ccn/ccn_private.h | 1 | ||||
-rw-r--r-- | include/bl31/services/psci.h | 2 | ||||
-rw-r--r-- | include/common/asm_macros.S | 29 | ||||
-rw-r--r-- | include/drivers/arm/ccn.h | 8 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_common.c | 11 | ||||
-rw-r--r-- | plat/arm/board/fvp/fvp_def.h | 19 | ||||
-rw-r--r-- | plat/arm/board/fvp/include/plat_macros.S | 2 | ||||
-rw-r--r-- | plat/arm/board/fvp/include/platform_def.h | 4 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 22 | ||||
-rw-r--r-- | plat/arm/common/arm_ccn.c | 3 | ||||
-rw-r--r-- | services/std_svc/psci/psci_entry.S | 3 | ||||
-rw-r--r-- | services/std_svc/psci/psci_off.c | 15 | ||||
-rw-r--r-- | services/std_svc/psci/psci_suspend.c | 9 |
20 files changed, 242 insertions, 181 deletions
diff --git a/bl1/aarch64/bl1_exceptions.S b/bl1/aarch64/bl1_exceptions.S index 9ff6a57b..68f9b7ae 100644 --- a/bl1/aarch64/bl1_exceptions.S +++ b/bl1/aarch64/bl1_exceptions.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: @@ -34,42 +34,37 @@ #include <bl1.h> #include <context.h> +/* ----------------------------------------------------------------------------- + * Very simple stackless exception handlers used by BL1. + * ----------------------------------------------------------------------------- + */ .globl bl1_exceptions - .section .vectors, "ax"; .align 11 +vector_base bl1_exceptions /* ----------------------------------------------------- - * Very simple stackless exception handlers used by BL1. - * ----------------------------------------------------- - */ - .align 7 -bl1_exceptions: - /* ----------------------------------------------------- * Current EL with SP0 : 0x0 - 0x200 * ----------------------------------------------------- */ -SynchronousExceptionSP0: +vector_entry SynchronousExceptionSP0 mov x0, #SYNC_EXCEPTION_SP_EL0 bl plat_report_exception b SynchronousExceptionSP0 check_vector_size SynchronousExceptionSP0 - .align 7 -IrqSP0: +vector_entry IrqSP0 mov x0, #IRQ_SP_EL0 bl plat_report_exception b IrqSP0 check_vector_size IrqSP0 - .align 7 -FiqSP0: +vector_entry FiqSP0 mov x0, #FIQ_SP_EL0 bl plat_report_exception b FiqSP0 check_vector_size FiqSP0 - .align 7 -SErrorSP0: +vector_entry SErrorSP0 mov x0, #SERROR_SP_EL0 bl plat_report_exception b SErrorSP0 @@ -79,29 +74,25 @@ SErrorSP0: * Current EL with SPx: 0x200 - 0x400 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionSPx: +vector_entry SynchronousExceptionSPx mov x0, #SYNC_EXCEPTION_SP_ELX bl plat_report_exception b SynchronousExceptionSPx check_vector_size SynchronousExceptionSPx - .align 7 -IrqSPx: +vector_entry IrqSPx mov x0, #IRQ_SP_ELX bl plat_report_exception b IrqSPx check_vector_size IrqSPx - .align 7 -FiqSPx: +vector_entry FiqSPx mov x0, #FIQ_SP_ELX bl plat_report_exception b FiqSPx check_vector_size FiqSPx - .align 7 -SErrorSPx: +vector_entry SErrorSPx mov x0, #SERROR_SP_ELX bl plat_report_exception b SErrorSPx @@ -111,8 +102,7 @@ SErrorSPx: * Lower EL using AArch64 : 0x400 - 0x600 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionA64: +vector_entry SynchronousExceptionA64 /* Enable the SError interrupt */ msr daifclr, #DAIF_ABT_BIT @@ -127,22 +117,19 @@ SynchronousExceptionA64: b smc_handler64 check_vector_size SynchronousExceptionA64 - .align 7 -IrqA64: +vector_entry IrqA64 mov x0, #IRQ_AARCH64 bl plat_report_exception b IrqA64 check_vector_size IrqA64 - .align 7 -FiqA64: +vector_entry FiqA64 mov x0, #FIQ_AARCH64 bl plat_report_exception b FiqA64 check_vector_size FiqA64 - .align 7 -SErrorA64: +vector_entry SErrorA64 mov x0, #SERROR_AARCH64 bl plat_report_exception b SErrorA64 @@ -152,29 +139,25 @@ SErrorA64: * Lower EL using AArch32 : 0x600 - 0x800 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionA32: +vector_entry SynchronousExceptionA32 mov x0, #SYNC_EXCEPTION_AARCH32 bl plat_report_exception b SynchronousExceptionA32 check_vector_size SynchronousExceptionA32 - .align 7 -IrqA32: +vector_entry IrqA32 mov x0, #IRQ_AARCH32 bl plat_report_exception b IrqA32 check_vector_size IrqA32 - .align 7 -FiqA32: +vector_entry FiqA32 mov x0, #FIQ_AARCH32 bl plat_report_exception b FiqA32 check_vector_size FiqA32 - .align 7 -SErrorA32: +vector_entry SErrorA32 mov x0, #SERROR_AARCH32 bl plat_report_exception b SErrorA32 diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S index dc11e0a7..799062ef 100644 --- a/bl31/aarch64/runtime_exceptions.S +++ b/bl31/aarch64/runtime_exceptions.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: @@ -161,14 +161,14 @@ interrupt_exit_\label: str x18, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_SP_EL0] .endm - .section .vectors, "ax"; .align 11 - .align 7 -runtime_exceptions: + +vector_base runtime_exceptions + /* ----------------------------------------------------- * Current EL with _sp_el0 : 0x0 - 0x200 * ----------------------------------------------------- */ -sync_exception_sp_el0: +vector_entry sync_exception_sp_el0 /* ----------------------------------------------------- * We don't expect any synchronous exceptions from EL3 * ----------------------------------------------------- @@ -176,23 +176,22 @@ sync_exception_sp_el0: bl report_unhandled_exception check_vector_size sync_exception_sp_el0 - .align 7 /* ----------------------------------------------------- * EL3 code is non-reentrant. Any asynchronous exception * is a serious error. Loop infinitely. * ----------------------------------------------------- */ -irq_sp_el0: +vector_entry irq_sp_el0 bl report_unhandled_interrupt check_vector_size irq_sp_el0 - .align 7 -fiq_sp_el0: + +vector_entry fiq_sp_el0 bl report_unhandled_interrupt check_vector_size fiq_sp_el0 - .align 7 -serror_sp_el0: + +vector_entry serror_sp_el0 bl report_unhandled_exception check_vector_size serror_sp_el0 @@ -200,8 +199,8 @@ serror_sp_el0: * Current EL with SPx: 0x200 - 0x400 * ----------------------------------------------------- */ - .align 7 -sync_exception_sp_elx: + +vector_entry sync_exception_sp_elx /* ----------------------------------------------------- * This exception will trigger if anything went wrong * during a previous exception entry or exit or while @@ -212,18 +211,15 @@ sync_exception_sp_elx: bl report_unhandled_exception check_vector_size sync_exception_sp_elx - .align 7 -irq_sp_elx: +vector_entry irq_sp_elx bl report_unhandled_interrupt check_vector_size irq_sp_elx - .align 7 -fiq_sp_elx: +vector_entry fiq_sp_elx bl report_unhandled_interrupt check_vector_size fiq_sp_elx - .align 7 -serror_sp_elx: +vector_entry serror_sp_elx bl report_unhandled_exception check_vector_size serror_sp_elx @@ -231,8 +227,7 @@ serror_sp_elx: * Lower EL using AArch64 : 0x400 - 0x600 * ----------------------------------------------------- */ - .align 7 -sync_exception_aarch64: +vector_entry sync_exception_aarch64 /* ----------------------------------------------------- * This exception vector will be the entry point for * SMCs and traps that are unhandled at lower ELs most @@ -244,23 +239,20 @@ sync_exception_aarch64: handle_sync_exception check_vector_size sync_exception_aarch64 - .align 7 /* ----------------------------------------------------- * Asynchronous exceptions from lower ELs are not * currently supported. Report their occurrence. * ----------------------------------------------------- */ -irq_aarch64: +vector_entry irq_aarch64 handle_interrupt_exception irq_aarch64 check_vector_size irq_aarch64 - .align 7 -fiq_aarch64: +vector_entry fiq_aarch64 handle_interrupt_exception fiq_aarch64 check_vector_size fiq_aarch64 - .align 7 -serror_aarch64: +vector_entry serror_aarch64 bl report_unhandled_exception check_vector_size serror_aarch64 @@ -268,8 +260,7 @@ serror_aarch64: * Lower EL using AArch32 : 0x600 - 0x800 * ----------------------------------------------------- */ - .align 7 -sync_exception_aarch32: +vector_entry sync_exception_aarch32 /* ----------------------------------------------------- * This exception vector will be the entry point for * SMCs and traps that are unhandled at lower ELs most @@ -281,27 +272,23 @@ sync_exception_aarch32: handle_sync_exception check_vector_size sync_exception_aarch32 - .align 7 /* ----------------------------------------------------- * Asynchronous exceptions from lower ELs are not * currently supported. Report their occurrence. * ----------------------------------------------------- */ -irq_aarch32: +vector_entry irq_aarch32 handle_interrupt_exception irq_aarch32 check_vector_size irq_aarch32 - .align 7 -fiq_aarch32: +vector_entry fiq_aarch32 handle_interrupt_exception fiq_aarch32 check_vector_size fiq_aarch32 - .align 7 -serror_aarch32: +vector_entry serror_aarch32 bl report_unhandled_exception check_vector_size serror_aarch32 - .align 7 /* ----------------------------------------------------- * The following code handles secure monitor calls. diff --git a/bl32/tsp/aarch64/tsp_exceptions.S b/bl32/tsp/aarch64/tsp_exceptions.S index edcfb718..20e40dfb 100644 --- a/bl32/tsp/aarch64/tsp_exceptions.S +++ b/bl32/tsp/aarch64/tsp_exceptions.S @@ -28,10 +28,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include <bl_common.h> #include <arch.h> -#include <tsp.h> #include <asm_macros.S> +#include <bl_common.h> +#include <tsp.h> /* ---------------------------------------------------- @@ -98,110 +98,90 @@ interrupt_exit_\label: * TSP exception handlers. * ----------------------------------------------------- */ - .section .vectors, "ax"; .align 11 - - .align 7 -tsp_exceptions: +vector_base tsp_exceptions /* ----------------------------------------------------- - * Current EL with _sp_el0 : 0x0 - 0x180. No exceptions + * Current EL with _sp_el0 : 0x0 - 0x200. No exceptions * are expected and treated as irrecoverable errors. * ----------------------------------------------------- */ -sync_exception_sp_el0: +vector_entry sync_exception_sp_el0 bl plat_panic_handler check_vector_size sync_exception_sp_el0 - .align 7 - -irq_sp_el0: +vector_entry irq_sp_el0 bl plat_panic_handler check_vector_size irq_sp_el0 - .align 7 -fiq_sp_el0: +vector_entry fiq_sp_el0 bl plat_panic_handler check_vector_size fiq_sp_el0 - .align 7 -serror_sp_el0: +vector_entry serror_sp_el0 bl plat_panic_handler check_vector_size serror_sp_el0 /* ----------------------------------------------------- - * Current EL with SPx: 0x200 - 0x380. Only IRQs/FIQs + * Current EL with SPx: 0x200 - 0x400. Only IRQs/FIQs * are expected and handled * ----------------------------------------------------- */ - .align 7 -sync_exception_sp_elx: +vector_entry sync_exception_sp_elx bl plat_panic_handler check_vector_size sync_exception_sp_elx - .align 7 -irq_sp_elx: +vector_entry irq_sp_elx handle_tsp_interrupt irq_sp_elx check_vector_size irq_sp_elx - .align 7 -fiq_sp_elx: +vector_entry fiq_sp_elx handle_tsp_interrupt fiq_sp_elx check_vector_size fiq_sp_elx - .align 7 -serror_sp_elx: +vector_entry serror_sp_elx bl plat_panic_handler check_vector_size serror_sp_elx /* ----------------------------------------------------- - * Lower EL using AArch64 : 0x400 - 0x580. No exceptions + * Lower EL using AArch64 : 0x400 - 0x600. No exceptions * are handled since TSP does not implement a lower EL * ----------------------------------------------------- */ - .align 7 -sync_exception_aarch64: +vector_entry sync_exception_aarch64 bl plat_panic_handler check_vector_size sync_exception_aarch64 - .align 7 -irq_aarch64: +vector_entry irq_aarch64 bl plat_panic_handler check_vector_size irq_aarch64 - .align 7 -fiq_aarch64: +vector_entry fiq_aarch64 bl plat_panic_handler check_vector_size fiq_aarch64 - .align 7 -serror_aarch64: +vector_entry serror_aarch64 bl plat_panic_handler check_vector_size serror_aarch64 /* ----------------------------------------------------- - * Lower EL using AArch32 : 0x600 - 0x780. No exceptions + * Lower EL using AArch32 : 0x600 - 0x800. No exceptions * handled since the TSP does not implement a lower EL. * ----------------------------------------------------- */ - .align 7 -sync_exception_aarch32: +vector_entry sync_exception_aarch32 bl plat_panic_handler check_vector_size sync_exception_aarch32 - .align 7 -irq_aarch32: +vector_entry irq_aarch32 bl plat_panic_handler check_vector_size irq_aarch32 - .align 7 -fiq_aarch32: +vector_entry fiq_aarch32 bl plat_panic_handler check_vector_size fiq_aarch32 - .align 7 -serror_aarch32: +vector_entry serror_aarch32 bl plat_panic_handler check_vector_size serror_aarch32 - .align 7 diff --git a/common/aarch64/early_exceptions.S b/common/aarch64/early_exceptions.S index 64bfcd0f..0ef59507 100644 --- a/common/aarch64/early_exceptions.S +++ b/common/aarch64/early_exceptions.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: @@ -31,140 +31,122 @@ #include <asm_macros.S> #include <bl_common.h> +/* ----------------------------------------------------------------------------- + * Very simple stackless exception handlers used by BL2 and BL31 stages. + * BL31 uses them before stacks are setup. BL2 uses them throughout. + * ----------------------------------------------------------------------------- + */ .globl early_exceptions - .section .vectors, "ax"; .align 11 +vector_base early_exceptions /* ----------------------------------------------------- - * Very simple stackless exception handlers used by BL2 - * and BL31 bootloader stages. BL31 uses them before - * stacks are setup. BL2 uses them throughout. - * ----------------------------------------------------- - */ - .align 7 -early_exceptions: - /* ----------------------------------------------------- - * Current EL with SP0 : 0x0 - 0x180 + * Current EL with SP0 : 0x0 - 0x200 * ----------------------------------------------------- */ -SynchronousExceptionSP0: +vector_entry SynchronousExceptionSP0 mov x0, #SYNC_EXCEPTION_SP_EL0 bl plat_report_exception b SynchronousExceptionSP0 check_vector_size SynchronousExceptionSP0 - .align 7 -IrqSP0: +vector_entry IrqSP0 mov x0, #IRQ_SP_EL0 bl plat_report_exception b IrqSP0 check_vector_size IrqSP0 - .align 7 -FiqSP0: +vector_entry FiqSP0 mov x0, #FIQ_SP_EL0 bl plat_report_exception b FiqSP0 check_vector_size FiqSP0 - .align 7 -SErrorSP0: +vector_entry SErrorSP0 mov x0, #SERROR_SP_EL0 bl plat_report_exception b SErrorSP0 check_vector_size SErrorSP0 /* ----------------------------------------------------- - * Current EL with SPx: 0x200 - 0x380 + * Current EL with SPx: 0x200 - 0x400 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionSPx: +vector_entry SynchronousExceptionSPx mov x0, #SYNC_EXCEPTION_SP_ELX bl plat_report_exception b SynchronousExceptionSPx check_vector_size SynchronousExceptionSPx - .align 7 -IrqSPx: +vector_entry IrqSPx mov x0, #IRQ_SP_ELX bl plat_report_exception b IrqSPx check_vector_size IrqSPx - .align 7 -FiqSPx: +vector_entry FiqSPx mov x0, #FIQ_SP_ELX bl plat_report_exception b FiqSPx check_vector_size FiqSPx - .align 7 -SErrorSPx: +vector_entry SErrorSPx mov x0, #SERROR_SP_ELX bl plat_report_exception b SErrorSPx check_vector_size SErrorSPx /* ----------------------------------------------------- - * Lower EL using AArch64 : 0x400 - 0x580 + * Lower EL using AArch64 : 0x400 - 0x600 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionA64: +vector_entry SynchronousExceptionA64 mov x0, #SYNC_EXCEPTION_AARCH64 bl plat_report_exception b SynchronousExceptionA64 check_vector_size SynchronousExceptionA64 - .align 7 -IrqA64: +vector_entry IrqA64 mov x0, #IRQ_AARCH64 bl plat_report_exception b IrqA64 check_vector_size IrqA64 - .align 7 -FiqA64: +vector_entry FiqA64 mov x0, #FIQ_AARCH64 bl plat_report_exception b FiqA64 check_vector_size FiqA64 - .align 7 -SErrorA64: +vector_entry SErrorA64 mov x0, #SERROR_AARCH64 bl plat_report_exception b SErrorA64 check_vector_size SErrorA64 /* ----------------------------------------------------- - * Lower EL using AArch32 : 0x0 - 0x180 + * Lower EL using AArch32 : 0x600 - 0x800 * ----------------------------------------------------- */ - .align 7 -SynchronousExceptionA32: +vector_entry SynchronousExceptionA32 mov x0, #SYNC_EXCEPTION_AARCH32 bl plat_report_exception b SynchronousExceptionA32 check_vector_size SynchronousExceptionA32 - .align 7 -IrqA32: +vector_entry IrqA32 mov x0, #IRQ_AARCH32 bl plat_report_exception b IrqA32 check_vector_size IrqA32 - .align 7 -FiqA32: +vector_entry FiqA32 mov x0, #FIQ_AARCH32 bl plat_report_exception b FiqA32 check_vector_size FiqA32 - .align 7 -SErrorA32: +vector_entry SErrorA32 mov x0, #SERROR_AARCH32 bl plat_report_exception b SErrorA32 diff --git a/docs/porting-guide.md b/docs/porting-guide.md index 0cd36134..8947defb 100644 --- a/docs/porting-guide.md +++ b/docs/porting-guide.md @@ -1715,6 +1715,22 @@ latter case, the power domain is expected to save enough state so that it can resume execution by restoring this state when its powered on (see `pwr_domain_suspend_finish()`). +#### plat_psci_ops.pwr_domain_pwr_down_wfi() + +This is an optional function and, if implemented, is expected to perform +platform specific actions including the `wfi` invocation which allows the +CPU to powerdown. Since this function is invoked outside the PSCI locks, +the actions performed in this hook must be local to the CPU or the platform +must ensure that races between multiple CPUs cannot occur. + +The `target_state` has a similar meaning as described in the `pwr_domain_off()` +operation and it encodes the platform coordinated target local power states for +the CPU power domain and its parent power domain levels. This function must +not return back to the caller. + +If this function is not implemented by the platform, PSCI generic +implementation invokes `psci_power_down_wfi()` for power down. + #### plat_psci_ops.pwr_domain_on_finish() This function is called by the PSCI implementation after the calling CPU is diff --git a/docs/user-guide.md b/docs/user-guide.md index cd9c8c33..ce0390d8 100644 --- a/docs/user-guide.md +++ b/docs/user-guide.md @@ -496,6 +496,14 @@ map is explained in the [Firmware Design]. for functions that wait for an arbitrary time length (udelay and mdelay). The default value is 0. +* `FVP_INTERCONNECT_DRIVER`: Selects the interconnect driver to be built. The + default interconnect driver depends on the value of `FVP_CLUSTER_COUNT` as + explained in the options below: + - `FVP_CCI` : The CCI driver is selected. This is the default + if 0 < `FVP_CLUSTER_COUNT` <= 2. + - `FVP_CCN` : The CCN driver is selected. This is the default + if `FVP_CLUSTER_COUNT` > 2. + ### Debugging options To compile a debug version and make the build more verbose use diff --git a/drivers/arm/ccn/ccn.c b/drivers/arm/ccn/ccn.c index 28d27098..060acdd2 100644 --- a/drivers/arm/ccn/ccn.c +++ b/drivers/arm/ccn/ccn.c @@ -254,6 +254,7 @@ static unsigned long long ccn_master_to_rn_id_map(unsigned long long master_map) assert(ccn_plat_desc); FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, master_map) { + assert(iface_id < ccn_plat_desc->num_masters); /* Convert the master ID into the node ID */ node_id = ccn_plat_desc->master_to_rn_id_map[iface_id]; @@ -501,3 +502,15 @@ void ccn_program_sys_addrmap(unsigned int sn0_id, } } + +/******************************************************************************* + * This function returns the part0 id from the peripheralID 0 register + * in CCN. This id can be used to distinguish the CCN variant present in the + * system. + ******************************************************************************/ +int ccn_get_part0_id(uintptr_t periphbase) +{ + assert(periphbase); + return (int)(mmio_read_64(periphbase + + MN_PERIPH_ID_0_1_OFFSET) & 0xFF); +} diff --git a/drivers/arm/ccn/ccn_private.h b/drivers/arm/ccn/ccn_private.h index 8b154725..fffa2ca9 100644 --- a/drivers/arm/ccn/ccn_private.h +++ b/drivers/arm/ccn/ccn_private.h @@ -149,6 +149,7 @@ typedef enum rn_types { #define MN_DDC_STAT_OFFSET DOMAIN_CTRL_STAT_OFFSET #define MN_DDC_SET_OFFSET DOMAIN_CTRL_SET_OFFSET #define MN_DDC_CLR_OFFSET DOMAIN_CTRL_CLR_OFFSET +#define MN_PERIPH_ID_0_1_OFFSET 0xFE0 #define MN_ID_OFFSET REGION_ID_OFFSET /* HNF System Address Map register bit masks and shifts */ diff --git a/include/bl31/services/psci.h b/include/bl31/services/psci.h index acf07869..95e77809 100644 --- a/include/bl31/services/psci.h +++ b/include/bl31/services/psci.h @@ -265,6 +265,8 @@ typedef struct plat_psci_ops { void (*pwr_domain_on_finish)(const psci_power_state_t *target_state); void (*pwr_domain_suspend_finish)( const psci_power_state_t *target_state); + void (*pwr_domain_pwr_down_wfi)( + const psci_power_state_t *target_state) __dead2; void (*system_off)(void) __dead2; void (*system_reset)(void) __dead2; int (*validate_power_state)(unsigned int power_state, diff --git a/include/common/asm_macros.S b/include/common/asm_macros.S index a331c051..d4bd11ee 100644 --- a/include/common/asm_macros.S +++ b/include/common/asm_macros.S @@ -66,11 +66,36 @@ b.ne $label .endm + /* + * Declare the exception vector table, enforcing it is aligned on a + * 2KB boundary, as required by the ARMv8 architecture. + * Use zero bytes as the fill value to be stored in the padding bytes + * so that it inserts illegal AArch64 instructions. This increases + * security, robustness and potentially facilitates debugging. + */ + .macro vector_base label + .section .vectors, "ax" + .align 11, 0 + \label: + .endm + + /* + * Create an entry in the exception vector table, enforcing it is + * aligned on a 128-byte boundary, as required by the ARMv8 architecture. + * Use zero bytes as the fill value to be stored in the padding bytes + * so that it inserts illegal AArch64 instructions. This increases + * security, robustness and potentially facilitates debugging. + */ + .macro vector_entry label + .section .vectors, "ax" + .align 7, 0 + \label: + .endm /* - * This macro verifies that the a given vector doesn't exceed the + * This macro verifies that the given vector doesn't exceed the * architectural limit of 32 instructions. This is meant to be placed - * immedately after the last instruction in the vector. It takes the + * immediately after the last instruction in the vector. It takes the * vector entry as the parameter */ .macro check_vector_size since diff --git a/include/drivers/arm/ccn.h b/include/drivers/arm/ccn.h index 23615966..85c45c68 100644 --- a/include/drivers/arm/ccn.h +++ b/include/drivers/arm/ccn.h @@ -51,6 +51,13 @@ #define CCN_L3_RUN_MODE_HAM 0x2 /* HNF_PM_HALF */ #define CCN_L3_RUN_MODE_FAM 0x3 /* HNF_PM_FULL */ +/* part 0 IDs for various CCN variants */ +#define CCN_502_PART0_ID 0x30 +#define CCN_504_PART0_ID 0x26 +#define CCN_505_PART0_ID 0x27 +#define CCN_508_PART0_ID 0x28 +#define CCN_512_PART0_ID 0x29 + /* * The following macro takes the value returned from a read of a HN-F P-state * status register and returns the retention state value. @@ -107,6 +114,7 @@ void ccn_program_sys_addrmap(unsigned int sn0_id, unsigned int top_addr_bit1, unsigned char three_sn_en); unsigned int ccn_get_l3_run_mode(void); +int ccn_get_part0_id(uintptr_t periphbase); #endif /* __ASSEMBLY__ */ #endif /* __CCN_H__ */ diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 78782d43..eb67dab2 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -30,6 +30,7 @@ #include <arm_config.h> #include <arm_def.h> +#include <ccn.h> #include <debug.h> #include <gicv2.h> #include <mmio.h> @@ -213,8 +214,16 @@ void fvp_config_setup(void) void fvp_interconnect_init(void) { - if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) + if (arm_config.flags & ARM_CONFIG_HAS_INTERCONNECT) { +#if FVP_INTERCONNECT_DRIVER == FVP_CCN + if (ccn_get_part0_id(PLAT_ARM_CCN_BASE) != CCN_502_PART0_ID) { + ERROR("Unrecognized CCN variant detected. Only CCN-502" + " is supported"); + panic(); + } +#endif plat_arm_interconnect_init(); + } } void fvp_interconnect_enable(void) diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index b0f07ef5..40d20fce 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -40,6 +40,10 @@ #define FVP_PRIMARY_CPU 0x0 +/* Defines for the Interconnect build selection */ +#define FVP_CCI 1 +#define FVP_CCN 2 + /******************************************************************************* * FVP memory map related constants ******************************************************************************/ @@ -57,16 +61,23 @@ #define DEVICE0_BASE 0x20000000 #define DEVICE0_SIZE 0x0c200000 +/* + * In case of FVP models with CCN, the CCN register space overlaps into + * the NSRAM area. + */ +#if FVP_INTERCONNECT_DRIVER == FVP_CCN +#define DEVICE1_BASE 0x2e000000 +#define DEVICE1_SIZE 0x1A00000 +#else #define DEVICE1_BASE 0x2f000000 #define DEVICE1_SIZE 0x200000 - +#define NSRAM_BASE 0x2e000000 +#define NSRAM_SIZE 0x10000 +#endif /* Devices in the second GB */ #define DEVICE2_BASE 0x7fe00000 #define DEVICE2_SIZE 0x00200000 -#define NSRAM_BASE 0x2e000000 -#define NSRAM_SIZE 0x10000 - #define PCIE_EXP_BASE 0x40000000 #define TZRNG_BASE 0x7fe60000 diff --git a/plat/arm/board/fvp/include/plat_macros.S b/plat/arm/board/fvp/include/plat_macros.S index e43c7acf..657a39b9 100644 --- a/plat/arm/board/fvp/include/plat_macros.S +++ b/plat/arm/board/fvp/include/plat_macros.S @@ -64,7 +64,9 @@ use_ve_mmap: mov_imm x16, VE_GICD_BASE print_gic_regs: arm_print_gic_regs +#if FVP_INTERCONNECT_DRIVER == FVP_CCI print_cci_regs +#endif .endm #endif /* __PLAT_MACROS_S__ */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index ca8e35e3..1e906d82 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -90,6 +90,10 @@ #define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 3 #define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 4 +/* CCN related constants. Only CCN 502 is currently supported */ +#define PLAT_ARM_CCN_BASE 0x2e000000 +#define PLAT_ARM_CLUSTER_TO_CCN_ID_MAP 1, 5, 7, 11 + /* System timer related constants */ #define PLAT_ARM_NSTIMER_FRAME_ID 1 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index c0fe662e..6456cdea 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -39,11 +39,22 @@ $(eval $(call add_define,FVP_USE_SP804_TIMER)) # 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 +# Define default FVP_CLUSTER_COUNT to 2 and pass it into the build system. +FVP_CLUSTER_COUNT := 2 $(eval $(call add_define,FVP_CLUSTER_COUNT)) + +# Sanity check the cluster count and if FVP_CLUSTER_COUNT <= 2, +# choose the CCI driver , else the CCN driver +ifeq ($(FVP_CLUSTER_COUNT), 0) +$(error "Incorrect cluster count specified for FVP port") +else ifeq ($(FVP_CLUSTER_COUNT),$(filter $(FVP_CLUSTER_COUNT),1 2)) +FVP_INTERCONNECT_DRIVER := FVP_CCI +else +FVP_INTERCONNECT_DRIVER := FVP_CCN endif +$(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) + # 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 \ @@ -67,8 +78,15 @@ else $(error "Incorrect GIC driver chosen on FVP port") endif +ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCI) FVP_INTERCONNECT_SOURCES := drivers/arm/cci/cci.c \ plat/arm/common/arm_cci.c +else ifeq (${FVP_INTERCONNECT_DRIVER}, FVP_CCN) +FVP_INTERCONNECT_SOURCES := drivers/arm/ccn/ccn.c \ + plat/arm/common/arm_ccn.c +else +$(error "Incorrect CCN driver chosen on FVP port") +endif FVP_SECURITY_SOURCES := drivers/arm/tzc/tzc400.c \ plat/arm/board/fvp/fvp_security.c \ diff --git a/plat/arm/common/arm_ccn.c b/plat/arm/common/arm_ccn.c index 5cb443aa..fe10d7b5 100644 --- a/plat/arm/common/arm_ccn.c +++ b/plat/arm/common/arm_ccn.c @@ -43,6 +43,9 @@ static const ccn_desc_t arm_ccn_desc = { .master_to_rn_id_map = master_to_rn_id_map }; +CASSERT(PLAT_ARM_CLUSTER_COUNT == ARRAY_SIZE(master_to_rn_id_map), + assert_invalid_cluster_count_for_ccn_variant); + /****************************************************************************** * The following functions are defined as weak to allow a platform to override * the way ARM CCN driver is initialised and used. diff --git a/services/std_svc/psci/psci_entry.S b/services/std_svc/psci/psci_entry.S index 5f4f91c5..f8c0afa2 100644 --- a/services/std_svc/psci/psci_entry.S +++ b/services/std_svc/psci/psci_entry.S @@ -106,7 +106,6 @@ endfunc psci_entrypoint func psci_power_down_wfi dsb sy // ensure write buffer empty wfi -wfi_spill: - b wfi_spill + bl plat_panic_handler endfunc psci_power_down_wfi diff --git a/services/std_svc/psci/psci_off.c b/services/std_svc/psci/psci_off.c index cef66689..686666d5 100644 --- a/services/std_svc/psci/psci_off.c +++ b/services/std_svc/psci/psci_off.c @@ -138,11 +138,16 @@ exit: dsbish(); inv_cpu_data(psci_svc_cpu_data.aff_info_state); - /* - * Enter a wfi loop which will allow the power controller to - * physically power down this cpu. - */ - psci_power_down_wfi(); + if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) { + /* This function must not return */ + psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info); + } else { + /* + * Enter a wfi loop which will allow the power + * controller to physically power down this cpu. + */ + psci_power_down_wfi(); + } } return rc; diff --git a/services/std_svc/psci/psci_suspend.c b/services/std_svc/psci/psci_suspend.c index 367bb32a..8c6ab6b4 100644 --- a/services/std_svc/psci/psci_suspend.c +++ b/services/std_svc/psci/psci_suspend.c @@ -189,8 +189,13 @@ exit: if (skip_wfi) return; - if (is_power_down_state) - psci_power_down_wfi(); + if (is_power_down_state) { + /* The function calls below must not return */ + if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) + psci_plat_pm_ops->pwr_domain_pwr_down_wfi(state_info); + else + psci_power_down_wfi(); + } /* * We will reach here if only retention/standby states have been |