aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--Makefile73
-rw-r--r--acknowledgements.rst4
-rw-r--r--bl1/aarch32/bl1_exceptions.S2
-rw-r--r--bl1/bl1.mk9
-rw-r--r--bl1/bl1_private.h2
-rw-r--r--bl2/bl2.mk11
-rw-r--r--bl2u/bl2u_main.c1
-rw-r--r--bl31/aarch64/ea_delegate.S263
-rw-r--r--bl31/aarch64/runtime_exceptions.S122
-rw-r--r--bl31/bl31.mk6
-rw-r--r--bl31/bl31_main.c11
-rw-r--r--bl31/ehf.c100
-rw-r--r--bl31/interrupt_mgmt.c42
-rw-r--r--bl32/sp_min/sp_min_main.c2
-rw-r--r--common/backtrace.c256
-rw-r--r--common/runtime_svc.c2
-rw-r--r--common/tf_log.c19
-rw-r--r--docs/cpu-specific-build-macros.rst33
-rw-r--r--docs/marvell/build.txt181
-rw-r--r--docs/marvell/misc/mvebu-a8k-addr-map.txt47
-rw-r--r--docs/marvell/misc/mvebu-amb.txt45
-rw-r--r--docs/marvell/misc/mvebu-ccu.txt23
-rw-r--r--docs/marvell/misc/mvebu-io-win.txt35
-rw-r--r--docs/marvell/misc/mvebu-iob.txt40
-rw-r--r--docs/marvell/porting.txt66
-rw-r--r--docs/plat/rpi3.rst179
-rw-r--r--docs/plat/stm32mp1.rst82
-rw-r--r--docs/porting-guide.rst136
-rw-r--r--docs/psci-lib-integration-guide.rst10
-rw-r--r--docs/psci-pd-tree.rst4
-rw-r--r--docs/user-guide.rst42
-rw-r--r--drivers/arm/cci/cci.c58
-rw-r--r--drivers/arm/gic/common/gic_common.c106
-rw-r--r--drivers/arm/gic/v2/gicv2_helpers.c25
-rw-r--r--drivers/arm/gic/v2/gicv2_main.c143
-rw-r--r--drivers/arm/gic/v2/gicv2_private.h4
-rw-r--r--drivers/arm/gic/v3/gicv3_helpers.c139
-rw-r--r--drivers/arm/gic/v3/gicv3_main.c209
-rw-r--r--drivers/arm/gic/v3/gicv3_private.h76
-rw-r--r--drivers/arm/smmu/smmu_v3.c19
-rw-r--r--drivers/arm/sp805/sp805.c18
-rw-r--r--drivers/auth/mbedtls/mbedtls_common.c15
-rw-r--r--drivers/auth/mbedtls/mbedtls_common.mk88
-rw-r--r--drivers/auth/mbedtls/mbedtls_crypto.mk82
-rw-r--r--drivers/auth/mbedtls/mbedtls_x509.mk6
-rw-r--r--drivers/console/aarch64/multi_console.S151
-rw-r--r--drivers/emmc/emmc.c363
-rw-r--r--drivers/io/io_fip.c1
-rw-r--r--drivers/io/io_memmap.c3
-rw-r--r--drivers/io/io_semihosting.c3
-rw-r--r--drivers/io/io_storage.c4
-rw-r--r--drivers/marvell/amb_adec.c156
-rw-r--r--drivers/marvell/cache_llc.c109
-rw-r--r--drivers/marvell/ccu.c361
-rw-r--r--drivers/marvell/comphy.h473
-rw-r--r--drivers/marvell/comphy/comphy-cp110.h775
-rw-r--r--drivers/marvell/comphy/phy-comphy-cp110.c2319
-rw-r--r--drivers/marvell/comphy/phy-comphy-cp110.h19
-rw-r--r--drivers/marvell/gwin.c227
-rw-r--r--drivers/marvell/i2c/a8k_i2c.c613
-rw-r--r--drivers/marvell/io_win.c267
-rw-r--r--drivers/marvell/iob.c195
-rw-r--r--drivers/marvell/mci.c832
-rw-r--r--drivers/marvell/mochi/ap807_setup.c237
-rw-r--r--drivers/marvell/mochi/apn806_setup.c251
-rw-r--r--drivers/marvell/mochi/cp110_setup.c429
-rw-r--r--drivers/marvell/thermal.c54
-rw-r--r--drivers/mmc/mmc.c111
-rw-r--r--drivers/partition/partition.c3
-rw-r--r--drivers/st/clk/stm32mp1_clk.c1612
-rw-r--r--drivers/st/clk/stm32mp1_clkfunc.c365
-rw-r--r--drivers/st/ddr/stm32mp1_ddr.c895
-rw-r--r--drivers/st/ddr/stm32mp1_ddr_helpers.c20
-rw-r--r--drivers/st/ddr/stm32mp1_ram.c308
-rw-r--r--drivers/st/gpio/stm32_gpio.c86
-rw-r--r--drivers/st/pmic/stm32_i2c.c851
-rw-r--r--drivers/st/pmic/stm32mp1_pmic.c346
-rw-r--r--drivers/st/pmic/stpmu1.c600
-rw-r--r--drivers/st/reset/stm32mp1_reset.c39
-rw-r--r--drivers/st/uart/aarch32/stm32_console.S184
-rw-r--r--drivers/synopsys/emmc/dw_mmc.c78
-rw-r--r--fdts/stm32mp15-ddr.dtsi153
-rw-r--r--fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi121
-rw-r--r--fdts/stm32mp157-pinctrl.dtsi250
-rw-r--r--fdts/stm32mp157c-ed1.dts246
-rw-r--r--fdts/stm32mp157c-ev1.dts25
-rw-r--r--fdts/stm32mp157c.dtsi240
-rw-r--r--fdts/stm32mp157caa-pinctrl.dtsi90
-rw-r--r--include/bl31/ehf.h25
-rw-r--r--include/bl31/interrupt_mgmt.h87
-rw-r--r--include/common/bl_common.h1
-rw-r--r--include/common/debug.h69
-rw-r--r--include/common/ep_info.h4
-rw-r--r--include/common/param_header.h29
-rw-r--r--include/common/romlib.h15
-rw-r--r--include/common/tbbr/tbbr_img_def.h60
-rw-r--r--include/drivers/arm/arm_gic.h3
-rw-r--r--include/drivers/arm/cci.h142
-rw-r--r--include/drivers/arm/gic_common.h70
-rw-r--r--include/drivers/arm/gic_v3.h4
-rw-r--r--include/drivers/arm/gicv2.h111
-rw-r--r--include/drivers/arm/gicv3.h235
-rw-r--r--include/drivers/arm/pl011.h4
-rw-r--r--include/drivers/arm/smmu_v3.h11
-rw-r--r--include/drivers/arm/sp805.h26
-rw-r--r--include/drivers/cadence/cdns_uart.h4
-rw-r--r--include/drivers/console.h8
-rw-r--r--include/drivers/dw_ufs.h4
-rw-r--r--include/drivers/emmc.h165
-rw-r--r--include/drivers/marvell/a8k_i2c.h38
-rw-r--r--include/drivers/marvell/addr_map.h21
-rw-r--r--include/drivers/marvell/amb_adec.h36
-rw-r--r--include/drivers/marvell/aro.h46
-rw-r--r--include/drivers/marvell/cache_llc.h42
-rw-r--r--include/drivers/marvell/ccu.h51
-rw-r--r--include/drivers/marvell/gwin.h19
-rw-r--r--include/drivers/marvell/i2c.h19
-rw-r--r--include/drivers/marvell/io_win.h21
-rw-r--r--include/drivers/marvell/iob.h31
-rw-r--r--include/drivers/marvell/mci.h18
-rw-r--r--include/drivers/marvell/mochi/ap_setup.h17
-rw-r--r--include/drivers/marvell/mochi/cp110_setup.h53
-rw-r--r--include/drivers/marvell/thermal.h31
-rw-r--r--include/drivers/mmc.h13
-rw-r--r--include/drivers/partition/partition.h4
-rw-r--r--include/drivers/st/stm32_gpio.h101
-rw-r--r--include/drivers/st/stm32_i2c.h300
-rw-r--r--include/drivers/st/stm32mp1_clk.h30
-rw-r--r--include/drivers/st/stm32mp1_clkfunc.h42
-rw-r--r--include/drivers/st/stm32mp1_ddr.h173
-rw-r--r--include/drivers/st/stm32mp1_ddr_helpers.h12
-rw-r--r--include/drivers/st/stm32mp1_ddr_regs.h413
-rw-r--r--include/drivers/st/stm32mp1_pmic.h18
-rw-r--r--include/drivers/st/stm32mp1_pwr.h32
-rw-r--r--include/drivers/st/stm32mp1_ram.h12
-rw-r--r--include/drivers/st/stm32mp1_rcc.h368
-rw-r--r--include/drivers/st/stm32mp1_reset.h15
-rw-r--r--include/drivers/st/stpmu1.h141
-rw-r--r--include/drivers/synopsys/dw_mmc.h4
-rw-r--r--include/drivers/ti/uart/uart_16550.h4
-rw-r--r--include/dt-bindings/clock/stm32mp1-clks.h251
-rw-r--r--include/dt-bindings/clock/stm32mp1-clksrc.h283
-rw-r--r--include/dt-bindings/pinctrl/stm32-pinfunc.h35
-rw-r--r--include/dt-bindings/reset/stm32mp1-resets.h108
-rw-r--r--include/lib/aarch32/arch.h513
-rw-r--r--include/lib/aarch32/arch_helpers.h25
-rw-r--r--include/lib/aarch32/smccc_helpers.h2
-rw-r--r--include/lib/aarch64/arch.h162
-rw-r--r--include/lib/aarch64/arch_helpers.h15
-rw-r--r--include/lib/bakery_lock.h3
-rw-r--r--include/lib/cassert.h4
-rw-r--r--include/lib/coreboot.h4
-rw-r--r--include/lib/cpus/aarch64/cortex_a72.h7
-rw-r--r--include/lib/cpus/aarch64/dsu_def.h33
-rw-r--r--include/lib/el3_runtime/aarch64/context.h6
-rw-r--r--include/lib/extensions/amu.h3
-rw-r--r--include/lib/extensions/mpam.h15
-rw-r--r--include/lib/extensions/ras.h32
-rw-r--r--include/lib/extensions/ras_arch.h80
-rw-r--r--include/lib/libc/aarch32/endian_.h146
-rw-r--r--include/lib/libc/aarch32/limits_.h26
-rw-r--r--include/lib/libc/aarch32/stddef_.h15
-rw-r--r--include/lib/libc/aarch32/stdint_.h118
-rw-r--r--include/lib/libc/aarch32/stdio_.h15
-rw-r--r--include/lib/libc/aarch32/stdlib_.h13
-rw-r--r--include/lib/libc/aarch32/string_.h10
-rw-r--r--include/lib/libc/aarch32/time_.h12
-rw-r--r--include/lib/libc/aarch64/endian_.h (renamed from include/lib/stdlib/machine/endian.h)88
-rw-r--r--include/lib/libc/aarch64/limits_.h26
-rw-r--r--include/lib/libc/aarch64/stddef_.h15
-rw-r--r--include/lib/libc/aarch64/stdint_.h118
-rw-r--r--include/lib/libc/aarch64/stdio_.h15
-rw-r--r--include/lib/libc/aarch64/stdlib_.h13
-rw-r--r--include/lib/libc/aarch64/string_.h10
-rw-r--r--include/lib/libc/aarch64/time_.h12
-rw-r--r--include/lib/libc/assert.h39
-rw-r--r--include/lib/libc/cdefs.h28
-rw-r--r--include/lib/libc/endian.h (renamed from include/lib/stdlib/sys/endian.h)42
-rw-r--r--include/lib/libc/errno.h (renamed from include/lib/stdlib/sys/errno.h)50
-rw-r--r--include/lib/libc/limits.h19
-rw-r--r--include/lib/libc/stdarg.h20
-rw-r--r--include/lib/libc/stdbool.h17
-rw-r--r--include/lib/libc/stddef.h22
-rw-r--r--include/lib/libc/stdint.h16
-rw-r--r--include/lib/libc/stdio.h33
-rw-r--r--include/lib/libc/stdlib.h26
-rw-r--r--include/lib/libc/string.h31
-rw-r--r--include/lib/libc/time.h20
-rw-r--r--include/lib/pmf/pmf.h16
-rw-r--r--include/lib/pmf/pmf_helpers.h14
-rw-r--r--include/lib/psci/psci.h103
-rw-r--r--include/lib/psci/psci_compat.h21
-rw-r--r--include/lib/psci/psci_lib.h22
-rw-r--r--include/lib/spinlock.h4
-rw-r--r--include/lib/stdlib/assert.h77
-rw-r--r--include/lib/stdlib/inttypes.h52
-rw-r--r--include/lib/stdlib/machine/_inttypes.h15
-rw-r--r--include/lib/stdlib/machine/_limits.h105
-rw-r--r--include/lib/stdlib/machine/_stdint.h184
-rw-r--r--include/lib/stdlib/machine/_types.h121
-rw-r--r--include/lib/stdlib/stdbool.h43
-rw-r--r--include/lib/stdlib/stddef.h64
-rw-r--r--include/lib/stdlib/stdio.h78
-rw-r--r--include/lib/stdlib/stdlib.h313
-rw-r--r--include/lib/stdlib/string.h69
-rw-r--r--include/lib/stdlib/strings.h71
-rw-r--r--include/lib/stdlib/sys/_null.h47
-rw-r--r--include/lib/stdlib/sys/_stdint.h82
-rw-r--r--include/lib/stdlib/sys/_timespec.h49
-rw-r--r--include/lib/stdlib/sys/_types.h106
-rw-r--r--include/lib/stdlib/sys/cdefs.h688
-rw-r--r--include/lib/stdlib/sys/ctype.h59
-rw-r--r--include/lib/stdlib/sys/limits.h100
-rw-r--r--include/lib/stdlib/sys/stdarg.h75
-rw-r--r--include/lib/stdlib/sys/stdint.h74
-rw-r--r--include/lib/stdlib/sys/timespec.h63
-rw-r--r--include/lib/stdlib/sys/types.h245
-rw-r--r--include/lib/stdlib/time.h204
-rw-r--r--include/lib/stdlib/xlocale/_strings.h48
-rw-r--r--include/lib/stdlib/xlocale/_time.h58
-rw-r--r--include/lib/utils.h2
-rw-r--r--include/lib/utils_def.h36
-rw-r--r--include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h17
-rw-r--r--include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h24
-rw-r--r--include/lib/xlat_tables/xlat_mmu_helpers.h41
-rw-r--r--include/lib/xlat_tables/xlat_tables.h8
-rw-r--r--include/lib/xlat_tables/xlat_tables_arch.h12
-rw-r--r--include/lib/xlat_tables/xlat_tables_defs.h36
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2.h36
-rw-r--r--include/lib/xlat_tables/xlat_tables_v2_helpers.h142
-rw-r--r--include/plat/arm/board/common/board_arm_def.h19
-rw-r--r--include/plat/arm/common/arm_config.h30
-rw-r--r--include/plat/arm/common/arm_def.h90
-rw-r--r--include/plat/arm/common/arm_spm_def.h10
-rw-r--r--include/plat/arm/common/plat_arm.h16
-rw-r--r--include/plat/arm/css/common/css_def.h8
-rw-r--r--include/plat/arm/css/common/css_pm.h2
-rw-r--r--include/plat/common/common_def.h1
-rw-r--r--include/plat/common/platform.h9
-rw-r--r--include/plat/marvell/a8k/common/a8k_common.h128
-rw-r--r--include/plat/marvell/a8k/common/board_marvell_def.h79
-rw-r--r--include/plat/marvell/a8k/common/marvell_def.h180
-rw-r--r--include/plat/marvell/a8k/common/plat_marvell.h111
-rw-r--r--include/plat/marvell/a8k/common/plat_pm_trace.h100
-rw-r--r--include/plat/marvell/common/aarch64/cci_macros.S39
-rw-r--r--include/plat/marvell/common/aarch64/marvell_macros.S134
-rw-r--r--include/plat/marvell/common/marvell_plat_priv.h34
-rw-r--r--include/plat/marvell/common/marvell_pm.h26
-rw-r--r--include/plat/marvell/common/mvebu.h38
-rw-r--r--include/services/sdei.h113
-rw-r--r--include/services/secure_partition.h2
-rw-r--r--lib/aarch32/armclang_printf.S19
-rw-r--r--lib/aarch64/armclang_printf.S19
-rw-r--r--lib/compiler-rt/builtins/int_lib.h7
-rw-r--r--lib/cpus/aarch64/cortex_a55.S32
-rw-r--r--lib/cpus/aarch64/cortex_a75.S8
-rw-r--r--lib/cpus/aarch64/cortex_a76.S10
-rw-r--r--lib/cpus/aarch64/denver.S60
-rw-r--r--lib/cpus/aarch64/dsu_helpers.S70
-rw-r--r--lib/cpus/cpu-ops.mk9
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c7
-rw-r--r--lib/extensions/mpam/mpam.c40
-rw-r--r--lib/extensions/ras/ras_common.c32
-rw-r--r--lib/extensions/ras/std_err_record.c26
-rw-r--r--lib/libc/abort.c (renamed from lib/stdlib/abort.c)5
-rw-r--r--lib/libc/assert.c (renamed from lib/stdlib/assert.c)22
-rw-r--r--lib/libc/exit.c26
-rw-r--r--lib/libc/libc.mk27
-rw-r--r--lib/libc/memchr.c20
-rw-r--r--lib/libc/memcmp.c24
-rw-r--r--lib/libc/memcpy.c18
-rw-r--r--lib/libc/memmove.c31
-rw-r--r--lib/libc/memset.c17
-rw-r--r--lib/libc/printf.c (renamed from common/tf_printf.c)117
-rw-r--r--lib/libc/putchar.c19
-rw-r--r--lib/libc/puts.c (renamed from lib/stdlib/puts.c)11
-rw-r--r--lib/libc/snprintf.c (renamed from common/tf_snprintf.c)72
-rw-r--r--lib/libc/strchr.c (renamed from lib/stdlib/strchr.c)7
-rw-r--r--lib/libc/strcmp.c (renamed from lib/stdlib/strcmp.c)26
-rw-r--r--lib/libc/strlen.c17
-rw-r--r--lib/libc/strncmp.c (renamed from lib/stdlib/strncmp.c)13
-rw-r--r--lib/libc/strnlen.c (renamed from lib/stdlib/strnlen.c)7
-rw-r--r--lib/libfdt/libfdt.mk2
-rw-r--r--lib/pmf/pmf_main.c2
-rw-r--r--lib/psci/aarch32/psci_helpers.S22
-rw-r--r--lib/psci/aarch64/psci_helpers.S22
-rw-r--r--lib/psci/psci_common.c166
-rw-r--r--lib/psci/psci_main.c146
-rw-r--r--lib/psci/psci_mem_protect.c25
-rw-r--r--lib/psci/psci_off.c19
-rw-r--r--lib/psci/psci_on.c51
-rw-r--r--lib/psci/psci_private.h268
-rw-r--r--lib/psci/psci_setup.c70
-rw-r--r--lib/psci/psci_stat.c47
-rw-r--r--lib/psci/psci_suspend.c42
-rw-r--r--lib/psci/psci_system_off.c40
-rw-r--r--lib/romlib/Makefile71
-rwxr-xr-xlib/romlib/gentbl.sh40
-rwxr-xr-xlib/romlib/genvar.sh36
-rwxr-xr-xlib/romlib/genwrappers.sh52
-rw-r--r--lib/romlib/init.s30
-rw-r--r--lib/romlib/jmptbl.i35
-rw-r--r--lib/romlib/romlib.ld.S44
-rw-r--r--lib/stdlib/exit.c14
-rw-r--r--lib/stdlib/mem.c97
-rw-r--r--lib/stdlib/printf.c36
-rw-r--r--lib/stdlib/putchar.c24
-rw-r--r--lib/stdlib/sscanf.c27
-rw-r--r--lib/stdlib/stdlib.mk25
-rw-r--r--lib/stdlib/strlen.c44
-rw-r--r--lib/stdlib/subr_prf.c548
-rw-r--r--lib/stdlib/timingsafe_bcmp.c36
-rw-r--r--lib/xlat_tables/aarch32/xlat_tables.c48
-rw-r--r--lib/xlat_tables/aarch64/xlat_tables.c46
-rw-r--r--lib/xlat_tables/xlat_tables_common.c130
-rw-r--r--lib/xlat_tables/xlat_tables_private.h12
-rw-r--r--lib/xlat_tables_v2/aarch32/enable_mmu.S72
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch.c152
-rw-r--r--lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h22
-rw-r--r--lib/xlat_tables_v2/aarch64/enable_mmu.S36
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch.c165
-rw-r--r--lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h28
-rw-r--r--lib/xlat_tables_v2/xlat_tables.mk2
-rw-r--r--lib/xlat_tables_v2/xlat_tables_context.c75
-rw-r--r--lib/xlat_tables_v2/xlat_tables_core.c375
-rw-r--r--lib/xlat_tables_v2/xlat_tables_private.h44
-rw-r--r--lib/xlat_tables_v2/xlat_tables_utils.c232
-rw-r--r--maintainers.rst34
-rw-r--r--make_helpers/build_macros.mk83
-rw-r--r--make_helpers/defaults.mk9
-rw-r--r--plat/allwinner/common/include/platform_def.h15
-rw-r--r--plat/arm/board/common/board_common.mk10
-rw-r--r--plat/arm/board/common/board_css_common.c2
-rw-r--r--plat/arm/board/fvp/fvp_bl31_setup.c2
-rw-r--r--plat/arm/board/fvp/fvp_def.h8
-rw-r--r--plat/arm/board/fvp/include/platform_def.h3
-rw-r--r--plat/arm/board/fvp/platform.mk7
-rw-r--r--plat/arm/board/juno/include/platform_def.h13
-rw-r--r--plat/arm/board/juno/juno_bl2_setup.c2
-rw-r--r--plat/arm/board/juno/juno_def.h9
-rw-r--r--plat/arm/board/juno/platform.mk7
-rw-r--r--plat/arm/board/sgi575/platform.mk7
-rw-r--r--plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts16
-rw-r--r--plat/arm/board/sgm775/include/platform_def.h15
-rw-r--r--plat/arm/board/sgm775/platform.mk20
-rw-r--r--plat/arm/common/arm_bl1_setup.c52
-rw-r--r--plat/arm/common/arm_bl2_el3_setup.c29
-rw-r--r--plat/arm/common/arm_bl2_setup.c42
-rw-r--r--plat/arm/common/arm_bl2u_setup.c35
-rw-r--r--plat/arm/common/arm_bl31_setup.c46
-rw-r--r--plat/arm/common/arm_common.c75
-rw-r--r--plat/arm/common/arm_common.mk3
-rw-r--r--plat/arm/common/arm_dyn_cfg.c6
-rw-r--r--plat/arm/common/arm_err.c2
-rw-r--r--plat/arm/common/arm_nor_psci_mem_protect.c8
-rw-r--r--plat/arm/common/arm_pm.c14
-rw-r--r--plat/arm/common/arm_sip_svc.c8
-rw-r--r--plat/arm/common/arm_tzc_dmc500.c1
-rw-r--r--plat/arm/common/execution_state_switch.c31
-rw-r--r--plat/arm/common/sp_min/arm_sp_min_setup.c30
-rw-r--r--plat/arm/common/tsp/arm_tsp_setup.c24
-rw-r--r--plat/arm/css/common/css_topology.c6
-rw-r--r--plat/arm/css/drivers/scp/css_pm_scmi.c8
-rw-r--r--plat/arm/css/drivers/scp/css_scp.h4
-rw-r--r--plat/arm/css/sgi/aarch64/sgi_helper.S60
-rw-r--r--plat/arm/css/sgi/include/platform_def.h65
-rw-r--r--plat/arm/css/sgi/include/sgi_ras.h22
-rw-r--r--plat/arm/css/sgi/sgi-common.mk16
-rw-r--r--plat/arm/css/sgi/sgi_bl31_setup.c10
-rw-r--r--plat/arm/css/sgi/sgi_plat.c71
-rw-r--r--plat/arm/css/sgi/sgi_ras.c173
-rw-r--r--plat/arm/css/sgi/sgi_topology.c9
-rw-r--r--plat/arm/css/sgm/aarch64/css_sgm_helpers.S96
-rw-r--r--plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts16
-rw-r--r--plat/arm/css/sgm/include/plat_macros.S24
-rw-r--r--plat/arm/css/sgm/include/platform_oid.h11
-rw-r--r--plat/arm/css/sgm/include/sgm_base_platform_def.h234
-rw-r--r--plat/arm/css/sgm/include/sgm_plat_config.h43
-rw-r--r--plat/arm/css/sgm/include/sgm_variant.h17
-rw-r--r--plat/arm/css/sgm/sgm-common.mk68
-rw-r--r--plat/arm/css/sgm/sgm_bl1_setup.c31
-rw-r--r--plat/arm/css/sgm/sgm_bl31_setup.c34
-rw-r--r--plat/arm/css/sgm/sgm_interconnect.c32
-rw-r--r--plat/arm/css/sgm/sgm_mmap_config.c83
-rw-r--r--plat/arm/css/sgm/sgm_plat_config.c69
-rw-r--r--plat/arm/css/sgm/sgm_security.c64
-rw-r--r--plat/arm/css/sgm/sgm_topology.c32
-rw-r--r--plat/arm/css/sgm/tsp/sgm_tsp_setup.c16
-rw-r--r--plat/arm/css/sgm/tsp/tsp-sgm.mk11
-rw-r--r--plat/common/aarch32/plat_common.c2
-rw-r--r--plat/common/aarch64/platform_helpers.S35
-rw-r--r--plat/common/plat_gicv2.c22
-rw-r--r--plat/common/plat_gicv3.c39
-rw-r--r--plat/common/plat_log_common.c21
-rw-r--r--plat/common/plat_psci_common.c32
-rw-r--r--plat/hisilicon/hikey/hikey_bl1_setup.c10
-rw-r--r--plat/hisilicon/hikey/hikey_bl2_setup.c10
-rw-r--r--plat/hisilicon/hikey/hikey_io_storage.c95
-rw-r--r--plat/hisilicon/hikey/hikey_rotpk.S16
-rw-r--r--plat/hisilicon/hikey/hikey_security.c2
-rw-r--r--plat/hisilicon/hikey/hikey_tbbr.c31
-rw-r--r--plat/hisilicon/hikey/hisi_ipc.c3
-rw-r--r--plat/hisilicon/hikey/include/hikey_layout.h14
-rw-r--r--plat/hisilicon/hikey/include/platform_def.h13
-rw-r--r--plat/hisilicon/hikey/platform.mk44
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl1_setup.c1
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl2_setup.c1
-rw-r--r--plat/hisilicon/hikey960/hikey960_bl_common.c32
-rw-r--r--plat/hisilicon/hikey960/hikey960_private.h1
-rw-r--r--plat/hisilicon/hikey960/include/hi3660.h24
-rw-r--r--plat/hisilicon/hikey960/include/platform_def.h11
-rw-r--r--plat/hisilicon/hikey960/platform.mk6
-rw-r--r--plat/hisilicon/poplar/bl1_plat_setup.c6
-rw-r--r--plat/hisilicon/poplar/bl2_plat_setup.c7
-rw-r--r--plat/hisilicon/poplar/include/hi3798cv200.h4
-rw-r--r--plat/hisilicon/poplar/include/platform_def.h12
-rw-r--r--plat/hisilicon/poplar/plat_storage.c8
-rw-r--r--plat/hisilicon/poplar/platform.mk4
-rw-r--r--plat/imx/common/imx8_psci.c46
-rw-r--r--plat/imx/common/imx8_topology.c3
-rw-r--r--plat/imx/common/include/imx8_lpuart.h2
-rw-r--r--plat/imx/common/include/plat_imx8.h6
-rw-r--r--plat/imx/common/include/sci/sci_scfw.h2
-rw-r--r--plat/imx/common/sci/imx8_mu.h2
-rw-r--r--plat/imx/imx8qm/imx8qm_psci.c108
-rw-r--r--plat/imx/imx8qm/include/platform_def.h15
-rw-r--r--plat/imx/imx8qm/platform.mk1
-rw-r--r--plat/imx/imx8qx/imx8qx_psci.c62
-rw-r--r--plat/imx/imx8qx/include/platform_def.h18
-rw-r--r--plat/imx/imx8qx/platform.mk2
-rw-r--r--plat/layerscape/board/ls1043/include/ls_def.h12
-rw-r--r--plat/layerscape/board/ls1043/include/platform_def.h6
-rw-r--r--plat/layerscape/board/ls1043/ls1043_psci.c10
-rw-r--r--plat/layerscape/common/include/ls_16550.h2
-rw-r--r--plat/layerscape/common/include/plat_ls.h2
-rw-r--r--plat/layerscape/common/ls_bl1_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl2_setup.c2
-rw-r--r--plat/layerscape/common/ls_bl31_setup.c5
-rw-r--r--plat/marvell/a8k/a70x0/board/dram_port.c89
-rw-r--r--plat/marvell/a8k/a70x0/board/marvell_plat_config.c141
-rw-r--r--plat/marvell/a8k/a70x0/mvebu_def.h15
-rw-r--r--plat/marvell/a8k/a70x0/platform.mk16
-rw-r--r--plat/marvell/a8k/a70x0_amc/board/dram_port.c89
-rw-r--r--plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c142
-rw-r--r--plat/marvell/a8k/a70x0_amc/mvebu_def.h31
-rw-r--r--plat/marvell/a8k/a70x0_amc/platform.mk16
-rw-r--r--plat/marvell/a8k/a80x0/board/dram_port.c141
-rw-r--r--plat/marvell/a8k/a80x0/board/marvell_plat_config.c191
-rw-r--r--plat/marvell/a8k/a80x0/mvebu_def.h17
-rw-r--r--plat/marvell/a8k/a80x0/platform.mk16
-rw-r--r--plat/marvell/a8k/a80x0_mcbin/board/dram_port.c129
-rw-r--r--plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c196
-rw-r--r--plat/marvell/a8k/a80x0_mcbin/mvebu_def.h17
-rw-r--r--plat/marvell/a8k/a80x0_mcbin/platform.mk16
-rw-r--r--plat/marvell/a8k/common/a8k_common.mk122
-rw-r--r--plat/marvell/a8k/common/aarch64/a8k_common.c64
-rw-r--r--plat/marvell/a8k/common/aarch64/plat_arch_config.c46
-rw-r--r--plat/marvell/a8k/common/aarch64/plat_helpers.S112
-rw-r--r--plat/marvell/a8k/common/include/a8k_plat_def.h190
-rw-r--r--plat/marvell/a8k/common/include/ddr_info.h9
-rw-r--r--plat/marvell/a8k/common/include/plat_macros.S20
-rw-r--r--plat/marvell/a8k/common/include/platform_def.h202
-rw-r--r--plat/marvell/a8k/common/mss/mss_a8k.mk20
-rw-r--r--plat/marvell/a8k/common/mss/mss_bl2_setup.c143
-rw-r--r--plat/marvell/a8k/common/mss/mss_pm_ipc.c84
-rw-r--r--plat/marvell/a8k/common/mss/mss_pm_ipc.h35
-rw-r--r--plat/marvell/a8k/common/plat_bl1_setup.c18
-rw-r--r--plat/marvell/a8k/common/plat_bl31_setup.c119
-rw-r--r--plat/marvell/a8k/common/plat_ble_setup.c570
-rw-r--r--plat/marvell/a8k/common/plat_pm.c829
-rw-r--r--plat/marvell/a8k/common/plat_pm_trace.c91
-rw-r--r--plat/marvell/a8k/common/plat_thermal.c129
-rw-r--r--plat/marvell/common/aarch64/marvell_common.c135
-rw-r--r--plat/marvell/common/aarch64/marvell_helpers.S223
-rw-r--r--plat/marvell/common/marvell_bl1_setup.c117
-rw-r--r--plat/marvell/common/marvell_bl2_setup.c275
-rw-r--r--plat/marvell/common/marvell_bl31_setup.c236
-rw-r--r--plat/marvell/common/marvell_cci.c51
-rw-r--r--plat/marvell/common/marvell_common.mk67
-rw-r--r--plat/marvell/common/marvell_ddr_info.c110
-rw-r--r--plat/marvell/common/marvell_gicv2.c59
-rw-r--r--plat/marvell/common/marvell_io_storage.c206
-rw-r--r--plat/marvell/common/marvell_pm.c58
-rw-r--r--plat/marvell/common/marvell_topology.c84
-rw-r--r--plat/marvell/common/mrvl_sip_svc.c127
-rw-r--r--plat/marvell/common/mss/mss_common.mk20
-rw-r--r--plat/marvell/common/mss/mss_ipc_drv.c111
-rw-r--r--plat/marvell/common/mss/mss_ipc_drv.h120
-rw-r--r--plat/marvell/common/mss/mss_mem.h60
-rw-r--r--plat/marvell/common/mss/mss_scp_bl2_format.h44
-rw-r--r--plat/marvell/common/mss/mss_scp_bootloader.c308
-rw-r--r--plat/marvell/common/mss/mss_scp_bootloader.h19
-rw-r--r--plat/marvell/common/plat_delay_timer.c33
-rw-r--r--plat/marvell/marvell.mk53
-rw-r--r--plat/marvell/version.mk1
-rw-r--r--plat/mediatek/mt6795/include/platform_def.h12
-rw-r--r--plat/mediatek/mt6795/power_tracer.c12
-rw-r--r--plat/mediatek/mt8173/include/platform_def.h16
-rw-r--r--plat/mediatek/mt8173/power_tracer.c12
-rw-r--r--plat/nvidia/tegra/common/drivers/smmu/smmu.c4
-rw-r--r--plat/nvidia/tegra/common/tegra_bl31_setup.c9
-rw-r--r--plat/nvidia/tegra/include/drivers/memctrl_v2.h4
-rw-r--r--plat/nvidia/tegra/include/tegra_platform.h4
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/mce/ari.c4
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/mce/mce.c4
-rw-r--r--plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c4
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_psci_handlers.c4
-rw-r--r--plat/nvidia/tegra/soc/t186/plat_secondary.c4
-rw-r--r--plat/qemu/include/platform_def.h17
-rw-r--r--plat/qemu/platform.mk3
-rw-r--r--plat/qemu/qemu_private.h5
-rw-r--r--plat/qemu/topology.c4
-rw-r--r--plat/rockchip/common/aarch64/plat_helpers.S7
-rw-r--r--plat/rockchip/rk3328/include/platform_def.h12
-rw-r--r--plat/rockchip/rk3368/include/platform_def.h13
-rw-r--r--plat/rockchip/rk3399/drivers/dp/cdn_dp.c1
-rw-r--r--plat/rockchip/rk3399/include/platform_def.h13
-rw-r--r--plat/rpi3/aarch64/plat_helpers.S4
-rw-r--r--plat/rpi3/include/plat_macros.S11
-rw-r--r--plat/rpi3/include/platform_def.h21
-rw-r--r--plat/rpi3/platform.mk54
-rw-r--r--plat/rpi3/rpi3_bl1_setup.c34
-rw-r--r--plat/rpi3/rpi3_bl2_setup.c6
-rw-r--r--plat/rpi3/rpi3_bl31_setup.c81
-rw-r--r--plat/rpi3/rpi3_hw.h63
-rw-r--r--plat/rpi3/rpi3_mbox.c146
-rw-r--r--plat/rpi3/rpi3_pm.c73
-rw-r--r--plat/rpi3/rpi3_private.h8
-rw-r--r--plat/rpi3/rpi3_rng.c74
-rw-r--r--plat/rpi3/rpi3_stack_protector.c27
-rw-r--r--plat/rpi3/rpi3_topology.c4
-rw-r--r--plat/socionext/synquacer/include/platform_def.h13
-rw-r--r--plat/socionext/synquacer/include/sq_common.h2
-rw-r--r--plat/socionext/synquacer/platform.mk4
-rw-r--r--plat/socionext/synquacer/sq_bl31_setup.c37
-rw-r--r--plat/socionext/uniphier/include/platform_def.h12
-rw-r--r--plat/socionext/uniphier/uniphier.h2
-rw-r--r--plat/socionext/uniphier/uniphier_bl31_setup.c5
-rw-r--r--plat/socionext/uniphier/uniphier_emmc.c4
-rw-r--r--plat/socionext/uniphier/uniphier_io_storage.c4
-rw-r--r--plat/socionext/uniphier/uniphier_nand.c4
-rw-r--r--plat/socionext/uniphier/uniphier_usb.c4
-rw-r--r--plat/st/stm32mp1/bl2_io_storage.c193
-rw-r--r--plat/st/stm32mp1/bl2_plat_setup.c161
-rw-r--r--plat/st/stm32mp1/include/boot_api.h235
-rw-r--r--plat/st/stm32mp1/include/platform_def.h187
-rw-r--r--plat/st/stm32mp1/include/stm32mp1_context.h14
-rw-r--r--plat/st/stm32mp1/include/stm32mp1_dt.h41
-rw-r--r--plat/st/stm32mp1/include/stm32mp1_private.h22
-rw-r--r--plat/st/stm32mp1/plat_bl2_mem_params_desc.c68
-rw-r--r--plat/st/stm32mp1/plat_image_load.c32
-rw-r--r--plat/st/stm32mp1/platform.mk148
-rw-r--r--plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk21
-rw-r--r--plat/st/stm32mp1/sp_min/sp_min_setup.c144
-rw-r--r--plat/st/stm32mp1/stm32mp1.S16
-rw-r--r--plat/st/stm32mp1/stm32mp1.ld.S76
-rw-r--r--plat/st/stm32mp1/stm32mp1_common.c101
-rw-r--r--plat/st/stm32mp1/stm32mp1_context.c42
-rw-r--r--plat/st/stm32mp1/stm32mp1_def.h193
-rw-r--r--plat/st/stm32mp1/stm32mp1_dt.c476
-rw-r--r--plat/st/stm32mp1/stm32mp1_gic.c48
-rw-r--r--plat/st/stm32mp1/stm32mp1_helper.S180
-rw-r--r--plat/st/stm32mp1/stm32mp1_pm.c255
-rw-r--r--plat/st/stm32mp1/stm32mp1_security.c127
-rw-r--r--plat/st/stm32mp1/stm32mp1_stack_protector.c21
-rw-r--r--plat/st/stm32mp1/stm32mp1_topology.c56
-rw-r--r--plat/ti/k3/board/generic/include/board_def.h15
-rw-r--r--plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c289
-rw-r--r--plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h58
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci.c1482
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci.h208
-rw-r--r--plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h650
-rw-r--r--plat/ti/k3/common/k3_bl31_setup.c24
-rw-r--r--plat/ti/k3/common/k3_psci.c55
-rw-r--r--plat/ti/k3/common/plat_common.mk12
-rw-r--r--plat/ti/k3/include/platform_def.h15
-rw-r--r--plat/xilinx/zynqmp/bl31_zynqmp_setup.c23
-rw-r--r--plat/xilinx/zynqmp/include/platform_def.h15
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.c15
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.h1
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.c17
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.h1
-rw-r--r--plat/xilinx/zynqmp/tsp/tsp_plat_setup.c23
-rw-r--r--readme.rst33
-rw-r--r--services/spd/trusty/generic-arm64-smcall.c15
-rw-r--r--services/std_svc/sdei/sdei_event.c9
-rw-r--r--services/std_svc/sdei/sdei_intr_mgmt.c130
-rw-r--r--services/std_svc/sdei/sdei_main.c268
-rw-r--r--services/std_svc/sdei/sdei_private.h104
-rw-r--r--services/std_svc/sdei/sdei_state.c8
-rw-r--r--services/std_svc/spm/sp_setup.c49
-rw-r--r--services/std_svc/spm/sp_xlat.c10
-rw-r--r--services/std_svc/spm/spm_shim_private.h2
-rw-r--r--tools/doimage/Makefile48
-rw-r--r--tools/doimage/doimage.c1755
-rw-r--r--tools/doimage/doimage.mk15
-rw-r--r--tools/stm32image/Makefile49
-rw-r--r--tools/stm32image/stm32image.c247
599 files changed, 42099 insertions, 8891 deletions
diff --git a/.gitignore b/.gitignore
index 4ece189ab..78da669f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,10 @@ tools/cert_create/src/*.o
tools/cert_create/src/**/*.o
tools/cert_create/cert_create
tools/cert_create/cert_create.exe
+tools/doimage/doimage
+tools/stm32image/*.o
+tools/stm32image/stm32image
+tools/stm32image/stm32image.exe
# GNU GLOBAL files
GPATH
diff --git a/Makefile b/Makefile
index 533cb8ab1..9dc8a4220 100644
--- a/Makefile
+++ b/Makefile
@@ -45,7 +45,7 @@ CHECKCODE_ARGS := --no-patch
# Do not check the coding style on imported library files or documentation files
INC_LIB_DIRS_TO_CHECK := $(sort $(filter-out \
include/lib/libfdt \
- include/lib/stdlib, \
+ include/lib/libc, \
$(wildcard include/lib/*)))
INC_DIRS_TO_CHECK := $(sort $(filter-out \
include/lib, \
@@ -53,7 +53,7 @@ INC_DIRS_TO_CHECK := $(sort $(filter-out \
LIB_DIRS_TO_CHECK := $(sort $(filter-out \
lib/compiler-rt \
lib/libfdt% \
- lib/stdlib, \
+ lib/libc, \
$(wildcard lib/*)))
ROOT_DIRS_TO_CHECK := $(sort $(filter-out \
lib \
@@ -100,6 +100,13 @@ else
LOG_LEVEL := 20
endif
+# Enable backtrace by default in DEBUG AArch64 builds
+ifeq (${ARCH},aarch32)
+ ENABLE_BACKTRACE := 0
+else
+ ENABLE_BACKTRACE := ${DEBUG}
+endif
+
# Default build string (git branch and commit)
ifeq (${BUILD_STRING},)
BUILD_STRING := $(shell git describe --always --dirty --tags 2> /dev/null)
@@ -166,13 +173,21 @@ TF_CFLAGS_aarch64 = -march=armv8-a
LD = $(LINKER)
endif
+ifeq (${AARCH32_INSTRUCTION_SET},A32)
+TF_CFLAGS_aarch32 += -marm
+else ifeq (${AARCH32_INSTRUCTION_SET},T32)
+TF_CFLAGS_aarch32 += -mthumb
+else
+$(error Error: Unknown AArch32 instruction set ${AARCH32_INSTRUCTION_SET})
+endif
+
TF_CFLAGS_aarch32 += -mno-unaligned-access
TF_CFLAGS_aarch64 += -mgeneral-regs-only -mstrict-align
ASFLAGS_aarch32 = $(march32-directive)
ASFLAGS_aarch64 = -march=armv8-a
-CPPFLAGS = ${DEFINES} ${INCLUDES} -nostdinc \
+CPPFLAGS = ${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc \
-Wmissing-include-dirs -Werror
ASFLAGS += $(CPPFLAGS) $(ASFLAGS_$(ARCH)) \
-D__ASSEMBLY__ -ffreestanding \
@@ -188,6 +203,11 @@ ifneq ($(PIE_FOUND),)
TF_CFLAGS += -fno-PIE
endif
+# Force the compiler to include the frame pointer
+ifeq (${ENABLE_BACKTRACE},1)
+TF_CFLAGS += -fno-omit-frame-pointer
+endif
+
TF_LDFLAGS += --fatal-warnings -O1
TF_LDFLAGS += --gc-sections
TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH))
@@ -198,12 +218,10 @@ DTC_FLAGS += -I dts -O dtb
# Common sources and include directories
################################################################################
include lib/compiler-rt/compiler-rt.mk
-include lib/stdlib/stdlib.mk
+include lib/libc/libc.mk
BL_COMMON_SOURCES += common/bl_common.c \
common/tf_log.c \
- common/tf_printf.c \
- common/tf_snprintf.c \
common/${ARCH}/debug.S \
lib/${ARCH}/cache_helpers.S \
lib/${ARCH}/misc_helpers.S \
@@ -211,8 +229,15 @@ BL_COMMON_SOURCES += common/bl_common.c \
plat/common/plat_log_common.c \
plat/common/${ARCH}/plat_common.c \
plat/common/${ARCH}/platform_helpers.S \
- ${COMPILER_RT_SRCS} \
- ${STDLIB_SRCS}
+ ${COMPILER_RT_SRCS}
+
+ifeq ($(notdir $(CC)),armclang)
+BL_COMMON_SOURCES += lib/${ARCH}/armclang_printf.S
+endif
+
+ifeq (${ENABLE_BACKTRACE},1)
+BL_COMMON_SOURCES += common/backtrace.c
+endif
INCLUDES += -Iinclude \
-Iinclude/bl1 \
@@ -242,7 +267,6 @@ INCLUDES += -Iinclude \
${SPD_INCLUDES} \
-Iinclude/tools_share
-
################################################################################
# Generic definitions
################################################################################
@@ -345,6 +369,15 @@ endif
# Check incompatible options
################################################################################
+ifeq (${ARCH},aarch32)
+ ifeq (${ENABLE_BACKTRACE},1)
+ ifneq (${AARCH32_INSTRUCTION_SET},A32)
+ $(error Error: AARCH32_INSTRUCTION_SET=A32 is needed \
+ for ENABLE_BACKTRACE when compiling for AArch32.)
+ endif
+ endif
+endif
+
ifdef EL3_PAYLOAD_BASE
ifdef PRELOADED_BL33_BASE
$(warning "PRELOADED_BL33_BASE and EL3_PAYLOAD_BASE are \
@@ -506,6 +539,9 @@ CRTTOOL ?= ${CRTTOOLPATH}/cert_create${BIN_EXT}
FIPTOOLPATH ?= tools/fiptool
FIPTOOL ?= ${FIPTOOLPATH}/fiptool${BIN_EXT}
+# Variables for use with ROMLIB
+ROMLIBPATH ?= lib/romlib
+
################################################################################
# Include BL specific makefiles
################################################################################
@@ -548,6 +584,8 @@ $(eval $(call assert_boolean,DYN_DISABLE_AUTH))
$(eval $(call assert_boolean,EL3_EXCEPTION_HANDLING))
$(eval $(call assert_boolean,ENABLE_AMU))
$(eval $(call assert_boolean,ENABLE_ASSERTIONS))
+$(eval $(call assert_boolean,ENABLE_BACKTRACE))
+$(eval $(call assert_boolean,ENABLE_MPAM_FOR_LOWER_ELS))
$(eval $(call assert_boolean,ENABLE_PLAT_COMPAT))
$(eval $(call assert_boolean,ENABLE_PMF))
$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
@@ -574,6 +612,7 @@ $(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call assert_boolean,USE_ROMLIB))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
$(eval $(call assert_boolean,BL2_AT_EL3))
@@ -598,6 +637,8 @@ $(eval $(call add_define,CTX_INCLUDE_FPREGS))
$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
$(eval $(call add_define,ENABLE_AMU))
$(eval $(call add_define,ENABLE_ASSERTIONS))
+$(eval $(call add_define,ENABLE_BACKTRACE))
+$(eval $(call add_define,ENABLE_MPAM_FOR_LOWER_ELS))
$(eval $(call add_define,ENABLE_PLAT_COMPAT))
$(eval $(call add_define,ENABLE_PMF))
$(eval $(call add_define,ENABLE_PSCI_STAT))
@@ -626,6 +667,7 @@ $(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_ROMLIB))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
$(eval $(call add_define,BL2_AT_EL3))
@@ -670,6 +712,9 @@ ifeq (${ERROR_DEPRECATED},0)
CPPFLAGS += -Wno-error=deprecated-declarations -Wno-error=cpp
endif
+$(eval $(call MAKE_LIB_DIRS))
+$(eval $(call MAKE_LIB,c))
+
# Expand build macros for the different images
ifeq (${NEED_BL1},yes)
$(eval $(call MAKE_BL,1))
@@ -734,6 +779,7 @@ clean:
$(call SHELL_REMOVE_DIR,${BUILD_PLAT})
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+ ${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
realclean distclean:
@echo " REALCLEAN"
@@ -741,11 +787,12 @@ realclean distclean:
$(call SHELL_DELETE_ALL, ${CURDIR}/cscope.*)
${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean
${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean
+ ${Q}${MAKE} --no-print-directory -C ${ROMLIBPATH} clean
checkcodebase: locate-checkpatch
@echo " CHECKING STYLE"
@if test -d .git ; then \
- git ls-files | grep -E -v 'libfdt|stdlib|docs|\.md' | \
+ git ls-files | grep -E -v 'libfdt|libc|docs|\.md' | \
while read GIT_FILE ; \
do ${CHECKPATCH} ${CHECKCODE_ARGS} -f $$GIT_FILE ; \
done ; \
@@ -753,7 +800,7 @@ checkcodebase: locate-checkpatch
find . -type f -not -iwholename "*.git*" \
-not -iwholename "*build*" \
-not -iwholename "*libfdt*" \
- -not -iwholename "*stdlib*" \
+ -not -iwholename "*libc*" \
-not -iwholename "*docs*" \
-not -iwholename "*.md" \
-exec ${CHECKPATCH} ${CHECKCODE_ARGS} -f {} \; ; \
@@ -819,6 +866,10 @@ fwu_fip: ${BUILD_PLAT}/${FWU_FIP_NAME}
${FIPTOOL}:
${Q}${MAKE} CPPFLAGS="-DVERSION='\"${VERSION_STRING}\"'" --no-print-directory -C ${FIPTOOLPATH}
+.PHONY: libraries
+romlib.bin: libraries
+ ${Q}${MAKE} BUILD_PLAT=${BUILD_PLAT} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
+
cscope:
@echo " CSCOPE"
${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
diff --git a/acknowledgements.rst b/acknowledgements.rst
index 9b81b6c5e..4d527f406 100644
--- a/acknowledgements.rst
+++ b/acknowledgements.rst
@@ -14,5 +14,9 @@ Xilinx, Inc.
NXP Semiconductors
+Marvell International Ltd.
+
+STMicroelectronics
+
Individuals
-----------
diff --git a/bl1/aarch32/bl1_exceptions.S b/bl1/aarch32/bl1_exceptions.S
index 154054245..9b001a96f 100644
--- a/bl1/aarch32/bl1_exceptions.S
+++ b/bl1/aarch32/bl1_exceptions.S
@@ -116,7 +116,7 @@ func smc_handler
/* Turn on the MMU */
mov r0, #DISABLE_DCACHE
- bl enable_mmu_secure
+ bl enable_mmu_svc_mon
/* Enable the data cache. */
ldcopr r9, SCTLR
diff --git a/bl1/bl1.mk b/bl1/bl1.mk
index 41ee1a736..ec7d7280b 100644
--- a/bl1/bl1.mk
+++ b/bl1/bl1.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -14,12 +14,11 @@ BL1_SOURCES += bl1/bl1_main.c \
lib/el3_runtime/${ARCH}/context_mgmt.c \
plat/common/plat_bl1_common.c \
plat/common/${ARCH}/platform_up_stack.S \
- ${MBEDTLS_COMMON_SOURCES} \
- ${MBEDTLS_CRYPTO_SOURCES} \
- ${MBEDTLS_X509_SOURCES}
+ ${MBEDTLS_SOURCES}
ifeq (${ARCH},aarch64)
-BL1_SOURCES += lib/el3_runtime/aarch64/context.S
+BL1_SOURCES += lib/cpus/aarch64/dsu_helpers.S \
+ lib/el3_runtime/aarch64/context.S
endif
ifeq (${TRUSTED_BOARD_BOOT},1)
diff --git a/bl1/bl1_private.h b/bl1/bl1_private.h
index 42a74d22f..583b61f4f 100644
--- a/bl1/bl1_private.h
+++ b/bl1/bl1_private.h
@@ -7,7 +7,7 @@
#ifndef __BL1_PRIVATE_H__
#define __BL1_PRIVATE_H__
-#include <types.h>
+#include <stdint.h>
#include <utils_def.h>
/*******************************************************************************
diff --git a/bl2/bl2.mk b/bl2/bl2.mk
index a856fb738..af30a81d5 100644
--- a/bl2/bl2.mk
+++ b/bl2/bl2.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,9 +8,7 @@ BL2_SOURCES += bl2/bl2_main.c \
bl2/${ARCH}/bl2_arch_setup.c \
lib/locks/exclusive/${ARCH}/spinlock.S \
plat/common/${ARCH}/platform_up_stack.S \
- ${MBEDTLS_COMMON_SOURCES} \
- ${MBEDTLS_CRYPTO_SOURCES} \
- ${MBEDTLS_X509_SOURCES}
+ ${MBEDTLS_SOURCES}
ifeq (${ARCH},aarch64)
BL2_SOURCES += common/aarch64/early_exceptions.S
@@ -31,5 +29,10 @@ BL2_SOURCES += bl2/${ARCH}/bl2_el3_entrypoint.S \
bl2/${ARCH}/bl2_el3_exceptions.S \
lib/cpus/${ARCH}/cpu_helpers.S \
lib/cpus/errata_report.c
+
+ifeq (${ARCH},aarch64)
+BL2_SOURCES += lib/cpus/aarch64/dsu_helpers.S
+endif
+
BL2_LINKERFILE := bl2/bl2_el3.ld.S
endif
diff --git a/bl2u/bl2u_main.c b/bl2u/bl2u_main.c
index a7e3fb916..b29d57e9d 100644
--- a/bl2u/bl2u_main.c
+++ b/bl2u/bl2u_main.c
@@ -17,6 +17,7 @@
#include <platform_def.h>
#include <stdint.h>
+
/*******************************************************************************
* This function is responsible to:
* Load SCP_BL2U if platform has defined SCP_BL2U_BASE
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
new file mode 100644
index 000000000..9d7c5e8a9
--- /dev/null
+++ b/bl31/aarch64/ea_delegate.S
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <assert_macros.S>
+#include <asm_macros.S>
+#include <assert_macros.S>
+#include <context.h>
+#include <ea_handle.h>
+#include <ras_arch.h>
+
+
+ .globl handle_lower_el_ea_esb
+ .globl enter_lower_el_sync_ea
+ .globl enter_lower_el_async_ea
+
+
+/*
+ * Function to delegate External Aborts synchronized by ESB instruction at EL3
+ * vector entry. This function assumes GP registers x0-x29 have been saved, and
+ * are available for use. It delegates the handling of the EA to platform
+ * handler, and returns only upon successfully handling the EA; otherwise
+ * panics. On return from this function, the original exception handler is
+ * expected to resume.
+ */
+func handle_lower_el_ea_esb
+ mov x0, #ERROR_EA_ESB
+ mrs x1, DISR_EL1
+ b ea_proceed
+endfunc handle_lower_el_ea_esb
+
+
+/*
+ * This function forms the tail end of Synchronous Exception entry from lower
+ * EL, and expects to handle only Synchronous External Aborts from lower EL. If
+ * any other kind of exception is detected, then this function reports unhandled
+ * exception.
+ *
+ * Since it's part of exception vector, this function doesn't expect any GP
+ * registers to have been saved. It delegates the handling of the EA to platform
+ * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ */
+func enter_lower_el_sync_ea
+ /*
+ * Explicitly save x30 so as to free up a register and to enable
+ * branching.
+ */
+ str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+ mrs x30, esr_el3
+ ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+
+ /* Check for I/D aborts from lower EL */
+ cmp x30, #EC_IABORT_LOWER_EL
+ b.eq 1f
+
+ cmp x30, #EC_DABORT_LOWER_EL
+ b.ne 2f
+
+1:
+ /* Test for EA bit in the instruction syndrome */
+ mrs x30, esr_el3
+ tbz x30, #ESR_ISS_EABORT_EA_BIT, 2f
+
+ /* Save GP registers */
+ bl save_gp_registers
+
+ /* Setup exception class and syndrome arguments for platform handler */
+ mov x0, #ERROR_EA_SYNC
+ mrs x1, esr_el3
+ adr x30, el3_exit
+ b delegate_sync_ea
+
+2:
+ /* Synchronous exceptions other than the above are assumed to be EA */
+ ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+ no_ret report_unhandled_exception
+endfunc enter_lower_el_sync_ea
+
+
+/*
+ * This function handles SErrors from lower ELs.
+ *
+ * Since it's part of exception vector, this function doesn't expect any GP
+ * registers to have been saved. It delegates the handling of the EA to platform
+ * handler, and upon successfully handling the EA, exits EL3; otherwise panics.
+ */
+func enter_lower_el_async_ea
+ /*
+ * Explicitly save x30 so as to free up a register and to enable
+ * branching
+ */
+ str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
+
+ /* Save GP registers */
+ bl save_gp_registers
+
+ /* Setup exception class and syndrome arguments for platform handler */
+ mov x0, #ERROR_EA_ASYNC
+ mrs x1, esr_el3
+ adr x30, el3_exit
+ b delegate_async_ea
+endfunc enter_lower_el_async_ea
+
+
+/*
+ * Prelude for Synchronous External Abort handling. This function assumes that
+ * all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func delegate_sync_ea
+#if RAS_EXTENSION
+ /*
+ * Check for Uncontainable error type. If so, route to the platform
+ * fatal error handler rather than the generic EA one.
+ */
+ ubfx x2, x1, #EABORT_SET_SHIFT, #EABORT_SET_WIDTH
+ cmp x2, #ERROR_STATUS_SET_UC
+ b.ne 1f
+
+ /* Check fault status code */
+ ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
+ cmp x3, #SYNC_EA_FSC
+ b.ne 1f
+
+ no_ret plat_handle_uncontainable_ea
+1:
+#endif
+
+ b ea_proceed
+endfunc delegate_sync_ea
+
+
+/*
+ * Prelude for Asynchronous External Abort handling. This function assumes that
+ * all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func delegate_async_ea
+#if RAS_EXTENSION
+ /*
+ * Check for Implementation Defined Syndrome. If so, skip checking
+ * Uncontainable error type from the syndrome as the format is unknown.
+ */
+ tbnz x1, #SERROR_IDS_BIT, 1f
+
+ /*
+ * Check for Uncontainable error type. If so, route to the platform
+ * fatal error handler rather than the generic EA one.
+ */
+ ubfx x2, x1, #EABORT_AET_SHIFT, #EABORT_AET_WIDTH
+ cmp x2, #ERROR_STATUS_UET_UC
+ b.ne 1f
+
+ /* Check DFSC for SError type */
+ ubfx x3, x1, #EABORT_DFSC_SHIFT, #EABORT_DFSC_WIDTH
+ cmp x3, #DFSC_SERROR
+ b.ne 1f
+
+ no_ret plat_handle_uncontainable_ea
+1:
+#endif
+
+ b ea_proceed
+endfunc delegate_async_ea
+
+
+/*
+ * Delegate External Abort handling to platform's EA handler. This function
+ * assumes that all GP registers have been saved by the caller.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ */
+func ea_proceed
+ /*
+ * If the ESR loaded earlier is not zero, we were processing an EA
+ * already, and this is a double fault.
+ */
+ ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3]
+ cbz x5, 1f
+ no_ret plat_handle_double_fault
+
+1:
+ /* Save EL3 state */
+ mrs x2, spsr_el3
+ mrs x3, elr_el3
+ stp x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+
+ /*
+ * Save ESR as handling might involve lower ELs, and returning back to
+ * EL3 from there would trample the original ESR.
+ */
+ mrs x4, scr_el3
+ mrs x5, esr_el3
+ stp x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+
+ /*
+ * Setup rest of arguments, and call platform External Abort handler.
+ *
+ * x0: EA reason (already in place)
+ * x1: Exception syndrome (already in place).
+ * x2: Cookie (unused for now).
+ * x3: Context pointer.
+ * x4: Flags (security state from SCR for now).
+ */
+ mov x2, xzr
+ mov x3, sp
+ ubfx x4, x4, #0, #1
+
+ /* Switch to runtime stack */
+ ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
+ msr spsel, #0
+ mov sp, x5
+
+ mov x29, x30
+#if ENABLE_ASSERTIONS
+ /* Stash the stack pointer */
+ mov x28, sp
+#endif
+ bl plat_ea_handler
+
+#if ENABLE_ASSERTIONS
+ /*
+ * Error handling flows might involve long jumps; so upon returning from
+ * the platform error handler, validate that the we've completely
+ * unwound the stack.
+ */
+ mov x27, sp
+ cmp x28, x27
+ ASM_ASSERT(eq)
+#endif
+
+ /* Make SP point to context */
+ msr spsel, #1
+
+ /* Restore EL3 state and ESR */
+ ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
+ msr spsr_el3, x1
+ msr elr_el3, x2
+
+ /* Restore ESR_EL3 and SCR_EL3 */
+ ldp x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
+ msr scr_el3, x3
+ msr esr_el3, x4
+
+#if ENABLE_ASSERTIONS
+ cmp x4, xzr
+ ASM_ASSERT(ne)
+#endif
+
+ /* Clear ESR storage */
+ str xzr, [sp, #CTX_EL3STATE_OFFSET + CTX_ESR_EL3]
+
+ ret x29
+endfunc ea_proceed
diff --git a/bl31/aarch64/runtime_exceptions.S b/bl31/aarch64/runtime_exceptions.S
index 12f9f109b..54db6814d 100644
--- a/bl31/aarch64/runtime_exceptions.S
+++ b/bl31/aarch64/runtime_exceptions.S
@@ -66,9 +66,7 @@
/* Save GP registers and restore them afterwards */
bl save_gp_registers
- mov x0, #ERROR_EA_ESB
- mrs x1, DISR_EL1
- bl delegate_ea
+ bl handle_lower_el_ea_esb
bl restore_gp_registers
1:
@@ -80,27 +78,6 @@
#endif
.endm
- /*
- * Handle External Abort by delegating to the platform's EA handler.
- * Once the platform handler returns, the macro exits EL3 and returns to
- * where the abort was taken from.
- *
- * This macro assumes that x30 is available for use.
- *
- * 'abort_type' is a constant passed to the platform handler, indicating
- * the cause of the External Abort.
- */
- .macro handle_ea abort_type
- /* Save GP registers */
- bl save_gp_registers
-
- /* Setup exception class and syndrome arguments for platform handler */
- mov x0, \abort_type
- mrs x1, esr_el3
- adr x30, el3_exit
- b delegate_ea
- .endm
-
/* ---------------------------------------------------------------------
* This macro handles Synchronous exceptions.
* Only SMC exceptions are supported.
@@ -130,23 +107,9 @@
cmp x30, #EC_AARCH64_SMC
b.eq smc_handler64
- /* Check for I/D aborts from lower EL */
- cmp x30, #EC_IABORT_LOWER_EL
- b.eq 1f
-
- cmp x30, #EC_DABORT_LOWER_EL
- b.ne 2f
-
-1:
- /* Test for EA bit in the instruction syndrome */
- mrs x30, esr_el3
- tbz x30, #ESR_ISS_EABORT_EA_BIT, 2f
- handle_ea #ERROR_EA_SYNC
-
-2:
- /* Other kinds of synchronous exceptions are not handled */
+ /* Synchronous exceptions other than the above are assumed to be EA */
ldr x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
- b report_unhandled_exception
+ b enter_lower_el_sync_ea
.endm
@@ -250,7 +213,7 @@ end_vector_entry fiq_sp_el0
vector_entry serror_sp_el0
- b report_unhandled_exception
+ no_ret plat_handle_el3_ea
end_vector_entry serror_sp_el0
/* ---------------------------------------------------------------------
@@ -276,7 +239,7 @@ vector_entry fiq_sp_elx
end_vector_entry fiq_sp_elx
vector_entry serror_sp_elx
- b report_unhandled_exception
+ no_ret plat_handle_el3_ea
end_vector_entry serror_sp_elx
/* ---------------------------------------------------------------------
@@ -306,13 +269,7 @@ end_vector_entry fiq_aarch64
vector_entry serror_aarch64
msr daifclr, #DAIF_ABT_BIT
-
- /*
- * Explicitly save x30 so as to free up a register and to enable
- * branching
- */
- str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
- handle_ea #ERROR_EA_ASYNC
+ b enter_lower_el_async_ea
end_vector_entry serror_aarch64
/* ---------------------------------------------------------------------
@@ -342,13 +299,7 @@ end_vector_entry fiq_aarch32
vector_entry serror_aarch32
msr daifclr, #DAIF_ABT_BIT
-
- /*
- * Explicitly save x30 so as to free up a register and to enable
- * branching
- */
- str x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
- handle_ea #ERROR_EA_ASYNC
+ b enter_lower_el_async_ea
end_vector_entry serror_aarch32
@@ -525,62 +476,3 @@ rt_svc_fw_critical_error:
msr spsel, #1
no_ret report_unhandled_exception
endfunc smc_handler
-
-/*
- * Delegate External Abort handling to platform's EA handler. This function
- * assumes that all GP registers have been saved by the caller.
- *
- * x0: EA reason
- * x1: EA syndrome
- */
-func delegate_ea
- /* Save EL3 state */
- mrs x2, spsr_el3
- mrs x3, elr_el3
- stp x2, x3, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
-
- /*
- * Save ESR as handling might involve lower ELs, and returning back to
- * EL3 from there would trample the original ESR.
- */
- mrs x4, scr_el3
- mrs x5, esr_el3
- stp x4, x5, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
-
- /*
- * Setup rest of arguments, and call platform External Abort handler.
- *
- * x0: EA reason (already in place)
- * x1: Exception syndrome (already in place).
- * x2: Cookie (unused for now).
- * x3: Context pointer.
- * x4: Flags (security state from SCR for now).
- */
- mov x2, xzr
- mov x3, sp
- ubfx x4, x4, #0, #1
-
- /* Switch to runtime stack */
- ldr x5, [sp, #CTX_EL3STATE_OFFSET + CTX_RUNTIME_SP]
- msr spsel, #0
- mov sp, x5
-
- mov x29, x30
- bl plat_ea_handler
- mov x30, x29
-
- /* Make SP point to context */
- msr spsel, #1
-
- /* Restore EL3 state */
- ldp x1, x2, [sp, #CTX_EL3STATE_OFFSET + CTX_SPSR_EL3]
- msr spsr_el3, x1
- msr elr_el3, x2
-
- /* Restore ESR_EL3 and SCR_EL3 */
- ldp x3, x4, [sp, #CTX_EL3STATE_OFFSET + CTX_SCR_EL3]
- msr scr_el3, x3
- msr esr_el3, x4
-
- ret
-endfunc delegate_ea
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index 307ddab69..77779548f 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -19,10 +19,12 @@ BL31_SOURCES += bl31/bl31_main.c \
bl31/interrupt_mgmt.c \
bl31/aarch64/bl31_entrypoint.S \
bl31/aarch64/crash_reporting.S \
+ bl31/aarch64/ea_delegate.S \
bl31/aarch64/runtime_exceptions.S \
bl31/bl31_context_mgmt.c \
common/runtime_svc.c \
lib/aarch64/setjmp.S \
+ lib/cpus/aarch64/dsu_helpers.S \
plat/common/aarch64/platform_mp_stack.S \
services/arm_arch_svc/arm_arch_svc_setup.c \
services/std_svc/std_svc_setup.c \
@@ -62,6 +64,10 @@ ifeq (${ENABLE_SVE_FOR_NS},1)
BL31_SOURCES += lib/extensions/sve/sve.c
endif
+ifeq (${ENABLE_MPAM_FOR_LOWER_ELS},1)
+BL31_SOURCES += lib/extensions/mpam/mpam.c
+endif
+
ifeq (${WORKAROUND_CVE_2017_5715},1)
BL31_SOURCES += lib/cpus/aarch64/wa_cve_2017_5715_bpiall.S \
lib/cpus/aarch64/wa_cve_2017_5715_mmu.S
diff --git a/bl31/bl31_main.c b/bl31/bl31_main.c
index 066474124..650181ddc 100644
--- a/bl31/bl31_main.c
+++ b/bl31/bl31_main.c
@@ -103,9 +103,14 @@ void bl31_main(void)
/*
* If SPD had registerd an init hook, invoke it.
*/
- if (bl32_init) {
+ if (bl32_init != NULL) {
INFO("BL31: Initializing BL32\n");
- (*bl32_init)();
+
+ int32_t rc = (*bl32_init)();
+
+ if (rc != 0) {
+ ERROR("BL31: BL32 initialization failed (rc = %d)", rc);
+ }
}
/*
* We are ready to enter the next EL. Prepare entry into the image
@@ -167,7 +172,7 @@ void bl31_prepare_next_image_entry(void)
/* Program EL3 registers to enable entry into the next EL */
next_image_info = bl31_plat_get_next_image_ep_info(image_type);
- assert(next_image_info);
+ assert(next_image_info != NULL);
assert(image_type == GET_SECURITY_STATE(next_image_info->h.attr));
INFO("BL31: Preparing for EL3 exit to %s world\n",
diff --git a/bl31/ehf.c b/bl31/ehf.c
index 8673564f2..3d6d674bf 100644
--- a/bl31/ehf.c
+++ b/bl31/ehf.c
@@ -18,6 +18,7 @@
#include <interrupt_mgmt.h>
#include <platform.h>
#include <pubsub_events.h>
+#include <stdbool.h>
/* Output EHF logs as verbose */
#define EHF_LOG(...) VERBOSE("EHF: " __VA_ARGS__)
@@ -26,43 +27,44 @@
/* For a valid handler, return the actual function pointer; otherwise, 0. */
#define RAW_HANDLER(h) \
- ((ehf_handler_t) ((h & _EHF_PRI_VALID) ? (h & ~_EHF_PRI_VALID) : 0))
+ ((ehf_handler_t) ((((h) & EHF_PRI_VALID_) != 0U) ? \
+ ((h) & ~EHF_PRI_VALID_) : 0U))
-#define PRI_BIT(idx) (((ehf_pri_bits_t) 1) << idx)
+#define PRI_BIT(idx) (((ehf_pri_bits_t) 1u) << (idx))
/*
* Convert index into secure priority using the platform-defined priority bits
* field.
*/
#define IDX_TO_PRI(idx) \
- ((idx << (7 - exception_data.pri_bits)) & 0x7f)
+ ((((unsigned) idx) << (7u - exception_data.pri_bits)) & 0x7fU)
/* Check whether a given index is valid */
#define IS_IDX_VALID(idx) \
- ((exception_data.ehf_priorities[idx].ehf_handler & _EHF_PRI_VALID) != 0)
+ ((exception_data.ehf_priorities[idx].ehf_handler & EHF_PRI_VALID_) != 0U)
/* Returns whether given priority is in secure priority range */
-#define IS_PRI_SECURE(pri) ((pri & 0x80) == 0)
+#define IS_PRI_SECURE(pri) (((pri) & 0x80U) == 0U)
/* To be defined by the platform */
extern const ehf_priorities_t exception_data;
/* Translate priority to the index in the priority array */
-static int pri_to_idx(unsigned int priority)
+static unsigned int pri_to_idx(unsigned int priority)
{
- int idx;
+ unsigned int idx;
idx = EHF_PRI_TO_IDX(priority, exception_data.pri_bits);
- assert((idx >= 0) && (idx < exception_data.num_priorities));
+ assert(idx < exception_data.num_priorities);
assert(IS_IDX_VALID(idx));
return idx;
}
/* Return whether there are outstanding priority activation */
-static int has_valid_pri_activations(pe_exc_data_t *pe_data)
+static bool has_valid_pri_activations(pe_exc_data_t *pe_data)
{
- return pe_data->active_pri_bits != 0;
+ return pe_data->active_pri_bits != 0U;
}
static pe_exc_data_t *this_cpu_data(void)
@@ -80,7 +82,7 @@ static int get_pe_highest_active_idx(pe_exc_data_t *pe_data)
return EHF_INVALID_IDX;
/* Current priority is the right-most bit */
- return __builtin_ctz(pe_data->active_pri_bits);
+ return (int) __builtin_ctz(pe_data->active_pri_bits);
}
/*
@@ -95,8 +97,8 @@ static int get_pe_highest_active_idx(pe_exc_data_t *pe_data)
*/
void ehf_activate_priority(unsigned int priority)
{
- int idx, cur_pri_idx;
- unsigned int old_mask, run_pri;
+ int cur_pri_idx;
+ unsigned int old_mask, run_pri, idx;
pe_exc_data_t *pe_data = this_cpu_data();
/*
@@ -118,7 +120,8 @@ void ehf_activate_priority(unsigned int priority)
*/
cur_pri_idx = get_pe_highest_active_idx(pe_data);
idx = pri_to_idx(priority);
- if ((cur_pri_idx != EHF_INVALID_IDX) && (idx >= cur_pri_idx)) {
+ if ((cur_pri_idx != EHF_INVALID_IDX) &&
+ (idx >= ((unsigned int) cur_pri_idx))) {
ERROR("Activation priority mismatch: req=0x%x current=0x%x\n",
priority, IDX_TO_PRI(cur_pri_idx));
panic();
@@ -144,7 +147,7 @@ void ehf_activate_priority(unsigned int priority)
* restored after the last deactivation.
*/
if (cur_pri_idx == EHF_INVALID_IDX)
- pe_data->init_pri_mask = old_mask;
+ pe_data->init_pri_mask = (uint8_t) old_mask;
EHF_LOG("activate prio=%d\n", get_pe_highest_active_idx(pe_data));
}
@@ -161,9 +164,9 @@ void ehf_activate_priority(unsigned int priority)
*/
void ehf_deactivate_priority(unsigned int priority)
{
- int idx, cur_pri_idx;
+ int cur_pri_idx;
pe_exc_data_t *pe_data = this_cpu_data();
- unsigned int old_mask, run_pri;
+ unsigned int old_mask, run_pri, idx;
/*
* Query interrupt controller for the running priority, or idle priority
@@ -184,21 +187,22 @@ void ehf_deactivate_priority(unsigned int priority)
*/
cur_pri_idx = get_pe_highest_active_idx(pe_data);
idx = pri_to_idx(priority);
- if ((cur_pri_idx == EHF_INVALID_IDX) || (idx != cur_pri_idx)) {
+ if ((cur_pri_idx == EHF_INVALID_IDX) ||
+ (idx != ((unsigned int) cur_pri_idx))) {
ERROR("Deactivation priority mismatch: req=0x%x current=0x%x\n",
priority, IDX_TO_PRI(cur_pri_idx));
panic();
}
/* Clear bit corresponding to highest priority */
- pe_data->active_pri_bits &= (pe_data->active_pri_bits - 1);
+ pe_data->active_pri_bits &= (pe_data->active_pri_bits - 1u);
/*
* Restore priority mask corresponding to the next priority, or the
* one stashed earlier if there are no more to deactivate.
*/
- idx = get_pe_highest_active_idx(pe_data);
- if (idx == EHF_INVALID_IDX)
+ cur_pri_idx = get_pe_highest_active_idx(pe_data);
+ if (cur_pri_idx == EHF_INVALID_IDX)
old_mask = plat_ic_set_priority_mask(pe_data->init_pri_mask);
else
old_mask = plat_ic_set_priority_mask(priority);
@@ -231,16 +235,16 @@ static void *ehf_exited_normal_world(const void *arg)
/* If the running priority is in the secure range, do nothing */
run_pri = plat_ic_get_running_priority();
if (IS_PRI_SECURE(run_pri))
- return 0;
+ return NULL;
/* Do nothing if there are explicit activations */
if (has_valid_pri_activations(pe_data))
- return 0;
+ return NULL;
- assert(pe_data->ns_pri_mask == 0);
+ assert(pe_data->ns_pri_mask == 0u);
pe_data->ns_pri_mask =
- plat_ic_set_priority_mask(GIC_HIGHEST_NS_PRIORITY);
+ (uint8_t) plat_ic_set_priority_mask(GIC_HIGHEST_NS_PRIORITY);
/* The previous Priority Mask is not expected to be in secure range */
if (IS_PRI_SECURE(pe_data->ns_pri_mask)) {
@@ -252,7 +256,7 @@ static void *ehf_exited_normal_world(const void *arg)
EHF_LOG("Priority Mask: 0x%x => 0x%x\n", pe_data->ns_pri_mask,
GIC_HIGHEST_NS_PRIORITY);
- return 0;
+ return NULL;
}
/*
@@ -274,18 +278,18 @@ static void *ehf_entering_normal_world(const void *arg)
/* If the running priority is in the secure range, do nothing */
run_pri = plat_ic_get_running_priority();
if (IS_PRI_SECURE(run_pri))
- return 0;
+ return NULL;
/*
* If there are explicit activations, do nothing. The Priority Mask will
* be restored upon the last deactivation.
*/
if (has_valid_pri_activations(pe_data))
- return 0;
+ return NULL;
/* Do nothing if we don't have a valid Priority Mask to restore */
- if (pe_data->ns_pri_mask == 0)
- return 0;
+ if (pe_data->ns_pri_mask == 0U)
+ return NULL;
old_pmr = plat_ic_set_priority_mask(pe_data->ns_pri_mask);
@@ -304,7 +308,7 @@ static void *ehf_entering_normal_world(const void *arg)
pe_data->ns_pri_mask = 0;
- return 0;
+ return NULL;
}
/*
@@ -328,7 +332,7 @@ void ehf_allow_ns_preemption(uint64_t preempt_ret_code)
* We should have been notified earlier of entering secure world, and
* therefore have stashed the Non-secure priority mask.
*/
- assert(pe_data->ns_pri_mask != 0);
+ assert(pe_data->ns_pri_mask != 0U);
/* Make sure no priority levels are active when requesting this */
if (has_valid_pri_activations(pe_data)) {
@@ -343,7 +347,7 @@ void ehf_allow_ns_preemption(uint64_t preempt_ret_code)
* to populate it, the caller would find the correct return value.
*/
ns_ctx = cm_get_context(NON_SECURE);
- assert(ns_ctx);
+ assert(ns_ctx != NULL);
write_ctx_reg(get_gpregs_ctx(ns_ctx), CTX_GPREG_X0, preempt_ret_code);
old_pmr = plat_ic_set_priority_mask(pe_data->ns_pri_mask);
@@ -376,7 +380,7 @@ unsigned int ehf_is_ns_preemption_allowed(void)
*/
if (has_valid_pri_activations(pe_data))
return 0;
- if (pe_data->ns_pri_mask != 0)
+ if (pe_data->ns_pri_mask != 0U)
return 0;
return 1;
@@ -388,7 +392,9 @@ unsigned int ehf_is_ns_preemption_allowed(void)
static uint64_t ehf_el3_interrupt_handler(uint32_t id, uint32_t flags,
void *handle, void *cookie)
{
- int pri, idx, intr, intr_raw, ret = 0;
+ int ret = 0;
+ uint32_t intr_raw;
+ unsigned int intr, pri, idx;
ehf_handler_t handler;
/*
@@ -425,8 +431,9 @@ static uint64_t ehf_el3_interrupt_handler(uint32_t id, uint32_t flags,
/* Validate priority */
assert(pri == IDX_TO_PRI(idx));
- handler = RAW_HANDLER(exception_data.ehf_priorities[idx].ehf_handler);
- if (!handler) {
+ handler = (ehf_handler_t) RAW_HANDLER(
+ exception_data.ehf_priorities[idx].ehf_handler);
+ if (handler == NULL) {
ERROR("No EL3 exception handler for priority 0x%x\n",
IDX_TO_PRI(idx));
panic();
@@ -438,7 +445,7 @@ static uint64_t ehf_el3_interrupt_handler(uint32_t id, uint32_t flags,
*/
ret = handler(intr_raw, flags, handle, cookie);
- return ret;
+ return (uint64_t) ret;
}
/*
@@ -450,21 +457,22 @@ void ehf_init(void)
int ret __unused;
/* Ensure EL3 interrupts are supported */
- assert(plat_ic_has_interrupt_type(INTR_TYPE_EL3));
+ assert(plat_ic_has_interrupt_type(INTR_TYPE_EL3) != 0);
/*
* Make sure that priority water mark has enough bits to represent the
* whole priority array.
*/
- assert(exception_data.num_priorities <= (sizeof(ehf_pri_bits_t) * 8));
+ assert(exception_data.num_priorities <= (sizeof(ehf_pri_bits_t) * 8U));
- assert(exception_data.ehf_priorities);
+ assert(exception_data.ehf_priorities != NULL);
/*
* Bit 7 of GIC priority must be 0 for secure interrupts. This means
* platforms must use at least 1 of the remaining 7 bits.
*/
- assert((exception_data.pri_bits >= 1) || (exception_data.pri_bits < 8));
+ assert((exception_data.pri_bits >= 1U) ||
+ (exception_data.pri_bits < 8U));
/* Route EL3 interrupts when in Secure and Non-secure. */
set_interrupt_rm_flag(flags, NON_SECURE);
@@ -484,13 +492,13 @@ void ehf_init(void)
*/
void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler)
{
- int idx;
+ unsigned int idx;
/* Sanity check for handler */
assert(handler != NULL);
/* Handler ought to be 4-byte aligned */
- assert((((uintptr_t) handler) & 3) == 0);
+ assert((((uintptr_t) handler) & 3U) == 0U);
/* Ensure we register for valid priority */
idx = pri_to_idx(pri);
@@ -498,7 +506,7 @@ void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler)
assert(IDX_TO_PRI(idx) == pri);
/* Return failure if a handler was already registered */
- if (exception_data.ehf_priorities[idx].ehf_handler != _EHF_NO_HANDLER) {
+ if (exception_data.ehf_priorities[idx].ehf_handler != EHF_NO_HANDLER_) {
ERROR("Handler already registered for priority 0x%x\n", pri);
panic();
}
@@ -508,7 +516,7 @@ void ehf_register_priority_handler(unsigned int pri, ehf_handler_t handler)
* is 4-byte aligned, which is usually the case.
*/
exception_data.ehf_priorities[idx].ehf_handler =
- (((uintptr_t) handler) | _EHF_PRI_VALID);
+ (((uintptr_t) handler) | EHF_PRI_VALID_);
EHF_LOG("register pri=0x%x handler=%p\n", pri, handler);
}
diff --git a/bl31/interrupt_mgmt.c b/bl31/interrupt_mgmt.c
index b885a66ad..0df50b6d2 100644
--- a/bl31/interrupt_mgmt.c
+++ b/bl31/interrupt_mgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,6 @@
#include <errno.h>
#include <interrupt_mgmt.h>
#include <platform.h>
-#include <stdio.h>
/*******************************************************************************
* Local structure and corresponding array to keep track of the state of the
@@ -47,8 +46,8 @@ static intr_type_desc_t intr_type_descs[MAX_INTR_TYPES];
******************************************************************************/
static int32_t validate_interrupt_type(uint32_t type)
{
- if (type == INTR_TYPE_S_EL1 || type == INTR_TYPE_NS ||
- type == INTR_TYPE_EL3)
+ if ((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_NS) ||
+ (type == INTR_TYPE_EL3))
return 0;
return -EINVAL;
@@ -59,17 +58,16 @@ static int32_t validate_interrupt_type(uint32_t type)
******************************************************************************/
static int32_t validate_routing_model(uint32_t type, uint32_t flags)
{
- flags >>= INTR_RM_FLAGS_SHIFT;
- flags &= INTR_RM_FLAGS_MASK;
+ uint32_t rm_flags = (flags >> INTR_RM_FLAGS_SHIFT) & INTR_RM_FLAGS_MASK;
if (type == INTR_TYPE_S_EL1)
- return validate_sel1_interrupt_rm(flags);
+ return validate_sel1_interrupt_rm(rm_flags);
if (type == INTR_TYPE_NS)
- return validate_ns_interrupt_rm(flags);
+ return validate_ns_interrupt_rm(rm_flags);
if (type == INTR_TYPE_EL3)
- return validate_el3_interrupt_rm(flags);
+ return validate_el3_interrupt_rm(rm_flags);
return -EINVAL;
}
@@ -106,10 +104,12 @@ static void set_scr_el3_from_rm(uint32_t type,
bit_pos = plat_interrupt_type_to_line(type, security_state);
intr_type_descs[type].scr_el3[security_state] = flag << bit_pos;
- /* Update scr_el3 only if there is a context available. If not, it
+ /*
+ * Update scr_el3 only if there is a context available. If not, it
* will be updated later during context initialization which will obtain
- * the scr_el3 value to be used via get_scr_el3_from_routing_model() */
- if (cm_get_context(security_state))
+ * the scr_el3 value to be used via get_scr_el3_from_routing_model()
+ */
+ if (cm_get_context(security_state) != NULL)
cm_write_scr_el3_bit(security_state, bit_pos, flag);
}
@@ -124,11 +124,11 @@ int32_t set_routing_model(uint32_t type, uint32_t flags)
int32_t rc;
rc = validate_interrupt_type(type);
- if (rc)
+ if (rc != 0)
return rc;
rc = validate_routing_model(type, flags);
- if (rc)
+ if (rc != 0)
return rc;
/* Update the routing model in internal data structures */
@@ -149,7 +149,7 @@ int disable_intr_rm_local(uint32_t type, uint32_t security_state)
{
uint32_t bit_pos, flag;
- assert(intr_type_descs[type].handler);
+ assert(intr_type_descs[type].handler != NULL);
flag = get_interrupt_rm_flag(INTR_DEFAULT_RM, security_state);
@@ -167,7 +167,7 @@ int enable_intr_rm_local(uint32_t type, uint32_t security_state)
{
uint32_t bit_pos, flag;
- assert(intr_type_descs[type].handler);
+ assert(intr_type_descs[type].handler != NULL);
flag = get_interrupt_rm_flag(intr_type_descs[type].flags,
security_state);
@@ -190,19 +190,19 @@ int32_t register_interrupt_type_handler(uint32_t type,
int32_t rc;
/* Validate the 'handler' parameter */
- if (!handler)
+ if (handler == NULL)
return -EINVAL;
/* Validate the 'flags' parameter */
- if (flags & INTR_TYPE_FLAGS_MASK)
+ if ((flags & INTR_TYPE_FLAGS_MASK) != 0U)
return -EINVAL;
/* Check if a handler has already been registered */
- if (intr_type_descs[type].handler)
+ if (intr_type_descs[type].handler != NULL)
return -EALREADY;
rc = set_routing_model(type, flags);
- if (rc)
+ if (rc != 0)
return rc;
/* Save the handler */
@@ -218,7 +218,7 @@ int32_t register_interrupt_type_handler(uint32_t type,
******************************************************************************/
interrupt_type_handler_t get_interrupt_type_handler(uint32_t type)
{
- if (validate_interrupt_type(type))
+ if (validate_interrupt_type(type) != 0)
return NULL;
return intr_type_descs[type].handler;
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index f06a48bfe..59e88eb9f 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -21,8 +21,8 @@
#include <stddef.h>
#include <stdint.h>
#include <std_svc.h>
+#include <stdint.h>
#include <string.h>
-#include <types.h>
#include <utils.h>
#include "sp_min_private.h"
diff --git a/common/backtrace.c b/common/backtrace.c
new file mode 100644
index 000000000..a91d06573
--- /dev/null
+++ b/common/backtrace.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/* Maximum number of entries in the backtrace to display */
+#define UNWIND_LIMIT 20U
+
+/*
+ * If -fno-omit-frame-pointer is used:
+ *
+ * - AArch64: The AAPCS defines the format of the frame records and mandates the
+ * usage of r29 as frame pointer.
+ *
+ * - AArch32: The format of the frame records is not defined in the AAPCS.
+ * However, at least GCC and Clang use the same format. When they are forced
+ * to only generate A32 code (with -marm), they use r11 as frame pointer and a
+ * similar format as in AArch64. If interworking with T32 is enabled, the
+ * frame pointer is r7 and the format is different. This is not supported by
+ * this implementation of backtrace, so it is needed to use -marm.
+ */
+
+/* Frame records form a linked list in the stack */
+struct frame_record {
+ /* Previous frame record in the list */
+ struct frame_record *parent;
+ /* Return address of the function at this level */
+ uintptr_t return_addr;
+};
+
+static const char *get_el_str(unsigned int el)
+{
+ if (el == 3U) {
+ return "EL3";
+ } else if (el == 2U) {
+ return "EL2";
+ } else {
+ return "S-EL1";
+ }
+}
+
+/*
+ * Returns true if the address points to a virtual address that can be read at
+ * the current EL, false otherwise.
+ */
+#ifdef AARCH64
+static bool is_address_readable(uintptr_t addr)
+{
+ unsigned int el = get_current_el();
+
+ if (el == 3U) {
+ ats1e3r(addr);
+ } else if (el == 2U) {
+ ats1e2r(addr);
+ } else {
+ ats1e1r(addr);
+ }
+
+ isb();
+
+ /* If PAR.F == 1 the address translation was aborted. */
+ if ((read_par_el1() & PAR_F_MASK) != 0U)
+ return false;
+
+ return true;
+}
+#else /* if AARCH32 */
+static bool is_address_readable(uintptr_t addr)
+{
+ unsigned int el = get_current_el();
+
+ if (el == 3U) {
+ write_ats1cpr(addr);
+ } else if (el == 2U) {
+ write_ats1hr(addr);
+ } else {
+ write_ats1cpr(addr);
+ }
+
+ isb();
+
+ /* If PAR.F == 1 the address translation was aborted. */
+ if ((read64_par() & PAR_F_MASK) != 0U)
+ return false;
+
+ return true;
+}
+#endif
+
+/*
+ * Returns true if all the bytes in a given object are in mapped memory and an
+ * LDR using this pointer would succeed, false otherwise.
+ */
+static bool is_valid_object(uintptr_t addr, size_t size)
+{
+ assert(size > 0U);
+
+ if (addr == 0U)
+ return false;
+
+ /* Detect overflows */
+ if ((addr + size) < addr)
+ return false;
+
+ /* A pointer not aligned properly could trigger an alignment fault. */
+ if ((addr & (sizeof(uintptr_t) - 1U)) != 0U)
+ return false;
+
+ /* Check that all the object is readable */
+ for (size_t i = 0; i < size; i++) {
+ if (!is_address_readable(addr + i))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Returns true if the specified address is correctly aligned and points to a
+ * valid memory region.
+ */
+static bool is_valid_jump_address(uintptr_t addr)
+{
+ if (addr == 0U)
+ return false;
+
+ /* Check alignment. Both A64 and A32 use 32-bit opcodes */
+ if ((addr & (sizeof(uint32_t) - 1U)) != 0U)
+ return false;
+
+ if (!is_address_readable(addr))
+ return false;
+
+ return true;
+}
+
+/*
+ * Returns true if the pointer points at a valid frame record, false otherwise.
+ */
+static bool is_valid_frame_record(struct frame_record *fr)
+{
+ return is_valid_object((uintptr_t)fr, sizeof(struct frame_record));
+}
+
+/*
+ * Adjust the frame-pointer-register value by 4 bytes on AArch32 to have the
+ * same layout as AArch64.
+ */
+static struct frame_record *adjust_frame_record(struct frame_record *fr)
+{
+#ifdef AARCH64
+ return fr;
+#else
+ return (struct frame_record *)((uintptr_t)fr - 4U);
+#endif
+}
+
+static void unwind_stack(struct frame_record *fr, uintptr_t current_pc,
+ uintptr_t link_register)
+{
+ uintptr_t call_site;
+ static const char *backtrace_str = "%u: %s: 0x%lx\n";
+ const char *el_str = get_el_str(get_current_el());
+
+ if (!is_valid_frame_record(fr)) {
+ printf("ERROR: Corrupted frame pointer (frame record address = %p)\n",
+ fr);
+ return;
+ }
+
+ if (fr->return_addr != link_register) {
+ printf("ERROR: Corrupted stack (frame record address = %p)\n",
+ fr);
+ return;
+ }
+
+ /* The level 0 of the backtrace is the current backtrace function */
+ printf(backtrace_str, 0U, el_str, current_pc);
+
+ /*
+ * The last frame record pointer in the linked list at the beginning of
+ * the stack should be NULL unless stack is corrupted.
+ */
+ for (unsigned int i = 1U; i < UNWIND_LIMIT; i++) {
+ /* If an invalid frame record is found, exit. */
+ if (!is_valid_frame_record(fr))
+ return;
+ /*
+ * A32 and A64 are fixed length so the address from where the
+ * call was made is the instruction before the return address,
+ * which is always 4 bytes before it.
+ */
+ call_site = fr->return_addr - 4U;
+
+ /*
+ * If the address is invalid it means that the frame record is
+ * probably corrupted.
+ */
+ if (!is_valid_jump_address(call_site))
+ return;
+
+ printf(backtrace_str, i, el_str, call_site);
+
+ fr = adjust_frame_record(fr->parent);
+ }
+
+ printf("ERROR: Max backtrace depth reached\n");
+}
+
+/*
+ * Display a backtrace. The cookie string parameter is displayed along the
+ * trace to help filter the log messages.
+ *
+ * Many things can prevent displaying the expected backtrace. For example,
+ * compiler optimizations can use a branch instead of branch with link when it
+ * detects a tail call. The backtrace level for this caller will not be
+ * displayed, as it does not appear in the call stack anymore. Also, assembly
+ * functions will not be displayed unless they setup AAPCS compliant frame
+ * records on AArch64 and compliant with GCC-specific frame record format on
+ * AArch32.
+ *
+ * Usage of the trace: addr2line can be used to map the addresses to function
+ * and source code location when given the ELF file compiled with debug
+ * information. The "-i" flag is highly recommended to improve display of
+ * inlined function. The *.dump files generated when buildidng each image can
+ * also be used.
+ *
+ * WARNING: In case of corrupted stack, this function could display security
+ * sensitive information past the beginning of the stack so it must not be used
+ * in production build. This function is only compiled in when ENABLE_BACKTRACE
+ * is set to 1.
+ */
+void backtrace(const char *cookie)
+{
+ uintptr_t return_address = (uintptr_t)__builtin_return_address(0U);
+ struct frame_record *fr = __builtin_frame_address(0U);
+
+ /* Printing the backtrace may crash the system, flush before starting */
+ (void)console_flush();
+
+ fr = adjust_frame_record(fr);
+
+ printf("BACKTRACE: START: %s\n", cookie);
+
+ unwind_stack(fr, (uintptr_t)&backtrace, return_address);
+
+ printf("BACKTRACE: END: %s\n", cookie);
+}
diff --git a/common/runtime_svc.c b/common/runtime_svc.c
index f997c74a0..ad564f566 100644
--- a/common/runtime_svc.c
+++ b/common/runtime_svc.c
@@ -20,7 +20,6 @@
* 'rt_svc_descs' array which contains the SMC handler.
******************************************************************************/
uint8_t rt_svc_descs_indices[MAX_RT_SVCS];
-static rt_svc_desc_t *rt_svc_descs;
#define RT_SVC_DECS_NUM ((RT_SVC_DESCS_END - RT_SVC_DESCS_START)\
/ sizeof(rt_svc_desc_t))
@@ -98,6 +97,7 @@ void runtime_svc_init(void)
{
int rc = 0;
unsigned int index, start_idx, end_idx;
+ rt_svc_desc_t *rt_svc_descs;
/* Assert the number of descriptors detected are less than maximum indices */
assert((RT_SVC_DESCS_END >= RT_SVC_DESCS_START) &&
diff --git a/common/tf_log.c b/common/tf_log.c
index 54c0a4363..422959f60 100644
--- a/common/tf_log.c
+++ b/common/tf_log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,19 +28,21 @@ void tf_log(const char *fmt, ...)
log_level = fmt[0];
/* Verify that log_level is one of LOG_MARKER_* macro defined in debug.h */
- assert(log_level && log_level <= LOG_LEVEL_VERBOSE);
- assert(log_level % 10 == 0);
+ assert((log_level > 0U) && (log_level <= LOG_LEVEL_VERBOSE));
+ assert((log_level % 10U) == 0U);
if (log_level > max_log_level)
return;
prefix_str = plat_log_get_prefix(log_level);
- if (prefix_str != NULL)
- tf_string_print(prefix_str);
+ while (*prefix_str != '\0') {
+ (void)putchar(*prefix_str);
+ prefix_str++;
+ }
va_start(args, fmt);
- tf_vprintf(fmt+1, args);
+ (void)vprintf(fmt + 1, args);
va_end(args);
}
@@ -52,10 +54,9 @@ void tf_log(const char *fmt, ...)
void tf_log_set_max_level(unsigned int log_level)
{
assert(log_level <= LOG_LEVEL_VERBOSE);
- assert((log_level % 10) == 0);
+ assert((log_level % 10U) == 0U);
/* Cap log_level to the compile time maximum. */
- if (log_level < LOG_LEVEL)
+ if (log_level < (unsigned int)LOG_LEVEL)
max_log_level = log_level;
-
}
diff --git a/docs/cpu-specific-build-macros.rst b/docs/cpu-specific-build-macros.rst
index c11f64039..151c99e98 100644
--- a/docs/cpu-specific-build-macros.rst
+++ b/docs/cpu-specific-build-macros.rst
@@ -68,10 +68,10 @@ In the current implementation, a platform which has more than 1 variant
with different revisions of a processor has no runtime mechanism available
for it to specify which errata workarounds should be enabled or not.
-The value of the build flags are 0 by default, that is, disabled. Any other
-value will enable it.
+The value of the build flags is 0 by default, that is, disabled. A value of 1
+will enable it.
-For Cortex-A53, following errata build flags are defined :
+For Cortex-A53, the following errata build flags are defined :
- ``ERRATA_A53_826319``: This applies errata 826319 workaround to Cortex-A53
CPU. This needs to be enabled only for revision <= r0p2 of the CPU.
@@ -97,7 +97,7 @@ For Cortex-A53, following errata build flags are defined :
Earlier revisions of the CPU have other errata which require the same
workaround in software, so they should be covered anyway.
-For Cortex-A57, following errata build flags are defined :
+For Cortex-A57, the following errata build flags are defined :
- ``ERRATA_A57_806969``: This applies errata 806969 workaround to Cortex-A57
CPU. This needs to be enabled only for revision r0p0 of the CPU.
@@ -127,11 +127,33 @@ For Cortex-A57, following errata build flags are defined :
CPU. This needs to be enabled only for revision <= r1p3 of the CPU.
-For Cortex-A72, following errata build flags are defined :
+For Cortex-A72, the following errata build flags are defined :
- ``ERRATA_A72_859971``: This applies errata 859971 workaround to Cortex-A72
CPU. This needs to be enabled only for revision <= r0p3 of the CPU.
+DSU Errata Workarounds
+----------------------
+
+Similar to CPU errata, TF-A also implements workarounds for DSU (DynamIQ
+Shared Unit) errata. The DSU errata details can be found in the respective Arm
+documentation:
+
+- `Arm DSU Software Developers Errata Notice`_.
+
+Each erratum is identified by an ``ID``, as defined in the DSU errata notice
+document. Thus, the build flags which enable/disable the errata workarounds
+have the format ``ERRATA_DSU_<ID>``. The implementation and application logic
+of DSU errata workarounds are similar to `CPU errata workarounds`_.
+
+For DSU errata, the following build flags are defined:
+
+- ``ERRATA_DSU_936184``: This applies errata 936184 workaround for the
+ affected DSU configurations. This errata applies only for those DSUs that
+ contain the ACP interface **and** the DSU revision is older than r2p0 (on
+ r2p0 it is fixed). However, please note that this workaround results in
+ increased DSU power consumption on idle.
+
CPU Specific optimizations
--------------------------
@@ -171,3 +193,4 @@ architecture that can be enabled by the platform as desired.
.. _Cortex-A72 MPCore Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm012079/index.html
.. _Firmware Design guide: firmware-design.rst
.. _Cortex-A57 Software Optimization Guide: http://infocenter.arm.com/help/topic/com.arm.doc.uan0015b/Cortex_A57_Software_Optimization_Guide_external.pdf
+.. _Arm DSU Software Developers Errata Notice: http://infocenter.arm.com/help/topic/com.arm.doc.epm138168/index.html \ No newline at end of file
diff --git a/docs/marvell/build.txt b/docs/marvell/build.txt
new file mode 100644
index 000000000..63a40a8d8
--- /dev/null
+++ b/docs/marvell/build.txt
@@ -0,0 +1,181 @@
+TF-A Build Instructions
+======================
+
+This section describes how to compile the ARM Trusted Firmware (TF-A) project for Marvell's platforms.
+
+Build Instructions
+------------------
+(1) Set the cross compiler::
+
+ > export CROSS_COMPILE=/path/to/toolchain/aarch64-linux-gnu-
+
+(2) Set path for FIP images:
+
+ Set U-Boot image path (relatively to TF-A root or absolute path)::
+
+ > export BL33=path/to/u-boot.bin
+
+ For example: if U-Boot project (and its images) is located at ~/project/u-boot,
+ BL33 should be ~/project/u-boot/u-boot.bin
+
+ .. note::
+
+ u-boot.bin should be used and not u-boot-spl.bin
+
+ Set MSS/SCP image path (mandatory only for Armada80x0 and Aramada8xxy)::
+
+ > export SCP_BL2=path/to/mrvl_scp_bl2*.img
+
+(3) Armada-37x0 build requires WTP tools installation.
+
+ See below in the section "Tools Installation for Armada37x0 Builds".
+ Install ARM 32-bit cross compiler, which is required by building WTMI image for CM3::
+
+ > sudo apt-get install gcc-arm-linux-gnueabi
+
+(4) Clean previous build residuals (if any)::
+
+ > make distclean
+
+(5) Build TF-A:
+
+ There are several build options:
+
+ - DEBUG: default is without debug information (=0). in order to enable it use DEBUG=1
+
+ - LOG_LEVEL: defines the level of logging which will be purged to the default output port.
+
+ LOG_LEVEL_NONE 0
+ LOG_LEVEL_ERROR 10
+ LOG_LEVEL_NOTICE 20
+ LOG_LEVEL_WARNING 30
+ LOG_LEVEL_INFO 40
+ LOG_LEVEL_VERBOSE 50
+
+ - USE_COHERENT_MEM: This flag determines whether to include the coherent memory region in the
+ BL memory map or not.
+
+ -LLC_ENABLE: Flag defining the LLC (L3) cache state. The cache is enabled by default (LLC_ENABLE=1).
+
+ - MARVELL_SECURE_BOOT: build trusted(=1)/non trusted(=0) image, default is non trusted.
+
+ - BLE_PATH:
+ Points to BLE (Binary ROM extension) sources folder. Only required for A8K and A8K+ builds.
+ The parameter is optional, its default value is "ble".
+
+ - MV_DDR_PATH:
+ For A7/8K, use this parameter to point to mv_ddr driver sources to allow BLE build. For A37x0,
+ it is used for ddr_tool build.
+ Usage example: MV_DDR_PATH=path/to/mv_ddr
+ The parameter is optional for A7/8K, when this parameter is not set, the mv_ddr
+ sources are expected to be located at: drivers/marvell/mv_ddr. However, the parameter
+ is necessary for A37x0.
+
+ - DDR_TOPOLOGY: For Armada37x0 only, the DDR topology map index/name, default is 0.
+ Supported Options:
+ - DDR3 1CS (0): DB-88F3720-DDR3-Modular (512MB); EspressoBIN (512MB)
+ - DDR4 1CS (1): DB-88F3720-DDR4-Modular (512MB)
+ - DDR3 2CS (2): EspressoBIN (1GB)
+ - DDR4 2CS (3): DB-88F3720-DDR4-Modular (4GB)
+ - DDR3 1CS (4): DB-88F3720-DDR3-Modular (1GB)
+ - CUSTOMER (CUST): Customer board, DDR3 1CS 512MB
+
+ - CLOCKSPRESET: For Armada37x0 only, the clock tree configuration preset including CPU and DDR frequency,
+ default is CPU_800_DDR_800.
+ - CPU_600_DDR_600 - CPU at 600 MHz, DDR at 600 MHz
+ - CPU_800_DDR_800 - CPU at 800 MHz, DDR at 800 MHz
+ - CPU_1000_DDR_800 - CPU at 1000 MHz, DDR at 800 MHz
+ - CPU_1200_DDR_750 - CPU at 1200 MHz, DDR at 750 MHz
+
+ - BOOTDEV: For Armada37x0 only, the flash boot device, default is SPINOR,
+ Currently, Armada37x0 only supports SPINOR, SPINAND, EMMCNORM and SATA:
+
+ - SPINOR - SPI NOR flash boot
+ - SPINAND - SPI NAND flash boot
+ - EMMCNORM - eMMC Download Mode
+ Download boot loader or program code from eMMC flash into CM3 or CA53
+ Requires full initialization and command sequence
+ - SATA - SATA device boot
+
+ - PARTNUM: For Armada37x0 only, the boot partition number, default is 0. To boot from eMMC, the value
+ should be aligned with the parameter in U-Boot with name of CONFIG_SYS_MMC_ENV_PART, whose
+ value by default is 1.
+ For details about CONFIG_SYS_MMC_ENV_PART, please refer to the U-Boot build instructions.
+
+ - WTMI_IMG: For Armada37x0 only, the path of the WTMI image can point to an image which does
+ nothing, an image which supports EFUSE or a customized CM3 firmware binary. The default image
+ is wtmi.bin that built from sources in WTP folder, which is the next option. If the default
+ image is OK, then this option should be skipped.
+ - WTP: For Armada37x0 only, use this parameter to point to wtptools source code directory, which
+ can be found as a3700_utils.zip in the release.
+ Usage example: WTP=/path/to/a3700_utils
+
+ - CP_NUM: Total amount of CPs (South Bridge) chips wired to the interconnected APs.
+ When the parameter is omitted, the build is uses the default number of CPs equal to 2.
+ The parameter is valid for Armada 8K-plus SoC family (PLAT=a8xxy) and results in a build of images
+ suitable for a8xxY SoC, where "Y" is a number of connected CPs and "xx" is a number of CPU cores.
+ Valid values with CP_NUM is in a range of 0 to 8.
+ The CPs defined by this parameter are evenly distributed across interconnected APs that in turn
+ are dynamically detected. For instance, if the CP_NUM=6 and the TF-A detects 2 interconnected
+ APs, each AP assumed to have 3 attached CPs. With the same amount of APs and CP_NUM=3, the AP0
+ will have 2 CPs connected and AP1 - a just single CP.
+
+ For example, in order to build the image in debug mode with log level up to 'notice' level run::
+
+ > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 PLAT=<MARVELL_PLATFORM> all fip
+
+ And if we want to build a Armada37x0 image in debug mode with log level up to 'notice' level,
+ the image has the preset CPU at 1000 MHz, preset DDR3 at 800 MHz, the DDR topology of DDR3 2CS,
+ the image boot from SPI NOR flash partition 0, and the image is non trusted in WTP, the command
+ line is as following::
+
+ > make DEBUG=1 USE_COHERENT_MEM=0 LOG_LEVEL=20 SECURE=0 CLOCKSPRESET=CPU_1000_DDR_800 \
+ DDR_TOPOLOGY=2 BOOTDEV=SPINOR PARTNUM=0 PLAT=a3700 all fip
+
+ Supported MARVELL_PLATFORM are:
+ - a3700
+ - a70x0
+ - a70x0_amc (for AMC board)
+ - a70x0_cust (for customers)
+ - a80x0
+ - a80x0_mcbin (for MacciatoBin)
+
+Special Build Flags
+--------------------
+ - PLAT_RECOVERY_IMAGE_ENABLE: When set this option to enable secondary recovery function when build
+ atf. In order to build uart recovery image this operation should be disabled for a70x0 and a80x0
+ because of hardware limitation(boot from secondary image can interrupt uart recovery process).
+ This MACRO definition is set in plat/marvell/a8k/common/include/platform_def.h file
+
+(for more information about build options, please refer to section 'Summary of build options' in TF-A user-guide:
+ https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/user-guide.md)
+
+
+Build output
+-------------
+Marvell's TF-A compilation generates 7 files:
+ - ble.bin - BLe image
+ - bl1.bin - BL1 image
+ - bl2.bin - BL2 image
+ - bl31.bin - BL31 image
+ - fip.bin - FIP image (contains BL2, BL31 & BL33 (U-Boot) images)
+ - boot-image.bin - TF-A image (contains BL1 and FIP images)
+ - flash-image.bin - Image which contains boot-image.bin and SPL image; should be placed on the boot flash/device.
+
+
+Tools Installation for Armada37x0 Builds
+-----------------------------------------
+Install a cross GNU ARM tool chain for building the WTMI binary.
+Any cross GNU ARM tool chain that is able to build ARM Cortex M3 binaries
+is suitable.
+
+On Debian/Uboot hosts the default GNU ARM tool chain can be installed
+using the following command::
+
+ > sudo apt-get install gcc-arm-linux-gnueabi
+
+If required, the default tool chain prefix "arm-linux-gnueabi-" can be
+overwritten using the environment variable CROSS_CM3.
+Example for BASH shell::
+
+ > export CROSS_CM3=/opt/arm-cross/bin/arm-linux-gnueabi
diff --git a/docs/marvell/misc/mvebu-a8k-addr-map.txt b/docs/marvell/misc/mvebu-a8k-addr-map.txt
new file mode 100644
index 000000000..586e8b732
--- /dev/null
+++ b/docs/marvell/misc/mvebu-a8k-addr-map.txt
@@ -0,0 +1,47 @@
+Address decoding flow and address translation units of Marvell Armada 8K SoC family
+
++--------------------------------------------------------------------------------------------------+
+| +-------------+ +--------------+ |
+| | Memory +----- DRAM CS | |
+|+------------+ +-----------+ +-----------+ | Controller | +--------------+ |
+|| AP DMA | | | | | +-------------+ |
+|| SD/eMMC | | CA72 CPUs | | AP MSS | +-------------+ |
+|| MCI-0/1 | | | | | | Memory | |
+|+------+-----+ +--+--------+ +--------+--+ +------------+ | Controller | +-------------+ |
+| | | | | +----- Translaton | |AP | |
+| | | | | | +-------------+ |Configuration| |
+| | | +-----+ +-------------------------Space | |
+| | | +-------------+ | CCU | +-------------+ |
+| | | | MMU +---------+ Windows | +-----------+ +-------------+ |
+| | +-| translation | | Lookup +---- +--------- AP SPI | |
+| | +-------------+ | | | | +-------------+ |
+| | +-------------+ | | | IO | +-------------+ |
+| +------------| SMMU +---------+ | | Windows +--------- AP MCI0/1 | |
+| | translation | +------------+ | Lookup | +-------------+ |
+| +---------+---+ | | +-------------+ |
+| - | | +--------- AP STM | |
+| +----------------- | | +-------------+ |
+| AP | | +-+---------+ |
++---------------------------------------------------------------|----------------------------------+
++-------------|-------------------------------------------------|----------------------------------+
+| CP | +-------------+ +------+-----+ +-------------------+ |
+| | | | | +------- SB CFG Space | |
+| | | DIOB | | | +-------------------+ |
+| | | Windows ----------------- IOB | +-------------------+ |
+| | | Control | | Windows +------| SB PCIe-0 - PCIe2 | |
+| | | | | Lookup | +-------------------+ |
+| | +------+------+ | | +-------------------+ |
+| | | | +------+ SB NAND | |
+| | | +------+-----+ +-------------------+ |
+| | | | |
+| | | | |
+| +------------------+ +------------+ +------+-----+ +-------------------+ |
+| | Network Engine | | | | +------- SB SPI-0/SPI-1 | |
+| | Security Engine | | PCIe, MSS | | RUNIT | +-------------------+ |
+| | SATA, USB | | DMA | | Windows | +-------------------+ |
+| | SD/eMMC | | | | Lookup +------- SB Device Bus | |
+| | TDM, I2C | | | | | +-------------------+ |
+| +------------------+ +------------+ +------------+ |
+| |
++--------------------------------------------------------------------------------------------------+
+
diff --git a/docs/marvell/misc/mvebu-amb.txt b/docs/marvell/misc/mvebu-amb.txt
new file mode 100644
index 000000000..2a7a41ec9
--- /dev/null
+++ b/docs/marvell/misc/mvebu-amb.txt
@@ -0,0 +1,45 @@
+AMB - AXI MBUS address decoding
+-------------------------------
+
+AXI to M-bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs.
+
+- The Runit offers a second level of address windows lookup. It is used to map transaction towards
+the CD BootROM, SPI0, SPI1 and Device bus (NOR).
+- The Runit contains eight configurable windows. Each window defines a contiguous,
+address space and the properties associated with that address space.
+
+Unit Bank ATTR
+Device-Bus DEV_BOOT_CS 0x2F
+ DEV_CS0 0x3E
+ DEV_CS1 0x3D
+ DEV_CS2 0x3B
+ DEV_CS3 0x37
+SPI-0 SPI_A_CS0 0x1E
+ SPI_A_CS1 0x5E
+ SPI_A_CS2 0x9E
+ SPI_A_CS3 0xDE
+ SPI_A_CS4 0x1F
+ SPI_A_CS5 0x5F
+ SPI_A_CS6 0x9F
+ SPI_A_CS7 0xDF
+SPI1 SPI_B_CS0 0x1A
+ SPI_B_CS1 0x5A
+ SPI_B_CS2 0x9A
+ SPI_B_CS3 0xDA
+BOOT_ROM BOOT_ROM 0x1D
+UART UART 0x01
+
+Mandatory functions:
+ - marvell_get_amb_memory_map
+ returns the AMB windows configuration and the number of windows
+
+Mandatory structures:
+ amb_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 2 parameters:
+ - base address of the window
+ - Attribute of the window
+
+Examples:
+ struct addr_map_win amb_memory_map[] = {
+ {0xf900, AMB_DEV_CS0_ID},
+ };
diff --git a/docs/marvell/misc/mvebu-ccu.txt b/docs/marvell/misc/mvebu-ccu.txt
new file mode 100644
index 000000000..976402761
--- /dev/null
+++ b/docs/marvell/misc/mvebu-ccu.txt
@@ -0,0 +1,23 @@
+Marvell CCU address decoding bindings
+=====================================
+
+CCU configration driver (1st stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The CCU node includes a description of the address decoding configuration.
+
+Mandatory functions:
+ - marvell_get_ccu_memory_map
+ return the CCU windows configuration and the number of windows
+ of the specific AP.
+
+Mandatory structures:
+ ccu_memory_map - Array that includes the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Example:
+ struct addr_map_win ccu_memory_map[] = {
+ {0x00000000f2000000, 0x00000000e000000, IO_0_TID}, /* IO window */
+ };
diff --git a/docs/marvell/misc/mvebu-io-win.txt b/docs/marvell/misc/mvebu-io-win.txt
new file mode 100644
index 000000000..c83ad1fd2
--- /dev/null
+++ b/docs/marvell/misc/mvebu-io-win.txt
@@ -0,0 +1,35 @@
+Marvell IO WIN address decoding bindings
+=====================================
+
+IO Window configration driver (2nd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The IO WIN includes a description of the address decoding configuration.
+
+Transactions that are decoded by CCU windows as IO peripheral, have an additional
+layer of decoding. This additional address decoding layer defines one of the
+following targets:
+ 0x0 = BootRom
+ 0x1 = STM (Serial Trace Macro-cell, a programmer's port into trace stream)
+ 0x2 = SPI direct access
+ 0x3 = PCIe registers
+ 0x4 = MCI Port
+ 0x5 = PCIe port
+
+Mandatory functions:
+ - marvell_get_io_win_memory_map
+ returns the IO windows configuration and the number of windows
+ of the specific AP.
+
+Mandatory structures:
+ io_win_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Example:
+ struct addr_map_win io_win_memory_map[] = {
+ {0x00000000fe000000, 0x000000001f00000, PCIE_PORT_TID}, /* PCIe window 31Mb for PCIe port*/
+ {0x00000000ffe00000, 0x000000000100000, PCIE_REGS_TID}, /* PCI-REG window 64Kb for PCIe-reg*/
+ {0x00000000f6000000, 0x000000000100000, MCIPHY_TID}, /* MCI window 1Mb for PHY-reg*/
+ };
diff --git a/docs/marvell/misc/mvebu-iob.txt b/docs/marvell/misc/mvebu-iob.txt
new file mode 100644
index 000000000..97ec09d0e
--- /dev/null
+++ b/docs/marvell/misc/mvebu-iob.txt
@@ -0,0 +1,40 @@
+Marvell IOB address decoding bindings
+=====================================
+
+IO bridge configration driver (3rd stage address translation) for Marvell Armada 8K and 8K+ SoCs.
+
+The IOB includes a description of the address decoding configuration.
+
+IOB supports up to n (in CP110 n=24) windows for external memory transaction.
+When a transaction passes through the IOB, its address is compared to each of
+the enabled windows. If there is a hit and it passes the security checks, it is
+advanced to the target port.
+
+Mandatory functions:
+ - marvell_get_iob_memory_map
+ returns the IOB windows configuration and the number of windows
+
+Mandatory structures:
+ iob_memory_map - Array that include the configuration of the windows
+ every window/entry is a struct which has 3 parameters:
+ - Base address of the window
+ - Size of the window
+ - Target-ID of the window
+
+Target ID options:
+ - 0x0 = Internal configuration space
+ - 0x1 = MCI0
+ - 0x2 = PEX1_X1
+ - 0x3 = PEX2_X1
+ - 0x4 = PEX0_X4
+ - 0x5 = NAND flash
+ - 0x6 = RUNIT (NOR/SPI/BootRoom)
+ - 0x7 = MCI1
+
+Example:
+ struct addr_map_win iob_memory_map[] = {
+ {0x00000000f7000000, 0x0000000001000000, PEX1_TID}, /* PEX1_X1 window */
+ {0x00000000f8000000, 0x0000000001000000, PEX2_TID}, /* PEX2_X1 window */
+ {0x00000000f6000000, 0x0000000001000000, PEX0_TID}, /* PEX0_X4 window */
+ {0x00000000f9000000, 0x0000000001000000, NAND_TID} /* NAND window */
+ };
diff --git a/docs/marvell/porting.txt b/docs/marvell/porting.txt
new file mode 100644
index 000000000..78000e912
--- /dev/null
+++ b/docs/marvell/porting.txt
@@ -0,0 +1,66 @@
+TF-A Porting Guide
+=================
+
+This section describes how to port TF-A to a customer board, assuming that the SoC being used is already supported
+in TF-A.
+
+
+Source Code Structure
+---------------------
+- The customer platform specific code shall reside under "plat/marvell/<soc family>/<soc>_cust"
+ (e.g. 'plat/marvell/a8k/a7040_cust').
+- The platform name for build purposes is called "<soc>_cust" (e.g. a7040_cust).
+- The build system will reuse all files from within the soc directory, and take only the porting
+ files from the customer platform directory.
+
+Files that require porting are located at "plat/marvell/<soc family>/<soc>_cust" directory.
+
+
+Armada-70x0/Armada-80x0 Porting
+-------------------------------
+
+ - SoC Physical Address Map (marvell_plat_config.c):
+ - This file describes the SoC physical memory mapping to be used for the CCU, IOWIN, AXI-MBUS and IOB
+ address decode units (Refer to the functional spec for more details).
+ - In most cases, using the default address decode windows should work OK.
+ - In cases where a special physical address map is needed (e.g. Special size for PCIe MEM windows,
+ large memory mapped SPI flash...), then porting of the SoC memory map is required.
+ - Note: For a detailed information on how CCU, IOWIN, AXI-MBUS & IOB work, please refer to the SoC functional spec,
+ and under "docs/marvell/misc/mvebu-[ccu/iob/amb/io-win].txt" files.
+
+ - boot loader recovery (marvell_plat_config.c):
+ - Background:
+ boot rom can skip the current image and choose to boot from next position if a specific value
+ (0xDEADB002) is returned by the ble main function. This feature is used for boot loader recovery
+ by booting from a valid flash-image saved in next position on flash (e.g. address 2M in SPI flash).
+
+ Supported options to implement the skip request are:
+ - GPIO
+ - I2C
+ - User defined
+
+ - Porting:
+ Under marvell_plat_config.c, implement struct skip_image that includes specific board parameters.
+ .. warning:: to disable this feature make sure the struct skip_image is not implemented.
+
+ - Example:
+ In A7040-DB specific implementation (plat/marvell/a8k/a70x0/board/marvell_plat_config.c),
+ the image skip is implemented using GPIO: mpp 33 (SW5).
+
+ Before resetting the board make sure there is a valid image on the next flash address:
+ -tftp [valid address] flash-image.bin
+ -sf update [valid address] 0x2000000 [size]
+
+ Press reset and keep pressing the button connected to the chosen GPIO pin. A skip image request
+ message is printed on the screen and boot rom boots from the saved image at the next position.
+
+ - DDR Porting (dram_port.c):
+ - This file defines the dram topology and parameters of the target board.
+ - The DDR code is part of the BLE component, which is an extension of ARM Trusted Firmware (TF-A).
+ - The DDR driver called mv_ddr is released separately apart from TF-A sources.
+ - The BLE and consequently, the DDR init code is executed at the early stage of the boot process.
+ - Each supported platform of the TF-A has its own DDR porting file called dram_port.c located at
+ ``atf/plat/marvell/a8k/<platform>/board`` directory.
+ - Please refer to '<path_to_mv_ddr_sources>/doc/porting_guide.txt' for detailed porting description.
+ - The build target directory is "build/<platform>/release/ble".
+
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index 5ac908539..fbf753b09 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -7,8 +7,7 @@ Trusted Firmware-A for Raspberry Pi 3
.. contents::
The `Raspberry Pi 3`_ is an inexpensive single-board computer that contains four
-Arm Cortex-A53 cores, which makes it possible to have a port of Trusted
-Firmware-A (TF-A).
+Arm Cortex-A53 cores.
The following instructions explain how to use this port of the TF-A with the
default distribution of `Raspbian`_ because that's the distribution officially
@@ -66,7 +65,7 @@ Placement of images
The file ``armstub8.bin`` contains BL1 and the FIP. It is needed to add padding
between them so that the addresses they are loaded to match the ones specified
-when compiling TF-A.
+when compiling TF-A. This is done automatically by the build system.
The device tree block is loaded by the VideoCore loader from an appropriate
file, but we can specify the address it is loaded to in ``config.txt``.
@@ -108,13 +107,13 @@ secure platform!
| ... |
| |
0x01000000 +-----------------+
- | Kernel |
+ | DTB | (Loaded by the VideoCore)
+-----------------+
| |
| ... |
| |
0x02000000 +-----------------+
- | DTB |
+ | Kernel | (Loaded by the VideoCore)
+-----------------+
| |
| ... |
@@ -123,9 +122,9 @@ secure platform!
| Secure SRAM | BL2, BL31
0x10100000 +-----------------+
| Secure DRAM | BL32 (Secure payload)
- 0x10C00000 +-----------------+
- | Non-secure DRAM | BL33
0x11000000 +-----------------+
+ | Non-secure DRAM | BL33
+ +-----------------+
| |
| ... |
| |
@@ -133,10 +132,10 @@ secure platform!
| I/O |
0x40000000 +-----------------+
-The area between **0x10000000** and **0x11000000** has to be protected so that
-the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to the
-command line passed to the kernel. See the `Setup SD card`_ instructions to see
-how to do it.
+The area between **0x10000000** and **0x11000000** has to be manually protected
+so that the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to
+the command line passed to the kernel. See the `Setup SD card`_ instructions to
+see how to do it.
The last 16 MiB of DRAM can only be accessed by the VideoCore, that has
different mappings than the Arm cores in which the I/O addresses don't overlap
@@ -159,14 +158,24 @@ The `Linux kernel tree`_ has instructions on how to jump to the Linux kernel
in ``Documentation/arm/Booting`` and ``Documentation/arm64/booting.txt``. The
bootstrap should take care of this.
+This port support a direct boot of the Linux kernel from the firmware (as a BL33
+image). Alternatively, U-Boot or other bootloaders may be used.
+
Secondary cores
~~~~~~~~~~~~~~~
+This port of the Trusted Firmware-A supports ``PSCI_CPU_ON``,
+`PSCI_SYSTEM_RESET`` and ``PSCI_SYSTEM_OFF``. The last one doesn't really turn
+the system off, it simply reboots it and asks the VideoCore firmware to keep it
+in a low power mode permanently.
+
The kernel used by `Raspbian`_ doesn't have support for PSCI, so it is needed to
use mailboxes to trap the secondary cores until they are ready to jump to the
kernel. This mailbox is located at a different address in the AArch32 default
kernel than in the AArch64 kernel.
+Kernels with PSCI support can use the PSCI calls instead for a cleaner boot.
+
Also, this port of TF-A has another Trusted Mailbox in Shared BL RAM. During
cold boot, all secondary cores wait in a loop until they are given given an
address to jump to in this Mailbox (``bl31_warm_entrypoint``).
@@ -187,56 +196,38 @@ To boot a AArch32 kernel, both AArch64 and AArch32 toolchains are required. The
AArch32 toolchain is needed for the AArch32 bootstrap needed to load a 32-bit
kernel.
-First, clone and compile `Raspberry Pi 3 TF-A bootstrap`_. Choose the one
-needed for the architecture of your kernel.
-
-Then compile TF-A. For a AArch32 kernel, use the following command line:
-
-.. code:: shell
-
- CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
- RPI3_BL33_IN_AARCH32=1 \
- BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin \
- all fip
-
-For a AArch64 kernel, use this other command line:
-
-.. code:: shell
-
- CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
- BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin \
- all fip
-
-Then, join BL1 and the FIP with the following instructions (replace ``release``
-by ``debug`` if you set the build option ``DEBUG=1``):
-
-.. code:: shell
-
- cp build/rpi3/release/bl1.bin bl1.pad.bin
- truncate --size=131072 bl1.pad.bin
- cat bl1.pad.bin build/rpi3/release/fip.bin > armstub8.bin
-
-The resulting file, ``armstub8.bin``, contains BL1 and the FIP in the place they
-need to be for TF-A to boot correctly. Now, follow the instructions in
-`Setup SD card`_.
+The build system concatenates BL1 and the FIP so that the addresses match the
+ones in the memory map. The resulting file is ``armstub8.bin``, located in the
+build folder (e.g. ``build/rpi3/debug/armstub8.bin``). To know how to use this
+file, follow the instructions in `Setup SD card`_.
The following build options are supported:
-- ``PRELOADED_BL33_BASE``: Specially useful because the file ``kernel8.img`` can
- be loaded anywhere by modifying the file ``config.txt``. It doesn't have to
- contain a kernel, it could have any arbitrary payload.
-
-- ``RESET_TO_BL31``: Set to 1 by default. If using a 32-bit kernel like
- `Raspbian`_, the space used by BL1 can overwritten by the kernel when it is
- being loaded. Even when using a AArch64 kernel the region used by
- BL1 isn't protected and the kernel could overwrite it. The space used by BL31
- is reserved by the command line passed to the kernel.
-
- ``RPI3_BL33_IN_AARCH32``: This port can load a AArch64 or AArch32 BL33 image.
By default this option is 0, which means that TF-A will jump to BL33 in EL2
in AArch64 mode. If set to 1, it will jump to BL33 in Hypervisor in AArch32
mode.
+- ``PRELOADED_BL33_BASE``: Used to specify the address of a BL33 binary that has
+ been preloaded by any other system than using the firmware. ``BL33`` isn't
+ needed in the build command line if this option is used. Specially useful
+ because the file ``kernel8.img`` can be loaded anywhere by modifying the file
+ ``config.txt``. It doesn't have to contain a kernel, it could have any
+ arbitrary payload.
+
+- ``RPI3_DIRECT_LINUX_BOOT``: Disabled by default. Set to 1 to enable the direct
+ boot of the Linux kernel from the firmware. Option ``RPI3_PRELOADED_DTB_BASE``
+ is mandatory when the direct Linux kernel boot is used. Options
+ ``PRELOADED_BL33_BASE`` will most likely be needed as well because it is
+ unlikely that the kernel image will fit in the space reserved for BL33 images.
+ This option can be combined with ``RPI3_BL33_IN_AARCH32`` in order to boot a
+ 32-bit kernel. The only thing this option does is to set the arguments in
+ registers x0-x3 or r0-r2 as expected by the kernel.
+
+- ``RPI3_PRELOADED_DTB_BASE``: Auxiliary build option needed when using
+ ``RPI3_DIRECT_LINUX_BOOT=1``. This option allows to specify the location of a
+ DTB in memory.
+
- ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
@@ -249,15 +240,16 @@ The following build options are supported:
This will unfortunately reduce the performance of the USB driver. It is needed
when using Raspbian, for example.
-- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option
- ``TRUSTED_BOARD_BOOT=1`` to enable it. In order to use TBB, you might
- want to set ``GENERATE_COT=1`` to let the contents of the FIP automatically
- signed by the build process. The ROT key will be generated and output to
- ``rot_key.pem`` in the build directory. It is able to set ROT_KEY to
- your own key in PEM format.
- Also in order to build, you need to clone mbedtls from
- `here <https://github.com/ARMmbed/mbedtls>`__.
- And set MBEDTLS_DIR to mbedtls source directory.
+- ``TRUSTED_BOARD_BOOT``: This port supports TBB. Set this option to 1 to enable
+ it. In order to use TBB, you might want to set ``GENERATE_COT=1`` to let the
+ contents of the FIP automatically signed by the build process. The ROT key
+ will be generated and output to ``rot_key.pem`` in the build directory. It is
+ able to set ROT_KEY to your own key in PEM format. Also in order to build,
+ you need to clone mbed TLS from `here <https://github.com/ARMmbed/mbedtls>`__.
+ ``MBEDTLS_DIR`` must point at the mbed TLS source directory.
+
+- ``ENABLE_STACK_PROTECTOR``: Disabled by default. It uses the hardware RNG of
+ the board.
The following is not currently supported:
@@ -267,13 +259,65 @@ The following is not currently supported:
address by changing the file ``armstub8.bin``, so there's no point in using
TF-A in this case.
-- ``LOAD_IMAGE_V2=0``: Only version 2 is supported.
-
- ``MULTI_CONSOLE_API=0``: The multi console API must be enabled. Note that the
crash console uses the internal 16550 driver functions directly in order to be
able to print error messages during early crashes before setting up the
multi console API.
+Building the firmware for kernels that don't support PSCI
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is the case for the 32-bit image of Raspbian, for example. 64-bit kernels
+always support PSCI, but they may not know that the system understands PSCI due
+to an incorrect DTB file.
+
+First, clone and compile the 32-bit version of the `Raspberry Pi 3 TF-A
+bootstrap`_. Choose the one needed for the architecture of your kernel.
+
+Then compile TF-A. For a 32-bit kernel, use the following command line:
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
+ RPI3_BL33_IN_AARCH32=1 \
+ BL33=../rpi3-arm-tf-bootstrap/aarch32/el2-bootstrap.bin
+
+For a 64-bit kernel, use this other command line:
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
+ BL33=../rpi3-arm-tf-bootstrap/aarch64/el2-bootstrap.bin
+
+However, enabling PSCI support in a 64-bit kernel is really easy. In the
+repository `Raspberry Pi 3 TF-A bootstrap`_ there is a patch that can be applied
+to the Linux kernel tree maintained by the Raspberry Pi foundation. It modifes
+the DTS to tell the kernel to use PSCI. Once this patch is applied, follow the
+instructions in `AArch64 kernel build instructions`_ to get a working 64-bit
+kernel image and supporting files.
+
+Building the firmware for kernels that support PSCI
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For a 64-bit kernel:
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
+ PRELOADED_BL33_BASE=0x02000000 \
+ RPI3_PRELOADED_DTB_BASE=0x01000000 \
+ RPI3_DIRECT_LINUX_BOOT=1
+
+For a 32-bit kernel:
+
+.. code:: shell
+
+ CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi3 \
+ PRELOADED_BL33_BASE=0x02000000 \
+ RPI3_PRELOADED_DTB_BASE=0x01000000 \
+ RPI3_DIRECT_LINUX_BOOT=1 \
+ RPI3_BL33_IN_AARCH32=1
+
AArch64 kernel build instructions
---------------------------------
@@ -290,7 +334,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
.. code:: shell
- git clone --depth=1 -b rpi-4.14.y https://github.com/raspberrypi/linux
+ git clone --depth=1 -b rpi-4.18.y https://github.com/raspberrypi/linux
cd linux
2. Configure and compile the kernel. Adapt the number after ``-j`` so that it is
@@ -310,6 +354,7 @@ allows the user to run 64-bit binaries in addition to 32-bit binaries.
cp arch/arm64/boot/Image /path/to/boot/kernel8.img
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /path/to/boot/
+ cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b-plus.dtb /path/to/boot/
4. Install the kernel modules. Replace the path by the corresponding path to the
filesystem partition of the SD card on your computer.
@@ -353,8 +398,8 @@ untouched). They have been tested with the image available in 2018-03-13.
::
enable_uart=1
- kernel_address=0x01000000
- device_tree_address=0x02000000
+ kernel_address=0x02000000
+ device_tree_address=0x01000000
If you connect a serial cable to the Mini UART and your computer, and connect
to it (for example, with ``screen /dev/ttyUSB0 115200``) you should see some
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
new file mode 100644
index 000000000..9e731a419
--- /dev/null
+++ b/docs/plat/stm32mp1.rst
@@ -0,0 +1,82 @@
+Trusted Firmware-A for STM32MP1
+===============================
+
+STM32MP1 is a microprocessor designed by STMicroelectronics
+based on a dual Arm Cortex-A7.
+It is an Armv7-A platform, using dedicated code from TF-A.
+
+
+Design
+------
+The STM32MP1 resets in the ROM code of the Cortex-A7.
+The primary boot core (core 0) executes the boot sequence while
+secondary boot core (core 1) is kept in a holding pen loop.
+The ROM code boot sequence loads the TF-A binary image from boot device
+to embedded SRAM.
+
+The TF-A image must be properly formatted with a STM32 header structure
+for ROM code is able to load this image.
+Tool stm32image can be used to prepend this header to the generated TF-A binary.
+
+At compilation step, BL2, BL32 and DTB file are linked together in a single
+binary. The stm32image tool is also generated and the header is added to TF-A
+binary. This binary file with header is named tf-a-stm32mp157c-ev1.stm32.
+It can then be copied in the first partition of the boot device.
+
+
+Memory mapping
+~~~~~~~~~~~~~~
+
+::
+
+ 0x00000000 +-----------------+
+ | | ROM
+ 0x00020000 +-----------------+
+ | |
+ | ... |
+ | |
+ 0x2FFC0000 +-----------------+ \
+ | | |
+ | ... | |
+ | | |
+ 0x2FFD8000 +-----------------+ |
+ | TF-A DTB | | Embedded SRAM
+ 0x2FFDC000 +-----------------+ |
+ | BL2 | |
+ 0x2FFEF000 +-----------------+ |
+ | BL32 | |
+ 0x30000000 +-----------------+ /
+ | |
+ | ... |
+ | |
+ 0x40000000 +-----------------+
+ | |
+ | | Devices
+ | |
+ 0xC0000000 +-----------------+ \
+ | | |
+ 0xC0100000 +-----------------+ |
+ | BL33 | | Non-secure RAM (DDR)
+ | ... | |
+ | | |
+ 0xFFFFFFFF +-----------------+ /
+
+
+Boot sequence
+~~~~~~~~~~~~~
+
+ROM code -> BL2 (compiled with BL2_AT_EL3) -> BL32 (SP_min) -> BL33 (U-Boot)
+
+
+Build Instructions
+------------------
+
+To build:
+
+.. code:: bash
+
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min
+
+The following build options are supported:
+
+- ``ENABLE_STACK_PROTECTOR``: To enable the stack protection.
diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst
index 5462cc1ec..de7b5dba3 100644
--- a/docs/porting-guide.rst
+++ b/docs/porting-guide.rst
@@ -952,9 +952,9 @@ Function : plat\_disable\_acp()
Argument : void
Return : void
-This api allows a platform to disable the Accelerator Coherency Port (if
+This API allows a platform to disable the Accelerator Coherency Port (if
present) during a cluster power down sequence. The default weak implementation
-doesn't do anything. Since this api is called during the power down sequence,
+doesn't do anything. Since this API is called during the power down sequence,
it has restrictions for stack usage and it can use the registers x0 - x17 as
scratch registers. It should preserve the value in x18 register as it is used
by the caller to store the return address.
@@ -2850,6 +2850,106 @@ you can keep the default implementation here (which calls ``console_flush()``).
If you're trying to debug crashes in BL1, you can call the console_xx_core_flush
function exported by some console drivers from here.
+Extternal Abort handling and RAS Support
+----------------------------------------
+
+Function : plat_ea_handler
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Argument : void *
+ Argument : void *
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework for the platform to handle an
+External Abort received at EL3. The intention of the function is to attempt to
+resolve the cause of External Abort and return; if that's not possible, to
+initiate orderly shutdown of the system.
+
+The first parameter (``int ea_reason``) indicates the reason for External Abort.
+Its value is one of ``ERROR_EA_*`` constants defined in ``ea_handle.h``.
+
+The second parameter (``uint64_t syndrome``) is the respective syndrome
+presented to EL3 after having received the External Abort. Depending on the
+nature of the abort (as can be inferred from the ``ea_reason`` parameter), this
+can be the content of either ``ESR_EL3`` or ``DISR_EL1``.
+
+The third parameter (``void *cookie``) is unused for now. The fourth parameter
+(``void *handle``) is a pointer to the preempted context. The fifth parameter
+(``uint64_t flags``) indicates the preempted security state. These parameters
+are received from the top-level exception handler.
+
+If ``RAS_EXTENSION`` is set to ``1``, the default implementation of this
+function iterates through RAS handlers registered by the platform. If any of the
+RAS handlers resolve the External Abort, no further action is taken.
+
+If ``RAS_EXTENSION`` is set to ``0``, or if none of the platform RAS handlers
+could resolve the External Abort, the default implementation prints an error
+message, and panics.
+
+Function : plat_handle_uncontainable_ea
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework when an External Abort of
+Uncontainable type is received at EL3. Due to the critical nature of
+Uncontainable errors, the intention of this function is to initiate orderly
+shutdown of the system, and is not expected to return.
+
+This function must be implemented in assembly.
+
+The first and second parameters are the same as that of ``plat_ea_handler``.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
+Function : plat_handle_double_fault
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Argument : int
+ Argument : uint64_t
+ Return : void
+
+This function is invoked by the RAS framework when another External Abort is
+received at EL3 while one is already being handled. I.e., a call to
+``plat_ea_handler`` is outstanding. Due to its critical nature, the intention of
+this function is to initiate orderly shutdown of the system, and is not expected
+recover or return.
+
+This function must be implemented in assembly.
+
+The first and second parameters are the same as that of ``plat_ea_handler``.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
+Function : plat_handle_el3_ea
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+::
+
+ Return : void
+
+This function is invoked when an External Abort is received while executing in
+EL3. Due to its critical nature, the intention of this function is to initiate
+orderly shutdown of the system, and is not expected recover or return.
+
+This function must be implemented in assembly.
+
+The default implementation of this function calls
+``report_unhandled_exception``.
+
Build flags
-----------
@@ -2882,32 +2982,13 @@ contains those C library definitions required by the local implementation. If
more functionality is required, the needed library functions will need to be
added to the local implementation.
-Versions of `FreeBSD`_ headers can be found in ``include/lib/stdlib``. Some of
-these headers have been cut down in order to simplify the implementation. In
-order to minimize changes to the header files, the `FreeBSD`_ layout has been
-maintained. The generic C library definitions can be found in
-``include/lib/stdlib`` with more system and machine specific declarations in
-``include/lib/stdlib/sys`` and ``include/lib/stdlib/machine``.
-
-The local C library implementations can be found in ``lib/stdlib``. In order to
-extend the C library these files may need to be modified. It is recommended to
-use a release version of `FreeBSD`_ as a starting point.
-
-The C library header files in the `FreeBSD`_ source tree are located in the
-``include`` and ``sys/sys`` directories. `FreeBSD`_ machine specific definitions
-can be found in the ``sys/<machine-type>`` directories. These files define things
-like 'the size of a pointer' and 'the range of an integer'. Since an AArch64
-port for `FreeBSD`_ does not yet exist, the machine specific definitions are
-based on existing machine types with similar properties (for example SPARC64).
-
-Where possible, C library function implementations were taken from `FreeBSD`_
-as found in the ``lib/libc`` directory.
-
-A copy of the `FreeBSD`_ sources can be downloaded with ``git``.
-
-::
+Some C headers have been obtained from `FreeBSD`_ and `SCC`_, while others have
+been written specifically for TF-A. Fome implementation files have been obtained
+from `FreeBSD`_, others have been written specifically for TF-A as well. The
+files can be found in ``include/lib/libc`` and ``lib/libc``.
- git clone git://github.com/freebsd/freebsd.git -b origin/release/9.2.0
+SCC can be found in `http://www.simple-cc.org/`_. A copy of the `FreeBSD`_
+sources can be obtained from `http://github.com/freebsd/freebsd`_.
Storage abstraction layer
-------------------------
@@ -2982,3 +3063,4 @@ amount of open resources per driver.
.. _Arm Generic Interrupt Controller version 2.0 (GICv2): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0048b/index.html
.. _3.0 (GICv3): http://infocenter.arm.com/help/topic/com.arm.doc.ihi0069b/index.html
.. _FreeBSD: http://www.freebsd.org
+.. _SCC: http://www.simple-cc.org/
diff --git a/docs/psci-lib-integration-guide.rst b/docs/psci-lib-integration-guide.rst
index 47cbfcc8d..d86fc29e6 100644
--- a/docs/psci-lib-integration-guide.rst
+++ b/docs/psci-lib-integration-guide.rst
@@ -319,7 +319,7 @@ and some helper utilities for assert, print and memory operations as listed
below. The TF-A source tree provides implementations for all
these functions but the EL3 Runtime Software may use its own implementation.
-**Functions : assert(), memcpy(), memset**
+**Functions : assert(), memcpy(), memset(), printf()**
These must be implemented as described in ISO C Standard.
@@ -353,14 +353,6 @@ This function invalidates (flushes) the data cache for memory at address
This function will be called by the PSCI library on encountering a critical
failure that cannot be recovered from. This function **must not** return.
-**Function : tf\_printf()**
-
-This is printf-compatible function, but unlike printf, it does not return any
-value. The TF-A source tree provides an implementation which
-is optimized for stack usage and supports only a subset of format specifiers.
-The details of the format specifiers supported can be found in the
-``tf_printf.c`` file in the TF-A source tree.
-
CPU Context management API
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/psci-pd-tree.rst b/docs/psci-pd-tree.rst
index 1113abc57..9653725f9 100644
--- a/docs/psci-pd-tree.rst
+++ b/docs/psci-pd-tree.rst
@@ -1,5 +1,5 @@
-PSCI Library Integration guide for Armv8-A AArch32 systems
-==========================================================
+PSCI Power Domain Tree design
+=============================
.. section-numbering::
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index da260264a..b8bb4a190 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -67,14 +67,15 @@ Compiler 6. See instructions below on how to switch the default compiler.
In addition, the following optional packages and tools may be needed:
-- ``device-tree-compiler`` package if you need to rebuild the Flattened Device
- Tree (FDT) source files (``.dts`` files) provided with this software.
+- ``device-tree-compiler`` (dtc) package if you need to rebuild the Flattened Device
+ Tree (FDT) source files (``.dts`` files) provided with this software. The
+ version of dtc must be 1.4.6 or above.
- For debugging, Arm `Development Studio 5 (DS-5)`_.
- To create and modify the diagram files included in the documentation, `Dia`_.
This tool can be found in most Linux distributions. Inkscape is needed to
- generate the actual *.png files.
+ generate the actual \*.png files.
Getting the TF-A source code
----------------------------
@@ -211,6 +212,10 @@ performed.
Common build options
^^^^^^^^^^^^^^^^^^^^
+- ``AARCH32_INSTRUCTION_SET``: Choose the AArch32 instruction set that the
+ compiler should use. Valid values are T32 and A32. It defaults to T32 due to
+ code having a smaller resulting size.
+
- ``AARCH32_SP`` : Choose the AArch32 Secure Payload component to be built as
as the BL32 image when ``ARCH=aarch32``. The value should be the path to the
directory containing the SP source, relative to the ``bl32/``; the directory
@@ -350,6 +355,27 @@ Common build options
that is only required for the assertion and does not fit in the assertion
itself.
+- ``ENABLE_BACKTRACE``: This option controls whether to enables backtrace
+ dumps or not. It is supported in both AArch64 and AArch32. However, in
+ AArch32 the format of the frame records are not defined in the AAPCS and they
+ are defined by the implementation. This implementation of backtrace only
+ supports the format used by GCC when T32 interworking is disabled. For this
+ reason enabling this option in AArch32 will force the compiler to only
+ generate A32 code. This option is enabled by default only in AArch64 debug
+ builds, but this behaviour can be overriden in each platform's Makefile or in
+ the build command line.
+
+- ``ENABLE_MPAM_FOR_LOWER_ELS``: Boolean option to enable lower ELs to use MPAM
+ feature. MPAM is an optional Armv8.4 extension that enables various memory
+ system components and resources to define partitions; software running at
+ various ELs can assign themselves to desired partition to control their
+ performance aspects.
+
+ When this option is set to ``1``, EL3 allows lower ELs to access their own
+ MPAM registers without trapping into EL3. This option doesn't make use of
+ partitioning in EL3, however. Platform initialisation code should configure
+ and use partitions in EL3 as required. This option defaults to ``0``.
+
- ``ENABLE_PMF``: Boolean option to enable support for optional Performance
Measurement Framework(PMF). Default is 0.
@@ -445,8 +471,10 @@ Common build options
.. __: `platform-interrupt-controller-API.rst`
.. __: `interrupt-framework-design.rst`
-- ``HANDLE_EA_EL3_FIRST``: When defined External Aborts and SError Interrupts
- will be always trapped in EL3 i.e. in BL31 at runtime.
+- ``HANDLE_EA_EL3_FIRST``: When set to ``1``, External Aborts and SError
+ Interrupts will be always trapped in EL3 i.e. in BL31 at runtime. When set to
+ ``0`` (default), these exceptions will be trapped in the current exception
+ level (or in EL1 if the current exception level is EL0).
- ``HW_ASSISTED_COHERENCY``: On most Arm systems to-date, platform-specific
software operations are required for CPUs to enter and exit coherency.
@@ -485,8 +513,8 @@ Common build options
- ``LOAD_IMAGE_V2``: Boolean option to enable support for new version (v2) of
image loading, which provides more flexibility and scalability around what
images are loaded and executed during boot. Default is 0.
- Note: ``TRUSTED_BOARD_BOOT`` is currently only supported for AArch64 when
- ``LOAD_IMAGE_V2`` is enabled.
+
+ Note: this flag must be enabled for AArch32 builds.
- ``LOG_LEVEL``: Chooses the log level, which controls the amount of console log
output compiled into the build. This should be one of the following:
diff --git a/drivers/arm/cci/cci.c b/drivers/arm/cci/cci.c
index 81808b9f7..91245d46c 100644
--- a/drivers/arm/cci/cci.c
+++ b/drivers/arm/cci/cci.c
@@ -1,19 +1,21 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
+#include <arch_helpers.h>
#include <assert.h>
#include <cci.h>
#include <debug.h>
#include <mmio.h>
+#include <stdbool.h>
#include <stdint.h>
-#define MAKE_CCI_PART_NUMBER(hi, lo) ((hi << 8) | lo)
-#define CCI_PART_LO_MASK 0xff
-#define CCI_PART_HI_MASK 0xf
+#define MAKE_CCI_PART_NUMBER(hi, lo) (((hi) << 8) | (lo))
+#define CCI_PART_LO_MASK U(0xff)
+#define CCI_PART_HI_MASK U(0xf)
/* CCI part number codes read from Peripheral ID registers 0 and 1 */
#define CCI400_PART_NUM 0x420
@@ -31,14 +33,14 @@ static const int *cci_slave_if_map;
static unsigned int max_master_id;
static int cci_num_slave_ports;
-static int validate_cci_map(const int *map)
+static bool validate_cci_map(const int *map)
{
- unsigned int valid_cci_map = 0;
+ unsigned int valid_cci_map = 0U;
int slave_if_id;
- int i;
+ unsigned int i;
/* Validate the map */
- for (i = 0; i <= max_master_id; i++) {
+ for (i = 0U; i <= max_master_id; i++) {
slave_if_id = map[i];
if (slave_if_id < 0)
@@ -46,22 +48,22 @@ static int validate_cci_map(const int *map)
if (slave_if_id >= cci_num_slave_ports) {
ERROR("Slave interface ID is invalid\n");
- return 0;
+ return false;
}
- if (valid_cci_map & (1 << slave_if_id)) {
+ if ((valid_cci_map & (1U << slave_if_id)) != 0U) {
ERROR("Multiple masters are assigned same slave interface ID\n");
- return 0;
+ return false;
}
- valid_cci_map |= 1 << slave_if_id;
+ valid_cci_map |= 1U << slave_if_id;
}
- if (!valid_cci_map) {
+ if (valid_cci_map == 0U) {
ERROR("No master is assigned a valid slave interface\n");
- return 0;
+ return false;
}
- return 1;
+ return true;
}
/*
@@ -107,8 +109,8 @@ static int get_slave_ports(unsigned int part_num)
void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters)
{
- assert(map);
- assert(base);
+ assert(map != NULL);
+ assert(base != 0U);
cci_base = base;
cci_slave_if_map = map;
@@ -118,7 +120,7 @@ void cci_init(uintptr_t base, const int *map, unsigned int num_cci_masters)
* Master Id's are assigned from zero, So in an array of size n
* the max master id is (n - 1).
*/
- max_master_id = num_cci_masters - 1;
+ max_master_id = num_cci_masters - 1U;
cci_num_slave_ports = get_slave_ports(read_cci_part_number(base));
#endif
assert(cci_num_slave_ports >= 0);
@@ -132,7 +134,7 @@ void cci_enable_snoop_dvm_reqs(unsigned int master_id)
assert(master_id <= max_master_id);
assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0));
- assert(cci_base);
+ assert(cci_base != 0U);
/*
* Enable Snoops and DVM messages, no need for Read/Modify/Write as
@@ -142,8 +144,14 @@ void cci_enable_snoop_dvm_reqs(unsigned int master_id)
SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
DVM_EN_BIT | SNOOP_EN_BIT);
+ /*
+ * Wait for the completion of the write to the Snoop Control Register
+ * before testing the change_pending bit
+ */
+ dsbish();
+
/* Wait for the dust to settle down */
- while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
+ while ((mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) != 0U)
;
}
@@ -153,7 +161,7 @@ void cci_disable_snoop_dvm_reqs(unsigned int master_id)
assert(master_id <= max_master_id);
assert((slave_if_id < cci_num_slave_ports) && (slave_if_id >= 0));
- assert(cci_base);
+ assert(cci_base != 0U);
/*
* Disable Snoops and DVM messages, no need for Read/Modify/Write as
@@ -163,8 +171,14 @@ void cci_disable_snoop_dvm_reqs(unsigned int master_id)
SLAVE_IFACE_OFFSET(slave_if_id) + SNOOP_CTRL_REG,
~(DVM_EN_BIT | SNOOP_EN_BIT));
+ /*
+ * Wait for the completion of the write to the Snoop Control Register
+ * before testing the change_pending bit
+ */
+ dsbish();
+
/* Wait for the dust to settle down */
- while (mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT)
+ while ((mmio_read_32(cci_base + STATUS_REG) & CHANGE_PENDING_BIT) != 0U)
;
}
diff --git a/drivers/arm/gic/common/gic_common.c b/drivers/arm/gic/common/gic_common.c
index 07ed63d74..589de5da4 100644
--- a/drivers/arm/gic/common/gic_common.c
+++ b/drivers/arm/gic/common/gic_common.c
@@ -18,7 +18,8 @@
*/
unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> IGROUPR_SHIFT;
+ unsigned int n = id >> IGROUPR_SHIFT;
+
return mmio_read_32(base + GICD_IGROUPR + (n << 2));
}
@@ -28,7 +29,8 @@ unsigned int gicd_read_igroupr(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ISENABLER_SHIFT;
+ unsigned int n = id >> ISENABLER_SHIFT;
+
return mmio_read_32(base + GICD_ISENABLER + (n << 2));
}
@@ -38,7 +40,8 @@ unsigned int gicd_read_isenabler(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ICENABLER_SHIFT;
+ unsigned int n = id >> ICENABLER_SHIFT;
+
return mmio_read_32(base + GICD_ICENABLER + (n << 2));
}
@@ -48,7 +51,8 @@ unsigned int gicd_read_icenabler(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ISPENDR_SHIFT;
+ unsigned int n = id >> ISPENDR_SHIFT;
+
return mmio_read_32(base + GICD_ISPENDR + (n << 2));
}
@@ -58,7 +62,8 @@ unsigned int gicd_read_ispendr(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ICPENDR_SHIFT;
+ unsigned int n = id >> ICPENDR_SHIFT;
+
return mmio_read_32(base + GICD_ICPENDR + (n << 2));
}
@@ -68,7 +73,8 @@ unsigned int gicd_read_icpendr(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ISACTIVER_SHIFT;
+ unsigned int n = id >> ISACTIVER_SHIFT;
+
return mmio_read_32(base + GICD_ISACTIVER + (n << 2));
}
@@ -78,7 +84,8 @@ unsigned int gicd_read_isactiver(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ICACTIVER_SHIFT;
+ unsigned int n = id >> ICACTIVER_SHIFT;
+
return mmio_read_32(base + GICD_ICACTIVER + (n << 2));
}
@@ -88,7 +95,8 @@ unsigned int gicd_read_icactiver(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> IPRIORITYR_SHIFT;
+ unsigned int n = id >> IPRIORITYR_SHIFT;
+
return mmio_read_32(base + GICD_IPRIORITYR + (n << 2));
}
@@ -98,7 +106,8 @@ unsigned int gicd_read_ipriorityr(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> ICFGR_SHIFT;
+ unsigned int n = id >> ICFGR_SHIFT;
+
return mmio_read_32(base + GICD_ICFGR + (n << 2));
}
@@ -108,7 +117,8 @@ unsigned int gicd_read_icfgr(uintptr_t base, unsigned int id)
*/
unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> NSACR_SHIFT;
+ unsigned int n = id >> NSACR_SHIFT;
+
return mmio_read_32(base + GICD_NSACR + (n << 2));
}
@@ -121,7 +131,8 @@ unsigned int gicd_read_nsacr(uintptr_t base, unsigned int id)
*/
void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> IGROUPR_SHIFT;
+ unsigned int n = id >> IGROUPR_SHIFT;
+
mmio_write_32(base + GICD_IGROUPR + (n << 2), val);
}
@@ -131,7 +142,8 @@ void gicd_write_igroupr(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ISENABLER_SHIFT;
+ unsigned int n = id >> ISENABLER_SHIFT;
+
mmio_write_32(base + GICD_ISENABLER + (n << 2), val);
}
@@ -141,7 +153,8 @@ void gicd_write_isenabler(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ICENABLER_SHIFT;
+ unsigned int n = id >> ICENABLER_SHIFT;
+
mmio_write_32(base + GICD_ICENABLER + (n << 2), val);
}
@@ -151,7 +164,8 @@ void gicd_write_icenabler(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ISPENDR_SHIFT;
+ unsigned int n = id >> ISPENDR_SHIFT;
+
mmio_write_32(base + GICD_ISPENDR + (n << 2), val);
}
@@ -161,7 +175,8 @@ void gicd_write_ispendr(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ICPENDR_SHIFT;
+ unsigned int n = id >> ICPENDR_SHIFT;
+
mmio_write_32(base + GICD_ICPENDR + (n << 2), val);
}
@@ -171,7 +186,8 @@ void gicd_write_icpendr(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ISACTIVER_SHIFT;
+ unsigned int n = id >> ISACTIVER_SHIFT;
+
mmio_write_32(base + GICD_ISACTIVER + (n << 2), val);
}
@@ -181,7 +197,8 @@ void gicd_write_isactiver(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ICACTIVER_SHIFT;
+ unsigned int n = id >> ICACTIVER_SHIFT;
+
mmio_write_32(base + GICD_ICACTIVER + (n << 2), val);
}
@@ -191,7 +208,8 @@ void gicd_write_icactiver(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> IPRIORITYR_SHIFT;
+ unsigned int n = id >> IPRIORITYR_SHIFT;
+
mmio_write_32(base + GICD_IPRIORITYR + (n << 2), val);
}
@@ -201,7 +219,8 @@ void gicd_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> ICFGR_SHIFT;
+ unsigned int n = id >> ICFGR_SHIFT;
+
mmio_write_32(base + GICD_ICFGR + (n << 2), val);
}
@@ -211,7 +230,8 @@ void gicd_write_icfgr(uintptr_t base, unsigned int id, unsigned int val)
*/
void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> NSACR_SHIFT;
+ unsigned int n = id >> NSACR_SHIFT;
+
mmio_write_32(base + GICD_NSACR + (n << 2), val);
}
@@ -223,87 +243,89 @@ void gicd_write_nsacr(uintptr_t base, unsigned int id, unsigned int val)
******************************************************************************/
unsigned int gicd_get_igroupr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igroupr(base, id);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
void gicd_set_igroupr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igroupr(base, id);
- gicd_write_igroupr(base, id, reg_val | (1 << bit_num));
+ gicd_write_igroupr(base, id, reg_val | (1U << bit_num));
}
void gicd_clr_igroupr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igroupr(base, id);
- gicd_write_igroupr(base, id, reg_val & ~(1 << bit_num));
+ gicd_write_igroupr(base, id, reg_val & ~(1U << bit_num));
}
void gicd_set_isenabler(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
- gicd_write_isenabler(base, id, (1 << bit_num));
+ gicd_write_isenabler(base, id, (1U << bit_num));
}
void gicd_set_icenabler(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
- gicd_write_icenabler(base, id, (1 << bit_num));
+ gicd_write_icenabler(base, id, (1U << bit_num));
}
void gicd_set_ispendr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
- gicd_write_ispendr(base, id, (1 << bit_num));
+ gicd_write_ispendr(base, id, (1U << bit_num));
}
void gicd_set_icpendr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
- gicd_write_icpendr(base, id, (1 << bit_num));
+ gicd_write_icpendr(base, id, (1U << bit_num));
}
unsigned int gicd_get_isactiver(uintptr_t base, unsigned int id)
{
- unsigned int bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
unsigned int reg_val = gicd_read_isactiver(base, id);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
void gicd_set_isactiver(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
- gicd_write_isactiver(base, id, (1 << bit_num));
+ gicd_write_isactiver(base, id, (1U << bit_num));
}
void gicd_set_icactiver(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ICACTIVER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICACTIVER_SHIFT) - 1U);
- gicd_write_icactiver(base, id, (1 << bit_num));
+ gicd_write_icactiver(base, id, (1U << bit_num));
}
void gicd_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
{
- mmio_write_8(base + GICD_IPRIORITYR + id, pri & GIC_PRI_MASK);
+ uint8_t val = pri & GIC_PRI_MASK;
+
+ mmio_write_8(base + GICD_IPRIORITYR + id, val);
}
void gicd_set_icfgr(uintptr_t base, unsigned int id, unsigned int cfg)
{
/* Interrupt configuration is a 2-bit field */
- unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
unsigned int bit_shift = bit_num << 1;
uint32_t reg_val = gicd_read_icfgr(base, id);
diff --git a/drivers/arm/gic/v2/gicv2_helpers.c b/drivers/arm/gic/v2/gicv2_helpers.c
index 421669fc1..221f1b539 100644
--- a/drivers/arm/gic/v2/gicv2_helpers.c
+++ b/drivers/arm/gic/v2/gicv2_helpers.c
@@ -94,24 +94,24 @@ void gicv2_spis_configure_defaults(uintptr_t gicd_base)
num_ints = gicd_read_typer(gicd_base);
num_ints &= TYPER_IT_LINES_NO_MASK;
- num_ints = (num_ints + 1) << 5;
+ num_ints = (num_ints + 1U) << 5;
/*
* Treat all SPIs as G1NS by default. The number of interrupts is
* calculated as 32 * (IT_LINES + 1). We do 32 at a time.
*/
- for (index = MIN_SPI_ID; index < num_ints; index += 32)
+ for (index = MIN_SPI_ID; index < num_ints; index += 32U)
gicd_write_igroupr(gicd_base, index, ~0U);
/* Setup the default SPI priorities doing four at a time */
- for (index = MIN_SPI_ID; index < num_ints; index += 4)
+ for (index = MIN_SPI_ID; index < num_ints; index += 4U)
gicd_write_ipriorityr(gicd_base,
index,
GICD_IPRIORITYR_DEF_VAL);
/* Treat all SPIs as level triggered by default, 16 at a time */
- for (index = MIN_SPI_ID; index < num_ints; index += 16)
- gicd_write_icfgr(gicd_base, index, 0);
+ for (index = MIN_SPI_ID; index < num_ints; index += 16U)
+ gicd_write_icfgr(gicd_base, index, 0U);
}
#if !ERROR_DEPRECATED
@@ -125,7 +125,8 @@ void gicv2_secure_spis_configure(uintptr_t gicd_base,
unsigned int index, irq_num;
/* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */
- assert(num_ints ? (uintptr_t)sec_intr_list : 1);
+ if (num_ints != 0U)
+ assert(sec_intr_list != NULL);
for (index = 0; index < num_ints; index++) {
irq_num = sec_intr_list[index];
@@ -161,7 +162,8 @@ void gicv2_secure_spis_configure_props(uintptr_t gicd_base,
const interrupt_prop_t *prop_desc;
/* Make sure there's a valid property array */
- assert(interrupt_props_num != 0 ? (uintptr_t) interrupt_props : 1);
+ if (interrupt_props_num != 0U)
+ assert(interrupt_props != NULL);
for (i = 0; i < interrupt_props_num; i++) {
prop_desc = &interrupt_props[i];
@@ -252,20 +254,21 @@ void gicv2_secure_ppi_sgi_setup_props(uintptr_t gicd_base,
const interrupt_prop_t *prop_desc;
/* Make sure there's a valid property array */
- assert(interrupt_props_num != 0 ? (uintptr_t) interrupt_props : 1);
+ if (interrupt_props_num != 0U)
+ assert(interrupt_props != NULL);
/*
* Disable all SGIs (imp. def.)/PPIs before configuring them. This is a
* more scalable approach as it avoids clearing the enable bits in the
* GICD_CTLR.
*/
- gicd_write_icenabler(gicd_base, 0, ~0);
+ gicd_write_icenabler(gicd_base, 0U, ~0U);
/* Setup the default PPI/SGI priorities doing four at a time */
- for (i = 0; i < MIN_SPI_ID; i += 4)
+ for (i = 0U; i < MIN_SPI_ID; i += 4U)
gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL);
- for (i = 0; i < interrupt_props_num; i++) {
+ for (i = 0U; i < interrupt_props_num; i++) {
prop_desc = &interrupt_props[i];
if (prop_desc->intr_num >= MIN_SPI_ID)
diff --git a/drivers/arm/gic/v2/gicv2_main.c b/drivers/arm/gic/v2/gicv2_main.c
index bbe73fb95..311e77e98 100644
--- a/drivers/arm/gic/v2/gicv2_main.c
+++ b/drivers/arm/gic/v2/gicv2_main.c
@@ -12,6 +12,8 @@
#include <gicv2.h>
#include <interrupt_props.h>
#include <spinlock.h>
+#include <stdbool.h>
+
#include "../common/gic_common_private.h"
#include "gicv2_private.h"
@@ -32,8 +34,8 @@ void gicv2_cpuif_enable(void)
{
unsigned int val;
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
/*
* Enable the Group 0 interrupts, FIQEn and disable Group 0/1
@@ -55,8 +57,8 @@ void gicv2_cpuif_disable(void)
{
unsigned int val;
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
/* Disable secure, non-secure interrupts and disable their bypass */
val = gicc_read_ctlr(driver_data->gicc_base);
@@ -74,8 +76,8 @@ void gicv2_pcpu_distif_init(void)
{
unsigned int ctlr;
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
#if !ERROR_DEPRECATED
if (driver_data->interrupt_props != NULL) {
@@ -101,7 +103,7 @@ void gicv2_pcpu_distif_init(void)
/* Enable G0 interrupts if not already */
ctlr = gicd_read_ctlr(driver_data->gicd_base);
- if ((ctlr & CTLR_ENABLE_G0_BIT) == 0) {
+ if ((ctlr & CTLR_ENABLE_G0_BIT) == 0U) {
gicd_write_ctlr(driver_data->gicd_base,
ctlr | CTLR_ENABLE_G0_BIT);
}
@@ -116,8 +118,8 @@ void gicv2_distif_init(void)
{
unsigned int ctlr;
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
/* Disable the distributor before going further */
ctlr = gicd_read_ctlr(driver_data->gicd_base);
@@ -162,9 +164,10 @@ void gicv2_distif_init(void)
void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data)
{
unsigned int gic_version;
- assert(plat_driver_data);
- assert(plat_driver_data->gicd_base);
- assert(plat_driver_data->gicc_base);
+
+ assert(plat_driver_data != NULL);
+ assert(plat_driver_data->gicd_base != 0U);
+ assert(plat_driver_data->gicc_base != 0U);
#if !ERROR_DEPRECATED
if (plat_driver_data->interrupt_props == NULL) {
@@ -212,7 +215,8 @@ void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data)
* - interrupt priority drop.
* - interrupt signal bypass.
*/
- assert(gic_version == ARCH_REV_GICV2 || gic_version == ARCH_REV_GICV1);
+ assert((gic_version == ARCH_REV_GICV2) ||
+ (gic_version == ARCH_REV_GICV1));
driver_data = plat_driver_data;
@@ -221,9 +225,10 @@ void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data)
* enabled. When the secondary CPU boots up, it initializes the
* GICC/GICR interface with the caches disabled. Hence flush the
* driver_data to ensure coherency. This is not required if the
- * platform has HW_ASSISTED_COHERENCY enabled.
+ * platform has HW_ASSISTED_COHERENCY or WARMBOOT_ENABLE_DCACHE_EARLY
+ * enabled.
*/
-#if !HW_ASSISTED_COHERENCY
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data));
flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data));
#endif
@@ -237,11 +242,11 @@ unsigned int gicv2_is_fiq_enabled(void)
{
unsigned int gicc_ctlr;
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base);
- return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1;
+ return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1U;
}
/*******************************************************************************
@@ -254,8 +259,8 @@ unsigned int gicv2_is_fiq_enabled(void)
******************************************************************************/
unsigned int gicv2_get_pending_interrupt_type(void)
{
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK;
}
@@ -269,8 +274,8 @@ unsigned int gicv2_get_pending_interrupt_id(void)
{
unsigned int id;
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK;
@@ -291,8 +296,8 @@ unsigned int gicv2_get_pending_interrupt_id(void)
******************************************************************************/
unsigned int gicv2_acknowledge_interrupt(void)
{
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
return gicc_read_IAR(driver_data->gicc_base);
}
@@ -303,8 +308,8 @@ unsigned int gicv2_acknowledge_interrupt(void)
******************************************************************************/
void gicv2_end_of_interrupt(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
gicc_write_EOIR(driver_data->gicc_base, id);
}
@@ -317,8 +322,8 @@ void gicv2_end_of_interrupt(unsigned int id)
******************************************************************************/
unsigned int gicv2_get_interrupt_group(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
return gicd_get_igroupr(driver_data->gicd_base, id);
}
@@ -329,8 +334,8 @@ unsigned int gicv2_get_interrupt_group(unsigned int id)
******************************************************************************/
unsigned int gicv2_get_running_priority(void)
{
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
return gicc_read_rpr(driver_data->gicc_base);
}
@@ -343,24 +348,24 @@ unsigned int gicv2_get_running_priority(void)
******************************************************************************/
void gicv2_set_pe_target_mask(unsigned int proc_num)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
- assert(driver_data->target_masks);
- assert(proc_num < GICV2_MAX_TARGET_PE);
- assert(proc_num < driver_data->target_masks_num);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
+ assert(driver_data->target_masks != NULL);
+ assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
+ assert((unsigned int)proc_num < driver_data->target_masks_num);
/* Return if the target mask is already populated */
- if (driver_data->target_masks[proc_num])
+ if (driver_data->target_masks[proc_num] != 0U)
return;
/*
* Update target register corresponding to this CPU and flush for it to
* be visible to other CPUs.
*/
- if (driver_data->target_masks[proc_num] == 0) {
+ if (driver_data->target_masks[proc_num] == 0U) {
driver_data->target_masks[proc_num] =
gicv2_get_cpuif_id(driver_data->gicd_base);
-#if !HW_ASSISTED_COHERENCY
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
/*
* PEs only update their own masks. Primary updates it with
* caches on. But because secondaries does it with caches off,
@@ -381,8 +386,8 @@ void gicv2_set_pe_target_mask(unsigned int proc_num)
******************************************************************************/
unsigned int gicv2_get_interrupt_active(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
assert(id <= MAX_SPI_ID);
return gicd_get_isactiver(driver_data->gicd_base, id);
@@ -393,8 +398,8 @@ unsigned int gicv2_get_interrupt_active(unsigned int id)
******************************************************************************/
void gicv2_enable_interrupt(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
assert(id <= MAX_SPI_ID);
/*
@@ -410,8 +415,8 @@ void gicv2_enable_interrupt(unsigned int id)
******************************************************************************/
void gicv2_disable_interrupt(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
assert(id <= MAX_SPI_ID);
/*
@@ -428,8 +433,8 @@ void gicv2_disable_interrupt(unsigned int id)
******************************************************************************/
void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
assert(id <= MAX_SPI_ID);
gicd_set_ipriorityr(driver_data->gicd_base, id, priority);
@@ -441,8 +446,8 @@ void gicv2_set_interrupt_priority(unsigned int id, unsigned int priority)
******************************************************************************/
void gicv2_set_interrupt_type(unsigned int id, unsigned int type)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
assert(id <= MAX_SPI_ID);
/* Serialize read-modify-write to Distributor registers */
@@ -455,7 +460,7 @@ void gicv2_set_interrupt_type(unsigned int id, unsigned int type)
gicd_clr_igroupr(driver_data->gicd_base, id);
break;
default:
- assert(0);
+ assert(false);
break;
}
spin_unlock(&gic_lock);
@@ -471,20 +476,20 @@ void gicv2_raise_sgi(int sgi_num, int proc_num)
{
unsigned int sgir_val, target;
- assert(driver_data);
- assert(proc_num < GICV2_MAX_TARGET_PE);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
+ assert(driver_data->gicd_base != 0U);
/*
* Target masks array must have been supplied, and the core position
* should be valid.
*/
- assert(driver_data->target_masks);
- assert(proc_num < driver_data->target_masks_num);
+ assert(driver_data->target_masks != NULL);
+ assert((unsigned int)proc_num < driver_data->target_masks_num);
/* Don't raise SGI if the mask hasn't been populated */
target = driver_data->target_masks[proc_num];
- assert(target != 0);
+ assert(target != 0U);
sgir_val = GICV2_SGIR_VALUE(SGIR_TGT_SPECIFIC, target, sgi_num);
@@ -504,20 +509,20 @@ void gicv2_raise_sgi(int sgi_num, int proc_num)
******************************************************************************/
void gicv2_set_spi_routing(unsigned int id, int proc_num)
{
- int target;
+ unsigned int target;
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
- assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID);
+ assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID));
/*
* Target masks array must have been supplied, and the core position
* should be valid.
*/
- assert(driver_data->target_masks);
- assert(proc_num < GICV2_MAX_TARGET_PE);
- assert(proc_num < driver_data->target_masks_num);
+ assert(driver_data->target_masks != NULL);
+ assert((unsigned int)proc_num < GICV2_MAX_TARGET_PE);
+ assert((unsigned int)proc_num < driver_data->target_masks_num);
if (proc_num < 0) {
/* Target all PEs */
@@ -525,7 +530,7 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num)
} else {
/* Don't route interrupt if the mask hasn't been populated */
target = driver_data->target_masks[proc_num];
- assert(target != 0);
+ assert(target != 0U);
}
gicd_set_itargetsr(driver_data->gicd_base, id, target);
@@ -536,8 +541,8 @@ void gicv2_set_spi_routing(unsigned int id, int proc_num)
******************************************************************************/
void gicv2_clear_interrupt_pending(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
/* SGIs can't be cleared pending */
assert(id >= MIN_PPI_ID);
@@ -555,8 +560,8 @@ void gicv2_clear_interrupt_pending(unsigned int id)
******************************************************************************/
void gicv2_set_interrupt_pending(unsigned int id)
{
- assert(driver_data);
- assert(driver_data->gicd_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicd_base != 0U);
/* SGIs can't be cleared pending */
assert(id >= MIN_PPI_ID);
@@ -577,8 +582,8 @@ unsigned int gicv2_set_pmr(unsigned int mask)
{
unsigned int old_mask;
- assert(driver_data);
- assert(driver_data->gicc_base);
+ assert(driver_data != NULL);
+ assert(driver_data->gicc_base != 0U);
old_mask = gicc_read_pmr(driver_data->gicc_base);
diff --git a/drivers/arm/gic/v2/gicv2_private.h b/drivers/arm/gic/v2/gicv2_private.h
index 25600deba..fadc96006 100644
--- a/drivers/arm/gic/v2/gicv2_private.h
+++ b/drivers/arm/gic/v2/gicv2_private.h
@@ -50,7 +50,9 @@ static inline unsigned int gicd_get_itargetsr(uintptr_t base, unsigned int id)
static inline void gicd_set_itargetsr(uintptr_t base, unsigned int id,
unsigned int target)
{
- mmio_write_8(base + GICD_ITARGETSR + id, target & GIC_TARGET_CPU_MASK);
+ uint8_t val = target & GIC_TARGET_CPU_MASK;
+
+ mmio_write_8(base + GICD_ITARGETSR + id, val);
}
static inline void gicd_write_sgir(uintptr_t base, unsigned int val)
diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c
index 2ea8c727b..1953a37b1 100644
--- a/drivers/arm/gic/v3/gicv3_helpers.c
+++ b/drivers/arm/gic/v3/gicv3_helpers.c
@@ -19,7 +19,8 @@
*/
unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> IGRPMODR_SHIFT;
+ unsigned int n = id >> IGRPMODR_SHIFT;
+
return mmio_read_32(base + GICD_IGRPMODR + (n << 2));
}
@@ -29,7 +30,8 @@ unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id)
*/
void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> IGRPMODR_SHIFT;
+ unsigned int n = id >> IGRPMODR_SHIFT;
+
mmio_write_32(base + GICD_IGRPMODR + (n << 2), val);
}
@@ -39,10 +41,10 @@ void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val)
*/
unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igrpmodr(base, id);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
/*
@@ -51,10 +53,10 @@ unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id)
*/
void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igrpmodr(base, id);
- gicd_write_igrpmodr(base, id, reg_val | (1 << bit_num));
+ gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num));
}
/*
@@ -63,10 +65,10 @@ void gicd_set_igrpmodr(uintptr_t base, unsigned int id)
*/
void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicd_read_igrpmodr(base, id);
- gicd_write_igrpmodr(base, id, reg_val & ~(1 << bit_num));
+ gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num));
}
/*
@@ -75,7 +77,8 @@ void gicd_clr_igrpmodr(uintptr_t base, unsigned int id)
*/
unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
{
- unsigned n = id >> IPRIORITYR_SHIFT;
+ unsigned int n = id >> IPRIORITYR_SHIFT;
+
return mmio_read_32(base + GICR_IPRIORITYR + (n << 2));
}
@@ -85,7 +88,8 @@ unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id)
*/
void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
{
- unsigned n = id >> IPRIORITYR_SHIFT;
+ unsigned int n = id >> IPRIORITYR_SHIFT;
+
mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val);
}
@@ -95,10 +99,10 @@ void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val)
*/
unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igroupr0(base);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
/*
@@ -107,10 +111,10 @@ unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id)
*/
void gicr_set_igroupr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igroupr0(base);
- gicr_write_igroupr0(base, reg_val | (1 << bit_num));
+ gicr_write_igroupr0(base, reg_val | (1U << bit_num));
}
/*
@@ -119,10 +123,10 @@ void gicr_set_igroupr0(uintptr_t base, unsigned int id)
*/
void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGROUPR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igroupr0(base);
- gicr_write_igroupr0(base, reg_val & ~(1 << bit_num));
+ gicr_write_igroupr0(base, reg_val & ~(1U << bit_num));
}
/*
@@ -131,10 +135,10 @@ void gicr_clr_igroupr0(uintptr_t base, unsigned int id)
*/
unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igrpmodr0(base);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
/*
@@ -143,10 +147,10 @@ unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id)
*/
void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igrpmodr0(base);
- gicr_write_igrpmodr0(base, reg_val | (1 << bit_num));
+ gicr_write_igrpmodr0(base, reg_val | (1U << bit_num));
}
/*
@@ -155,10 +159,10 @@ void gicr_set_igrpmodr0(uintptr_t base, unsigned int id)
*/
void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << IGRPMODR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U);
unsigned int reg_val = gicr_read_igrpmodr0(base);
- gicr_write_igrpmodr0(base, reg_val & ~(1 << bit_num));
+ gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num));
}
/*
@@ -167,9 +171,9 @@ void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id)
*/
void gicr_set_isenabler0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISENABLER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U);
- gicr_write_isenabler0(base, (1 << bit_num));
+ gicr_write_isenabler0(base, (1U << bit_num));
}
/*
@@ -178,9 +182,9 @@ void gicr_set_isenabler0(uintptr_t base, unsigned int id)
*/
void gicr_set_icenabler0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U);
- gicr_write_icenabler0(base, (1 << bit_num));
+ gicr_write_icenabler0(base, (1U << bit_num));
}
/*
@@ -189,10 +193,10 @@ void gicr_set_icenabler0(uintptr_t base, unsigned int id)
*/
unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISACTIVER_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U);
unsigned int reg_val = gicr_read_isactiver0(base);
- return (reg_val >> bit_num) & 0x1;
+ return (reg_val >> bit_num) & 0x1U;
}
/*
@@ -201,9 +205,9 @@ unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id)
*/
void gicr_set_icpendr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ICPENDR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U);
- gicr_write_icpendr0(base, (1 << bit_num));
+ gicr_write_icpendr0(base, (1U << bit_num));
}
/*
@@ -212,9 +216,9 @@ void gicr_set_icpendr0(uintptr_t base, unsigned int id)
*/
void gicr_set_ispendr0(uintptr_t base, unsigned int id)
{
- unsigned bit_num = id & ((1 << ISPENDR_SHIFT) - 1);
+ unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U);
- gicr_write_ispendr0(base, (1 << bit_num));
+ gicr_write_ispendr0(base, (1U << bit_num));
}
/*
@@ -223,7 +227,9 @@ void gicr_set_ispendr0(uintptr_t base, unsigned int id)
*/
void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
{
- mmio_write_8(base + GICR_IPRIORITYR + id, pri & GIC_PRI_MASK);
+ uint8_t val = pri & GIC_PRI_MASK;
+
+ mmio_write_8(base + GICR_IPRIORITYR + id, val);
}
/*
@@ -233,8 +239,8 @@ void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri)
void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
{
/* Interrupt configuration is a 2-bit field */
- unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
- unsigned int bit_shift = bit_num << 1;
+ unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
+ unsigned int bit_shift = bit_num << 1U;
uint32_t reg_val = gicr_read_icfgr0(base);
@@ -252,8 +258,8 @@ void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg)
void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg)
{
/* Interrupt configuration is a 2-bit field */
- unsigned int bit_num = id & ((1 << ICFGR_SHIFT) - 1);
- unsigned int bit_shift = bit_num << 1;
+ unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U);
+ unsigned int bit_shift = bit_num << 1U;
uint32_t reg_val = gicr_read_icfgr1(base);
@@ -274,13 +280,13 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base)
* The WAKER_PS_BIT should be changed to 0
* only when WAKER_CA_BIT is 1.
*/
- assert(gicr_read_waker(gicr_base) & WAKER_CA_BIT);
+ assert((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U);
/* Mark the connected core as awake */
gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) & ~WAKER_PS_BIT);
/* Wait till the WAKER_CA_BIT changes to 0 */
- while (gicr_read_waker(gicr_base) & WAKER_CA_BIT)
+ while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) != 0U)
;
}
@@ -295,7 +301,7 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base)
gicr_write_waker(gicr_base, gicr_read_waker(gicr_base) | WAKER_PS_BIT);
/* Wait till the WAKER_CA_BIT changes to 1 */
- while (!(gicr_read_waker(gicr_base) & WAKER_CA_BIT))
+ while ((gicr_read_waker(gicr_base) & WAKER_CA_BIT) == 0U)
;
}
@@ -312,10 +318,10 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
{
u_register_t mpidr;
unsigned int proc_num;
- unsigned long long typer_val;
+ uint64_t typer_val;
uintptr_t rdistif_base = gicr_base;
- assert(rdistif_base_addrs);
+ assert(rdistif_base_addrs != NULL);
/*
* Iterate over the Redistributor frames. Store the base address of each
@@ -326,7 +332,7 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
*/
do {
typer_val = gicr_read_typer(rdistif_base);
- if (mpidr_to_core_pos) {
+ if (mpidr_to_core_pos != NULL) {
mpidr = mpidr_from_gicr_typer(typer_val);
proc_num = mpidr_to_core_pos(mpidr);
} else {
@@ -335,8 +341,8 @@ void gicv3_rdistif_base_addrs_probe(uintptr_t *rdistif_base_addrs,
}
assert(proc_num < rdistif_num);
rdistif_base_addrs[proc_num] = rdistif_base;
- rdistif_base += (1 << GICR_PCPUBASE_SHIFT);
- } while (!(typer_val & TYPER_LAST_BIT));
+ rdistif_base += (1U << GICR_PCPUBASE_SHIFT);
+ } while ((typer_val & TYPER_LAST_BIT) == 0U);
}
/*******************************************************************************
@@ -348,17 +354,17 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base)
num_ints = gicd_read_typer(gicd_base);
num_ints &= TYPER_IT_LINES_NO_MASK;
- num_ints = (num_ints + 1) << 5;
+ num_ints = (num_ints + 1U) << 5;
/*
* Treat all SPIs as G1NS by default. The number of interrupts is
* calculated as 32 * (IT_LINES + 1). We do 32 at a time.
*/
- for (index = MIN_SPI_ID; index < num_ints; index += 32)
+ for (index = MIN_SPI_ID; index < num_ints; index += 32U)
gicd_write_igroupr(gicd_base, index, ~0U);
/* Setup the default SPI priorities doing four at a time */
- for (index = MIN_SPI_ID; index < num_ints; index += 4)
+ for (index = MIN_SPI_ID; index < num_ints; index += 4U)
gicd_write_ipriorityr(gicd_base,
index,
GICD_IPRIORITYR_DEF_VAL);
@@ -367,8 +373,8 @@ void gicv3_spis_config_defaults(uintptr_t gicd_base)
* Treat all SPIs as level triggered by default, write 16 at
* a time
*/
- for (index = MIN_SPI_ID; index < num_ints; index += 16)
- gicd_write_icfgr(gicd_base, index, 0);
+ for (index = MIN_SPI_ID; index < num_ints; index += 16U)
+ gicd_write_icfgr(gicd_base, index, 0U);
}
#if !ERROR_DEPRECATED
@@ -385,9 +391,10 @@ void gicv3_secure_spis_config(uintptr_t gicd_base,
assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0));
/* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */
- assert(num_ints ? (uintptr_t)sec_intr_list : 1);
+ if (num_ints != 0U)
+ assert(sec_intr_list != NULL);
- for (index = 0; index < num_ints; index++) {
+ for (index = 0U; index < num_ints; index++) {
irq_num = sec_intr_list[index];
if (irq_num >= MIN_SPI_ID) {
@@ -407,7 +414,7 @@ void gicv3_secure_spis_config(uintptr_t gicd_base,
/* Target SPIs to the primary CPU */
gic_affinity_val =
- gicd_irouter_val_from_mpidr(read_mpidr(), 0);
+ gicd_irouter_val_from_mpidr(read_mpidr(), 0U);
gicd_write_irouter(gicd_base,
irq_num,
gic_affinity_val);
@@ -430,12 +437,13 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
unsigned int i;
const interrupt_prop_t *current_prop;
unsigned long long gic_affinity_val;
- unsigned int ctlr_enable = 0;
+ unsigned int ctlr_enable = 0U;
/* Make sure there's a valid property array */
- assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1);
+ if (interrupt_props_num > 0U)
+ assert(interrupt_props != NULL);
- for (i = 0; i < interrupt_props_num; i++) {
+ for (i = 0U; i < interrupt_props_num; i++) {
current_prop = &interrupt_props[i];
if (current_prop->intr_num < MIN_SPI_ID)
@@ -464,7 +472,8 @@ unsigned int gicv3_secure_spis_config_props(uintptr_t gicd_base,
current_prop->intr_pri);
/* Target SPIs to the primary CPU */
- gic_affinity_val = gicd_irouter_val_from_mpidr(read_mpidr(), 0);
+ gic_affinity_val =
+ gicd_irouter_val_from_mpidr(read_mpidr(), 0U);
gicd_write_irouter(gicd_base, current_prop->intr_num,
gic_affinity_val);
@@ -487,20 +496,20 @@ void gicv3_ppi_sgi_config_defaults(uintptr_t gicr_base)
* more scalable approach as it avoids clearing the enable bits in the
* GICD_CTLR
*/
- gicr_write_icenabler0(gicr_base, ~0);
+ gicr_write_icenabler0(gicr_base, ~0U);
gicr_wait_for_pending_write(gicr_base);
/* Treat all SGIs/PPIs as G1NS by default. */
gicr_write_igroupr0(gicr_base, ~0U);
/* Setup the default PPI/SGI priorities doing four at a time */
- for (index = 0; index < MIN_SPI_ID; index += 4)
+ for (index = 0U; index < MIN_SPI_ID; index += 4U)
gicr_write_ipriorityr(gicr_base,
index,
GICD_IPRIORITYR_DEF_VAL);
/* Configure all PPIs as level triggered by default */
- gicr_write_icfgr1(gicr_base, 0);
+ gicr_write_icfgr1(gicr_base, 0U);
}
#if !ERROR_DEPRECATED
@@ -516,7 +525,8 @@ void gicv3_secure_ppi_sgi_config(uintptr_t gicr_base,
assert((int_grp == INTR_GROUP1S) || (int_grp == INTR_GROUP0));
/* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */
- assert(num_ints ? (uintptr_t)sec_intr_list : 1);
+ if (num_ints != 0U)
+ assert(sec_intr_list != NULL);
for (index = 0; index < num_ints; index++) {
irq_num = sec_intr_list[index];
@@ -552,12 +562,13 @@ unsigned int gicv3_secure_ppi_sgi_config_props(uintptr_t gicr_base,
{
unsigned int i;
const interrupt_prop_t *current_prop;
- unsigned int ctlr_enable = 0;
+ unsigned int ctlr_enable = 0U;
/* Make sure there's a valid property array */
- assert(interrupt_props_num > 0 ? interrupt_props != NULL : 1);
+ if (interrupt_props_num > 0U)
+ assert(interrupt_props != NULL);
- for (i = 0; i < interrupt_props_num; i++) {
+ for (i = 0U; i < interrupt_props_num; i++) {
current_prop = &interrupt_props[i];
if (current_prop->intr_num >= MIN_SPI_ID)
diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c
index 83d030a86..8da4512e5 100644
--- a/drivers/arm/gic/v3/gicv3_main.c
+++ b/drivers/arm/gic/v3/gicv3_main.c
@@ -34,21 +34,21 @@ static spinlock_t gic_lock;
/* Helper macros to save and restore GICD registers to and from the context */
#define RESTORE_GICD_REGS(base, ctx, intr_num, reg, REG) \
do { \
- for (unsigned int int_id = MIN_SPI_ID; int_id < intr_num; \
- int_id += (1 << REG##_SHIFT)) { \
+ for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \
+ int_id += (1U << REG##_SHIFT)) { \
gicd_write_##reg(base, int_id, \
ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT]); \
} \
- } while (0)
+ } while (false)
#define SAVE_GICD_REGS(base, ctx, intr_num, reg, REG) \
do { \
- for (unsigned int int_id = MIN_SPI_ID; int_id < intr_num; \
- int_id += (1 << REG##_SHIFT)) { \
+ for (unsigned int int_id = MIN_SPI_ID; int_id < (intr_num); \
+ int_id += (1U << REG##_SHIFT)) { \
ctx->gicd_##reg[(int_id - MIN_SPI_ID) >> REG##_SHIFT] =\
gicd_read_##reg(base, int_id); \
} \
- } while (0)
+ } while (false)
/*******************************************************************************
@@ -59,11 +59,11 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
{
unsigned int gic_version;
- assert(plat_driver_data);
- assert(plat_driver_data->gicd_base);
- assert(plat_driver_data->gicr_base);
- assert(plat_driver_data->rdistif_num);
- assert(plat_driver_data->rdistif_base_addrs);
+ assert(plat_driver_data != NULL);
+ assert(plat_driver_data->gicd_base != 0U);
+ assert(plat_driver_data->gicr_base != 0U);
+ assert(plat_driver_data->rdistif_num != 0U);
+ assert(plat_driver_data->rdistif_base_addrs != NULL);
assert(IS_IN_EL3());
@@ -109,10 +109,10 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
/* Check for system register support */
#ifdef AARCH32
- assert(read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT));
+ assert((read_id_pfr1() & (ID_PFR1_GIC_MASK << ID_PFR1_GIC_SHIFT)) != 0U);
#else
- assert(read_id_aa64pfr0_el1() &
- (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT));
+ assert((read_id_aa64pfr0_el1() &
+ (ID_AA64PFR0_GIC_MASK << ID_AA64PFR0_GIC_SHIFT)) != 0U);
#endif /* AARCH32 */
/* The GIC version should be 3.0 */
@@ -147,9 +147,10 @@ void gicv3_driver_init(const gicv3_driver_data_t *plat_driver_data)
* enabled. When the secondary CPU boots up, it initializes the
* GICC/GICR interface with the caches disabled. Hence flush the
* driver data to ensure coherency. This is not required if the
- * platform has HW_ASSISTED_COHERENCY enabled.
+ * platform has HW_ASSISTED_COHERENCY or WARMBOOT_ENABLE_DCACHE_EARLY
+ * enabled.
*/
-#if !HW_ASSISTED_COHERENCY
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
flush_dcache_range((uintptr_t) &gicv3_driver_data,
sizeof(gicv3_driver_data));
flush_dcache_range((uintptr_t) gicv3_driver_data,
@@ -169,8 +170,8 @@ void gicv3_distif_init(void)
{
unsigned int bitmap = 0;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(IS_IN_EL3());
@@ -244,16 +245,16 @@ void gicv3_distif_init(void)
void gicv3_rdistif_init(unsigned int proc_num)
{
uintptr_t gicr_base;
- unsigned int bitmap = 0;
+ unsigned int bitmap = 0U;
uint32_t ctlr;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
ctlr = gicd_read_ctlr(gicv3_driver_data->gicd_base);
- assert(ctlr & CTLR_ARE_S_BIT);
+ assert((ctlr & CTLR_ARE_S_BIT) != 0U);
assert(IS_IN_EL3());
@@ -332,9 +333,9 @@ void gicv3_cpuif_enable(unsigned int proc_num)
unsigned int scr_el3;
unsigned int icc_sre_el3;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(IS_IN_EL3());
/* Mark the connected core as awake */
@@ -352,7 +353,7 @@ void gicv3_cpuif_enable(unsigned int proc_num)
icc_sre_el3 |= (ICC_SRE_EN_BIT | ICC_SRE_SRE_BIT);
write_icc_sre_el3(read_icc_sre_el3() | icc_sre_el3);
- scr_el3 = read_scr_el3();
+ scr_el3 = (uint32_t) read_scr_el3();
/*
* Switch to NS state to write Non secure ICC_SRE_EL1 and
@@ -392,9 +393,9 @@ void gicv3_cpuif_disable(unsigned int proc_num)
{
uintptr_t gicr_base;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(IS_IN_EL3());
@@ -428,14 +429,14 @@ unsigned int gicv3_get_pending_interrupt_id(void)
unsigned int id;
assert(IS_IN_EL3());
- id = read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;
+ id = (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;
/*
* If the ID is special identifier corresponding to G1S or G1NS
* interrupt, then read the highest pending group 1 interrupt.
*/
if ((id == PENDING_G1S_INTID) || (id == PENDING_G1NS_INTID))
- return read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK;
+ return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK;
return id;
}
@@ -452,7 +453,7 @@ unsigned int gicv3_get_pending_interrupt_id(void)
unsigned int gicv3_get_pending_interrupt_type(void)
{
assert(IS_IN_EL3());
- return read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;
+ return (uint32_t)read_icc_hppir0_el1() & HPPIR0_EL1_INTID_MASK;
}
/*******************************************************************************
@@ -472,10 +473,10 @@ unsigned int gicv3_get_interrupt_type(unsigned int id,
uintptr_t gicr_base;
assert(IS_IN_EL3());
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
/* Ensure the parameters are valid */
- assert(id < PENDING_G1S_INTID || id >= MIN_LPI_ID);
+ assert((id < PENDING_G1S_INTID) || (id >= MIN_LPI_ID));
assert(proc_num < gicv3_driver_data->rdistif_num);
/* All LPI interrupts are Group 1 non secure */
@@ -483,12 +484,12 @@ unsigned int gicv3_get_interrupt_type(unsigned int id,
return INTR_GROUP1NS;
if (id < MIN_SPI_ID) {
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
igroup = gicr_get_igroupr0(gicr_base, id);
grpmodr = gicr_get_igrpmodr0(gicr_base, id);
} else {
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data->gicd_base != 0U);
igroup = gicd_get_igroupr(gicv3_driver_data->gicd_base, id);
grpmodr = gicd_get_igrpmodr(gicv3_driver_data->gicd_base, id);
}
@@ -497,11 +498,11 @@ unsigned int gicv3_get_interrupt_type(unsigned int id,
* If the IGROUP bit is set, then it is a Group 1 Non secure
* interrupt
*/
- if (igroup)
+ if (igroup != 0U)
return INTR_GROUP1NS;
/* If the GRPMOD bit is set, then it is a Group 1 Secure interrupt */
- if (grpmodr)
+ if (grpmodr != 0U)
return INTR_GROUP1S;
/* Else it is a Group 0 Secure interrupt */
@@ -521,12 +522,12 @@ unsigned int gicv3_get_interrupt_type(unsigned int id,
*****************************************************************************/
void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx)
{
- int i;
+ unsigned int i;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(IS_IN_EL3());
- assert(its_ctx);
- assert(gits_base);
+ assert(its_ctx != NULL);
+ assert(gits_base != 0U);
its_ctx->gits_ctlr = gits_read_ctlr(gits_base);
@@ -554,16 +555,16 @@ void gicv3_its_save_disable(uintptr_t gits_base, gicv3_its_ctx_t * const its_ctx
*****************************************************************************/
void gicv3_its_restore(uintptr_t gits_base, const gicv3_its_ctx_t * const its_ctx)
{
- int i;
+ unsigned int i;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(IS_IN_EL3());
- assert(its_ctx);
- assert(gits_base);
+ assert(its_ctx != NULL);
+ assert(gits_base != 0U);
/* Assert that the GITS is disabled and quiescent */
- assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0);
- assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) != 0);
+ assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
+ assert((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) != 0U);
gits_write_cbaser(gits_base, its_ctx->gits_cbaser);
gits_write_cwriter(gits_base, its_ctx->gits_cwriter);
@@ -585,11 +586,11 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_
uintptr_t gicr_base;
unsigned int int_id;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(IS_IN_EL3());
- assert(rdist_ctx);
+ assert(rdist_ctx != NULL);
gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
@@ -613,7 +614,7 @@ void gicv3_rdistif_save(unsigned int proc_num, gicv3_redist_ctx_t * const rdist_
rdist_ctx->gicr_igrpmodr0 = gicr_read_igrpmodr0(gicr_base);
rdist_ctx->gicr_nsacr = gicr_read_nsacr(gicr_base);
for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM;
- int_id += (1 << IPRIORITYR_SHIFT)) {
+ int_id += (1U << IPRIORITYR_SHIFT)) {
rdist_ctx->gicr_ipriorityr[(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT] =
gicr_read_ipriorityr(gicr_base, int_id);
}
@@ -640,11 +641,11 @@ void gicv3_rdistif_init_restore(unsigned int proc_num,
uintptr_t gicr_base;
unsigned int int_id;
- assert(gicv3_driver_data);
+ assert(gicv3_driver_data != NULL);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(IS_IN_EL3());
- assert(rdist_ctx);
+ assert(rdist_ctx != NULL);
gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num];
@@ -663,7 +664,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num,
* more scalable approach as it avoids clearing the enable bits in the
* GICD_CTLR
*/
- gicr_write_icenabler0(gicr_base, ~0);
+ gicr_write_icenabler0(gicr_base, ~0U);
/* Wait for pending writes to GICR_ICENABLER */
gicr_wait_for_pending_write(gicr_base);
@@ -681,7 +682,7 @@ void gicv3_rdistif_init_restore(unsigned int proc_num,
gicr_write_igroupr0(gicr_base, rdist_ctx->gicr_igroupr0);
for (int_id = MIN_SGI_ID; int_id < TOTAL_PCPU_INTR_NUM;
- int_id += (1 << IPRIORITYR_SHIFT)) {
+ int_id += (1U << IPRIORITYR_SHIFT)) {
gicr_write_ipriorityr(gicr_base, int_id,
rdist_ctx->gicr_ipriorityr[
(int_id - MIN_SGI_ID) >> IPRIORITYR_SHIFT]);
@@ -721,18 +722,18 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx)
{
unsigned int num_ints;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(IS_IN_EL3());
- assert(dist_ctx);
+ assert(dist_ctx != NULL);
uintptr_t gicd_base = gicv3_driver_data->gicd_base;
num_ints = gicd_read_typer(gicd_base);
num_ints &= TYPER_IT_LINES_NO_MASK;
- num_ints = (num_ints + 1) << 5;
+ num_ints = (num_ints + 1U) << 5;
- assert(num_ints <= MAX_SPI_ID + 1);
+ assert(num_ints <= (MAX_SPI_ID + 1U));
/* Wait for pending write to complete */
gicd_wait_for_pending_write(gicd_base);
@@ -783,12 +784,12 @@ void gicv3_distif_save(gicv3_dist_ctx_t * const dist_ctx)
*****************************************************************************/
void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx)
{
- unsigned int num_ints = 0;
+ unsigned int num_ints = 0U;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(IS_IN_EL3());
- assert(dist_ctx);
+ assert(dist_ctx != NULL);
uintptr_t gicd_base = gicv3_driver_data->gicd_base;
@@ -808,9 +809,9 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx)
num_ints = gicd_read_typer(gicd_base);
num_ints &= TYPER_IT_LINES_NO_MASK;
- num_ints = (num_ints + 1) << 5;
+ num_ints = (num_ints + 1U) << 5;
- assert(num_ints <= MAX_SPI_ID + 1);
+ assert(num_ints <= (MAX_SPI_ID + 1U));
/* Restore GICD_IGROUPR for INTIDs 32 - 1020 */
RESTORE_GICD_REGS(gicd_base, dist_ctx, num_ints, igroupr, IGROUPR);
@@ -856,7 +857,7 @@ void gicv3_distif_init_restore(const gicv3_dist_ctx_t * const dist_ctx)
******************************************************************************/
unsigned int gicv3_get_running_priority(void)
{
- return read_icc_rpr_el1();
+ return (unsigned int)read_icc_rpr_el1();
}
/*******************************************************************************
@@ -869,10 +870,10 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
{
unsigned int value;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(id <= MAX_SPI_ID);
if (id < MIN_SPI_ID) {
@@ -893,10 +894,10 @@ unsigned int gicv3_get_interrupt_active(unsigned int id, unsigned int proc_num)
******************************************************************************/
void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
{
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(id <= MAX_SPI_ID);
/*
@@ -921,10 +922,10 @@ void gicv3_enable_interrupt(unsigned int id, unsigned int proc_num)
******************************************************************************/
void gicv3_disable_interrupt(unsigned int id, unsigned int proc_num)
{
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(id <= MAX_SPI_ID);
/*
@@ -959,10 +960,10 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
{
uintptr_t gicr_base;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
assert(id <= MAX_SPI_ID);
if (id < MIN_SPI_ID) {
@@ -981,29 +982,29 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
unsigned int type)
{
- unsigned int igroup = 0, grpmod = 0;
+ bool igroup = false, grpmod = false;
uintptr_t gicr_base;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
switch (type) {
case INTR_GROUP1S:
- igroup = 0;
- grpmod = 1;
+ igroup = false;
+ grpmod = true;
break;
case INTR_GROUP0:
- igroup = 0;
- grpmod = 0;
+ igroup = false;
+ grpmod = false;
break;
case INTR_GROUP1NS:
- igroup = 1;
- grpmod = 0;
+ igroup = true;
+ grpmod = false;
break;
default:
- assert(0);
+ assert(false);
break;
}
@@ -1039,7 +1040,7 @@ void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
*
* The target parameter must be a valid MPIDR in the system.
******************************************************************************/
-void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target)
+void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target)
{
unsigned int tgt, aff3, aff2, aff1, aff0;
uint64_t sgi_val;
@@ -1058,7 +1059,7 @@ void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target)
* this PE.
*/
assert(aff0 < GICV3_MAX_SGI_TARGETS);
- tgt = BIT(aff0);
+ tgt = BIT_32(aff0);
/* Raise SGI to PE specified by its affinity */
sgi_val = GICV3_SGIR_VALUE(aff3, aff2, aff1, sgi_num, SGIR_IRM_TO_AFF,
@@ -1089,11 +1090,11 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
unsigned long long aff;
uint64_t router;
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert((irm == GICV3_IRM_ANY) || (irm == GICV3_IRM_PE));
- assert(id >= MIN_SPI_ID && id <= MAX_SPI_ID);
+ assert((id >= MIN_SPI_ID) && (id <= MAX_SPI_ID));
aff = gicd_irouter_val_from_mpidr(mpidr, irm);
gicd_write_irouter(gicv3_driver_data->gicd_base, id, aff);
@@ -1104,7 +1105,7 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
*/
if (irm == GICV3_IRM_ANY) {
router = gicd_read_irouter(gicv3_driver_data->gicd_base, id);
- if (!((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK)) {
+ if (((router >> IROUTER_IRM_SHIFT) & IROUTER_IRM_MASK) == 0U) {
ERROR("GICv3 implementation doesn't support routing ANY\n");
panic();
}
@@ -1118,10 +1119,10 @@ void gicv3_set_spi_routing(unsigned int id, unsigned int irm, u_register_t mpidr
******************************************************************************/
void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
{
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
/*
* Clear pending interrupt, and ensure that any shared variable updates
@@ -1144,10 +1145,10 @@ void gicv3_clear_interrupt_pending(unsigned int id, unsigned int proc_num)
******************************************************************************/
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num)
{
- assert(gicv3_driver_data);
- assert(gicv3_driver_data->gicd_base);
+ assert(gicv3_driver_data != NULL);
+ assert(gicv3_driver_data->gicd_base != 0U);
assert(proc_num < gicv3_driver_data->rdistif_num);
- assert(gicv3_driver_data->rdistif_base_addrs);
+ assert(gicv3_driver_data->rdistif_base_addrs != NULL);
/*
* Ensure that any shared variable updates depending on out of band
@@ -1171,7 +1172,7 @@ unsigned int gicv3_set_pmr(unsigned int mask)
{
unsigned int old_mask;
- old_mask = read_icc_pmr_el1();
+ old_mask = (uint32_t) read_icc_pmr_el1();
/*
* Order memory updates w.r.t. PMR write, and ensure they're visible
diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h
index e1c0775f7..36d4b3ed5 100644
--- a/drivers/arm/gic/v3/gicv3_private.h
+++ b/drivers/arm/gic/v3/gicv3_private.h
@@ -19,28 +19,36 @@
******************************************************************************/
/* Constants to indicate the status of the RWP bit */
-#define RWP_TRUE 1
-#define RWP_FALSE 0
+#define RWP_TRUE U(1)
+#define RWP_FALSE U(0)
/*
* Macro to convert an mpidr to a value suitable for programming into a
* GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant
* to GICv3.
*/
-#define gicd_irouter_val_from_mpidr(_mpidr, _irm) \
- ((_mpidr & ~(0xff << 24)) | \
- (_irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT)
+static inline u_register_t gicd_irouter_val_from_mpidr(u_register_t mpidr,
+ unsigned int irm)
+{
+ return (mpidr & ~(U(0xff) << 24)) |
+ ((irm & IROUTER_IRM_MASK) << IROUTER_IRM_SHIFT);
+}
/*
* Macro to convert a GICR_TYPER affinity value into a MPIDR value. Bits[31:24]
* are zeroes.
*/
#ifdef AARCH32
-#define mpidr_from_gicr_typer(_typer_val) (((_typer_val) >> 32) & 0xffffff)
+static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
+{
+ return (((typer_val) >> 32) & U(0xffffff));
+}
#else
-#define mpidr_from_gicr_typer(_typer_val) \
- (((((_typer_val) >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) | \
- (((_typer_val) >> 32) & 0xffffff))
+static inline u_register_t mpidr_from_gicr_typer(uint64_t typer_val)
+{
+ return (((typer_val >> 56) & MPIDR_AFFLVL_MASK) << MPIDR_AFF3_SHIFT) |
+ ((typer_val >> 32) & U(0xffffff));
+}
#endif
/*******************************************************************************
@@ -121,7 +129,7 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base);
*/
static inline void gicd_wait_for_pending_write(uintptr_t gicd_base)
{
- while (gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT)
+ while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U)
;
}
@@ -149,7 +157,7 @@ static inline void gicd_clr_ctlr(uintptr_t base,
unsigned int rwp)
{
gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap);
- if (rwp)
+ if (rwp != 0U)
gicd_wait_for_pending_write(base);
}
@@ -158,21 +166,21 @@ static inline void gicd_set_ctlr(uintptr_t base,
unsigned int rwp)
{
gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap);
- if (rwp)
+ if (rwp != 0U)
gicd_wait_for_pending_write(base);
}
/*******************************************************************************
* GIC Redistributor interface accessors
******************************************************************************/
-static inline unsigned long long gicr_read_ctlr(uintptr_t base)
+static inline uint32_t gicr_read_ctlr(uintptr_t base)
{
- return mmio_read_64(base + GICR_CTLR);
+ return mmio_read_32(base + GICR_CTLR);
}
-static inline void gicr_write_ctlr(uintptr_t base, uint64_t val)
+static inline void gicr_write_ctlr(uintptr_t base, uint32_t val)
{
- mmio_write_64(base + GICR_CTLR, val);
+ mmio_write_32(base + GICR_CTLR, val);
}
static inline unsigned long long gicr_read_typer(uintptr_t base)
@@ -199,13 +207,13 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val)
*/
static inline void gicr_wait_for_pending_write(uintptr_t gicr_base)
{
- while (gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT)
+ while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U)
;
}
static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base)
{
- while (gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT)
+ while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U)
;
}
@@ -313,24 +321,24 @@ static inline void gicr_write_icfgr1(uintptr_t base, unsigned int val)
mmio_write_32(base + GICR_ICFGR1, val);
}
-static inline unsigned int gicr_read_propbaser(uintptr_t base)
+static inline uint64_t gicr_read_propbaser(uintptr_t base)
{
- return mmio_read_32(base + GICR_PROPBASER);
+ return mmio_read_64(base + GICR_PROPBASER);
}
-static inline void gicr_write_propbaser(uintptr_t base, unsigned int val)
+static inline void gicr_write_propbaser(uintptr_t base, uint64_t val)
{
- mmio_write_32(base + GICR_PROPBASER, val);
+ mmio_write_64(base + GICR_PROPBASER, val);
}
-static inline unsigned int gicr_read_pendbaser(uintptr_t base)
+static inline uint64_t gicr_read_pendbaser(uintptr_t base)
{
- return mmio_read_32(base + GICR_PENDBASER);
+ return mmio_read_64(base + GICR_PENDBASER);
}
-static inline void gicr_write_pendbaser(uintptr_t base, unsigned int val)
+static inline void gicr_write_pendbaser(uintptr_t base, uint64_t val)
{
- mmio_write_32(base + GICR_PENDBASER, val);
+ mmio_write_64(base + GICR_PENDBASER, val);
}
/*******************************************************************************
@@ -353,7 +361,7 @@ static inline uint64_t gits_read_cbaser(uintptr_t base)
static inline void gits_write_cbaser(uintptr_t base, uint64_t val)
{
- mmio_write_32(base + GITS_CBASER, val);
+ mmio_write_64(base + GITS_CBASER, val);
}
static inline uint64_t gits_read_cwriter(uintptr_t base)
@@ -363,19 +371,19 @@ static inline uint64_t gits_read_cwriter(uintptr_t base)
static inline void gits_write_cwriter(uintptr_t base, uint64_t val)
{
- mmio_write_32(base + GITS_CWRITER, val);
+ mmio_write_64(base + GITS_CWRITER, val);
}
static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id)
{
- assert(its_table_id < 8);
- return mmio_read_64(base + GITS_BASER + (8 * its_table_id));
+ assert(its_table_id < 8U);
+ return mmio_read_64(base + GITS_BASER + (8U * its_table_id));
}
static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val)
{
- assert(its_table_id < 8);
- mmio_write_64(base + GITS_BASER + (8 * its_table_id), val);
+ assert(its_table_id < 8U);
+ mmio_write_64(base + GITS_BASER + (8U * its_table_id), val);
}
/*
@@ -383,8 +391,8 @@ static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, u
*/
static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base)
{
- assert(!(gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT));
- while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0)
+ assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U);
+ while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U)
;
}
diff --git a/drivers/arm/smmu/smmu_v3.c b/drivers/arm/smmu/smmu_v3.c
index 7b017e300..ddb99634e 100644
--- a/drivers/arm/smmu/smmu_v3.c
+++ b/drivers/arm/smmu/smmu_v3.c
@@ -1,15 +1,12 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <mmio.h>
#include <smmu_v3.h>
-
-/* Test for pending invalidate */
-#define INVAL_PENDING(_base) \
- smmuv3_read_s_init(_base) & SMMU_S_INIT_INV_ALL_MASK
+#include <stdbool.h>
static inline uint32_t smmuv3_read_s_idr1(uintptr_t base)
{
@@ -26,6 +23,12 @@ static inline void smmuv3_write_s_init(uintptr_t base, uint32_t value)
mmio_write_32(base + SMMU_S_INIT, value);
}
+/* Test for pending invalidate */
+static inline bool smmuv3_inval_pending(uintptr_t base)
+{
+ return (smmuv3_read_s_init(base) & SMMU_S_INIT_INV_ALL_MASK) != 0U;
+}
+
/*
* Initialize the SMMU by invalidating all secure caches and TLBs.
*
@@ -41,14 +44,14 @@ int smmuv3_init(uintptr_t smmu_base)
* SMMU_S_INIT register is accessed.
*/
idr1_reg = smmuv3_read_s_idr1(smmu_base);
- if (!((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) &
- SMMU_S_IDR1_SECURE_IMPL_MASK)) {
+ if (((idr1_reg >> SMMU_S_IDR1_SECURE_IMPL_SHIFT) &
+ SMMU_S_IDR1_SECURE_IMPL_MASK) == 0U) {
return -1;
}
/* Initiate invalidation, and wait for it to finish */
smmuv3_write_s_init(smmu_base, SMMU_S_INIT_INV_ALL_MASK);
- while (INVAL_PENDING(smmu_base))
+ while (smmuv3_inval_pending(smmu_base))
;
return 0;
diff --git a/drivers/arm/sp805/sp805.c b/drivers/arm/sp805/sp805.c
index 98df7e215..aee90164a 100644
--- a/drivers/arm/sp805/sp805.c
+++ b/drivers/arm/sp805/sp805.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,17 +10,17 @@
/* Inline register access functions */
-static inline void sp805_write_wdog_load(uintptr_t base, unsigned long value)
+static inline void sp805_write_wdog_load(uintptr_t base, uint32_t value)
{
mmio_write_32(base + SP805_WDOG_LOAD_OFF, value);
}
-static inline void sp805_write_wdog_ctrl(uintptr_t base, unsigned long value)
+static inline void sp805_write_wdog_ctrl(uintptr_t base, uint32_t value)
{
mmio_write_32(base + SP805_WDOG_CTR_OFF, value);
}
-static inline void sp805_write_wdog_lock(uintptr_t base, unsigned long value)
+static inline void sp805_write_wdog_lock(uintptr_t base, uint32_t value)
{
mmio_write_32(base + SP805_WDOG_LOCK_OFF, value);
}
@@ -28,23 +28,23 @@ static inline void sp805_write_wdog_lock(uintptr_t base, unsigned long value)
/* Public API implementation */
-void sp805_start(uintptr_t base, unsigned long ticks)
+void sp805_start(uintptr_t base, unsigned int ticks)
{
sp805_write_wdog_load(base, ticks);
sp805_write_wdog_ctrl(base, SP805_CTR_RESEN | SP805_CTR_INTEN);
/* Lock registers access */
- sp805_write_wdog_lock(base, 0);
+ sp805_write_wdog_lock(base, 0U);
}
void sp805_stop(uintptr_t base)
{
sp805_write_wdog_lock(base, WDOG_UNLOCK_KEY);
- sp805_write_wdog_ctrl(base, 0);
+ sp805_write_wdog_ctrl(base, 0U);
}
-void sp805_refresh(uintptr_t base, unsigned long ticks)
+void sp805_refresh(uintptr_t base, unsigned int ticks)
{
sp805_write_wdog_lock(base, WDOG_UNLOCK_KEY);
sp805_write_wdog_load(base, ticks);
- sp805_write_wdog_lock(base, 0);
+ sp805_write_wdog_lock(base, 0U);
}
diff --git a/drivers/auth/mbedtls/mbedtls_common.c b/drivers/auth/mbedtls/mbedtls_common.c
index c048d005a..7095fde33 100644
--- a/drivers/auth/mbedtls/mbedtls_common.c
+++ b/drivers/auth/mbedtls/mbedtls_common.c
@@ -5,6 +5,8 @@
*/
#include <debug.h>
+#include <stdlib.h>
+#include <stdio.h>
/* mbed TLS headers */
#include <mbedtls/memory_buffer_alloc.h>
@@ -23,6 +25,12 @@
#endif
static unsigned char heap[MBEDTLS_HEAP_SIZE];
+static void cleanup(void)
+{
+ ERROR("EXIT from BL2\n");
+ panic();
+}
+
/*
* mbed TLS initialization function
*/
@@ -31,14 +39,15 @@ void mbedtls_init(void)
static int ready;
if (!ready) {
+ if (atexit(cleanup))
+ panic();
+
/* Initialize the mbed TLS heap */
mbedtls_memory_buffer_alloc_init(heap, MBEDTLS_HEAP_SIZE);
#ifdef MBEDTLS_PLATFORM_SNPRINTF_ALT
- /* Use reduced version of snprintf to save space. */
- mbedtls_platform_set_snprintf(tf_snprintf);
+ mbedtls_platform_set_snprintf(snprintf);
#endif
-
ready = 1;
}
}
diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk
index a5d19e6a9..71c496eda 100644
--- a/drivers/auth/mbedtls/mbedtls_common.mk
+++ b/drivers/auth/mbedtls/mbedtls_common.mk
@@ -13,22 +13,86 @@ ifeq (${MBEDTLS_DIR},)
$(error Error: MBEDTLS_DIR not set)
endif
-INCLUDES += -I${MBEDTLS_DIR}/include \
- -Iinclude/drivers/auth/mbedtls
+MBEDTLS_INC = -I${MBEDTLS_DIR}/include
+INCLUDES += -Iinclude/drivers/auth/mbedtls
# Specify mbed TLS configuration file
MBEDTLS_CONFIG_FILE := "<mbedtls_config.h>"
$(eval $(call add_define,MBEDTLS_CONFIG_FILE))
-MBEDTLS_COMMON_SOURCES := drivers/auth/mbedtls/mbedtls_common.c \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- asn1parse.c \
- asn1write.c \
- memory_buffer_alloc.c \
- oid.c \
- platform.c \
- platform_util.c \
- rsa_internal.c \
- )
+MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c
+
+
+LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
+ asn1parse.c \
+ asn1write.c \
+ memory_buffer_alloc.c \
+ oid.c \
+ platform.c \
+ platform_util.c \
+ bignum.c \
+ md.c \
+ md_wrap.c \
+ pk.c \
+ pk_wrap.c \
+ pkparse.c \
+ pkwrite.c \
+ sha256.c \
+ sha512.c \
+ ecdsa.c \
+ ecp_curves.c \
+ ecp.c \
+ rsa.c \
+ rsa_internal.c \
+ x509.c \
+ x509_crt.c \
+ )
+
+# The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
+# algorithm to use. If the variable is not defined, select it based on algorithm
+# used for key generation `KEY_ALG`. If `KEY_ALG` is not defined or is
+# defined to `rsa`/`rsa_1_5`, then set the variable to `rsa`.
+ifeq (${TF_MBEDTLS_KEY_ALG},)
+ ifeq (${KEY_ALG}, ecdsa)
+ TF_MBEDTLS_KEY_ALG := ecdsa
+ else
+ TF_MBEDTLS_KEY_ALG := rsa
+ endif
+endif
+
+# If MBEDTLS_KEY_ALG build flag is defined use it to set TF_MBEDTLS_KEY_ALG for
+# backward compatibility
+ifdef MBEDTLS_KEY_ALG
+ ifeq (${ERROR_DEPRECATED},1)
+ $(error "MBEDTLS_KEY_ALG is deprecated. Please use the new build flag TF_MBEDTLS_KEY_ALG")
+ endif
+ $(warning "MBEDTLS_KEY_ALG is deprecated. Please use the new build flag TF_MBEDTLS_KEY_ALG")
+ TF_MBEDTLS_KEY_ALG := ${MBEDTLS_KEY_ALG}
+endif
+
+ifeq (${HASH_ALG}, sha384)
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384
+else ifeq (${HASH_ALG}, sha512)
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
+else
+ TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
+endif
+
+ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
+ TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_ECDSA
+else ifeq (${TF_MBEDTLS_KEY_ALG},rsa)
+ TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
+else ifeq (${TF_MBEDTLS_KEY_ALG},rsa+ecdsa)
+ TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA_AND_ECDSA
+else
+ $(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
+endif
+
+# Needs to be set to drive mbed TLS configuration correctly
+$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
+$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
+
+
+$(eval $(call MAKE_LIB,mbedtls))
endif
diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk
index 6b15e717d..2a9fbbf99 100644
--- a/drivers/auth/mbedtls/mbedtls_crypto.mk
+++ b/drivers/auth/mbedtls/mbedtls_crypto.mk
@@ -6,86 +6,6 @@
include drivers/auth/mbedtls/mbedtls_common.mk
-# The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
-# algorithm to use. If the variable is not defined, select it based on algorithm
-# used for key generation `KEY_ALG`. If `KEY_ALG` is not defined or is
-# defined to `rsa`/`rsa_1_5`, then set the variable to `rsa`.
-ifeq (${TF_MBEDTLS_KEY_ALG},)
- ifeq (${KEY_ALG}, ecdsa)
- TF_MBEDTLS_KEY_ALG := ecdsa
- else
- TF_MBEDTLS_KEY_ALG := rsa
- endif
-endif
+MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_crypto.c
-# If MBEDTLS_KEY_ALG build flag is defined use it to set TF_MBEDTLS_KEY_ALG for
-# backward compatibility
-ifdef MBEDTLS_KEY_ALG
- ifeq (${ERROR_DEPRECATED},1)
- $(error "MBEDTLS_KEY_ALG is deprecated. Please use the new build flag TF_MBEDTLS_KEY_ALG")
- endif
- $(warning "MBEDTLS_KEY_ALG is deprecated. Please use the new build flag TF_MBEDTLS_KEY_ALG")
- TF_MBEDTLS_KEY_ALG := ${MBEDTLS_KEY_ALG}
-endif
-MBEDTLS_CRYPTO_SOURCES := drivers/auth/mbedtls/mbedtls_crypto.c \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- bignum.c \
- md.c \
- md_wrap.c \
- pk.c \
- pk_wrap.c \
- pkparse.c \
- pkwrite.c \
- )
-
-ifeq (${HASH_ALG}, sha384)
- MBEDTLS_CRYPTO_SOURCES += \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- sha256.c \
- sha512.c \
- )
- TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384
-else ifeq (${HASH_ALG}, sha512)
- MBEDTLS_CRYPTO_SOURCES += \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- sha256.c \
- sha512.c \
- )
- TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
-else
- MBEDTLS_CRYPTO_SOURCES += \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- sha256.c \
- )
- TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
-endif
-
-# Key algorithm specific files
-MBEDTLS_ECDSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
- ecdsa.c \
- ecp_curves.c \
- ecp.c \
- )
-
-MBEDTLS_RSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
- rsa.c \
- )
-
-ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
- MBEDTLS_CRYPTO_SOURCES += $(MBEDTLS_ECDSA_CRYPTO_SOURCES)
- TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_ECDSA
-else ifeq (${TF_MBEDTLS_KEY_ALG},rsa)
- MBEDTLS_CRYPTO_SOURCES += $(MBEDTLS_RSA_CRYPTO_SOURCES)
- TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
-else ifeq (${TF_MBEDTLS_KEY_ALG},rsa+ecdsa)
- MBEDTLS_CRYPTO_SOURCES += $(MBEDTLS_ECDSA_CRYPTO_SOURCES)
- MBEDTLS_CRYPTO_SOURCES += $(MBEDTLS_RSA_CRYPTO_SOURCES)
- TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA_AND_ECDSA
-else
- $(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
-endif
-
-# Needs to be set to drive mbed TLS configuration correctly
-$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
-$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
diff --git a/drivers/auth/mbedtls/mbedtls_x509.mk b/drivers/auth/mbedtls/mbedtls_x509.mk
index a6f72e678..a0557e20a 100644
--- a/drivers/auth/mbedtls/mbedtls_x509.mk
+++ b/drivers/auth/mbedtls/mbedtls_x509.mk
@@ -6,8 +6,4 @@
include drivers/auth/mbedtls/mbedtls_common.mk
-MBEDTLS_X509_SOURCES := drivers/auth/mbedtls/mbedtls_x509_parser.c \
- $(addprefix ${MBEDTLS_DIR}/library/, \
- x509.c \
- x509_crt.c \
- )
+MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_x509_parser.c
diff --git a/drivers/console/aarch64/multi_console.S b/drivers/console/aarch64/multi_console.S
index 0464776b2..7f076c623 100644
--- a/drivers/console/aarch64/multi_console.S
+++ b/drivers/console/aarch64/multi_console.S
@@ -39,10 +39,11 @@
* persistent memory (e.g. the data section).
* In : x0 - address of console_t structure
* Out: x0 - Always 1 (for easier tail calling)
- * Clobber list: x0, x1, x14, x15
+ * Clobber list: x0, x1
* -----------------------------------------------
*/
func console_register
+ stp x21, x30, [sp, #-16]!
#if ENABLE_ASSERTIONS
/* Assert that x0 isn't a NULL pointer */
cmp x0, #0
@@ -59,18 +60,17 @@ func console_register
not_on_stack:
/* Assert that this struct isn't in the list */
mov x1, x0 /* Preserve x0 and x30 */
- mov x15, x30
bl console_is_registered
cmp x0, #0
ASM_ASSERT(eq)
- mov x30, x15
mov x0, x1
#endif /* ENABLE_ASSERTIONS */
- adrp x14, console_list
- ldr x1, [x14, :lo12:console_list] /* X1 = first struct in list */
- str x0, [x14, :lo12:console_list] /* list head = new console */
+ adrp x21, console_list
+ ldr x1, [x21, :lo12:console_list] /* X1 = first struct in list */
+ str x0, [x21, :lo12:console_list] /* list head = new console */
str x1, [x0, #CONSOLE_T_NEXT] /* new console next ptr = X1 */
mov x0, #1
+ ldp x21, x30, [sp], #16
ret
endfunc console_register
@@ -80,7 +80,7 @@ endfunc console_register
* of currently active consoles and remove it.
* In: x0 - address of console_t struct to remove
* Out: x0 - removed address, or NULL if not found
- * Clobber list: x0, x1, x14
+ * Clobber list: x0, x1
* -----------------------------------------------
*/
func console_unregister
@@ -89,25 +89,28 @@ func console_unregister
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- adrp x14, console_list
- add x14, x14, :lo12:console_list /* X14 = ptr to first struct */
- ldr x1, [x14] /* X1 = first struct */
+ stp x21, xzr, [sp, #-16]!
+ adrp x21, console_list
+ add x21, x21, :lo12:console_list /* X21 = ptr to first struct */
+ ldr x1, [x21] /* X1 = first struct */
unregister_loop:
cbz x1, unregister_not_found
cmp x0, x1
b.eq unregister_found
- ldr x14, [x14] /* X14 = next ptr of struct */
- ldr x1, [x14] /* X1 = next struct */
+ ldr x21, [x21] /* X21 = next ptr of struct */
+ ldr x1, [x21] /* X1 = next struct */
b unregister_loop
unregister_found:
ldr x1, [x1] /* X1 = next struct */
- str x1, [x14] /* prev->next = cur->next */
+ str x1, [x21] /* prev->next = cur->next */
+ ldp x21, xzr, [sp], #16
ret
unregister_not_found:
mov x0, #0 /* return NULL if not found */
+ ldp x21, xzr, [sp], #16
ret
endfunc console_unregister
@@ -117,7 +120,7 @@ endfunc console_unregister
* registered or not.
* In: x0 - address of console_t struct to remove
* Out: x0 - 1 if it is registered, 0 if not.
- * Clobber list: x0, x14
+ * Clobber list: x0
* -----------------------------------------------
*/
func console_is_registered
@@ -126,19 +129,22 @@ func console_is_registered
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
- adrp x14, console_list
- ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+ stp x21, xzr, [sp, #-16]!
+ adrp x21, console_list
+ ldr x21, [x21, :lo12:console_list] /* X21 = first console struct */
check_registered_loop:
- cbz x14, console_not_registered /* Check if end of list */
- cmp x0, x14 /* Check if the pointers are different */
+ cbz x21, console_not_registered /* Check if end of list */
+ cmp x0, x21 /* Check if the pointers are different */
b.eq console_registered
- ldr x14, [x14, #CONSOLE_T_NEXT] /* Get pointer to next struct */
+ ldr x21, [x21, #CONSOLE_T_NEXT] /* Get pointer to next struct */
b check_registered_loop
console_not_registered:
mov x0, #0
+ ldp x21, xzr, [sp], #16
ret
console_registered:
mov x0, #1
+ ldp x21, xzr, [sp], #16
ret
endfunc console_is_registered
@@ -186,38 +192,41 @@ endfunc console_set_scope
* In : x0 - character to be printed
* Out: x0 - printed character on success, or < 0
if at least one console had an error
- * Clobber list : x0, x1, x2, x12, x13, x14, x15
+ * Clobber list : x0, x1, x2
* ---------------------------------------------
*/
func console_putc
- mov x15, x30
- mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
- mov w12, w0 /* W12 = character to print */
- adrp x14, console_list
- ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+ stp x21, x30, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ mov w20, #ERROR_NO_VALID_CONSOLE /* W20 = current return value */
+ mov w19, w0 /* W19 = character to print */
+ adrp x21, console_list
+ ldr x21, [x21, :lo12:console_list] /* X21 = first console struct */
putc_loop:
- cbz x14, putc_done
+ cbz x21, putc_done
adrp x1, console_state
ldrb w1, [x1, :lo12:console_state]
- ldr w2, [x14, #CONSOLE_T_FLAGS]
+ ldr w2, [x21, #CONSOLE_T_FLAGS]
tst w1, w2
b.eq putc_continue
- ldr x2, [x14, #CONSOLE_T_PUTC]
+ ldr x2, [x21, #CONSOLE_T_PUTC]
cbz x2, putc_continue
- mov w0, w12
- mov x1, x14
+ mov w0, w19
+ mov x1, x21
blr x2
- cmp w13, #ERROR_NO_VALID_CONSOLE /* update W13 if it's NOVALID */
+ cmp w20, #ERROR_NO_VALID_CONSOLE /* update W20 if it's NOVALID */
ccmp w0, #0, #0x8, ne /* else update it if W0 < 0 */
- csel w13, w0, w13, lt
+ csel w20, w0, w20, lt
putc_continue:
- ldr x14, [x14] /* X14 = next struct */
+ ldr x21, [x21] /* X21 = next struct */
b putc_loop
putc_done:
- mov w0, w13
- ret x15
+ mov w0, w20
+ ldp x19, x20, [sp], #16
+ ldp x21, x30, [sp], #16
+ ret
endfunc console_putc
/* ---------------------------------------------
@@ -230,42 +239,47 @@ endfunc console_putc
* if all active consoles report real errors
* (other than just not having a char available).
* Out : x0 - read character, or < 0 on error
- * Clobber list : x0, x1, x13, x14, x15
+ * Clobber list : x0, x1
* ---------------------------------------------
*/
func console_getc
- mov x15, x30
+ stp x30, xzr, [sp, #-16]!
+ stp x20, x21, [sp, #-16]!
getc_try_again:
- mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
- adrp x14, console_list
- ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
- cbnz x14, getc_loop
- mov w0, w13 /* If no consoles registered */
- ret x15 /* return immediately. */
+ mov w20, #ERROR_NO_VALID_CONSOLE /* W20 = current return value */
+ adrp x21, console_list
+ ldr x21, [x21, :lo12:console_list] /* X21 = first console struct */
+ cbnz x21, getc_loop
+ mov w0, w20 /* If no consoles registered */
+ ldp x20, x21, [sp], #16
+ ldp x30, xzr, [sp], #16
+ ret /* return immediately. */
getc_loop:
adrp x0, console_state
ldrb w0, [x0, :lo12:console_state]
- ldr w1, [x14, #CONSOLE_T_FLAGS]
+ ldr w1, [x21, #CONSOLE_T_FLAGS]
tst w0, w1
b.eq getc_continue
- ldr x1, [x14, #CONSOLE_T_GETC]
+ ldr x1, [x21, #CONSOLE_T_GETC]
cbz x1, getc_continue
- mov x0, x14
+ mov x0, x21
blr x1
cmp w0, #0 /* if X0 >= 0: return */
b.ge getc_found
- cmp w13, #ERROR_NO_PENDING_CHAR /* may update W13 (NOCHAR has */
- csel w13, w13, w0, eq /* precedence vs real errors) */
+ cmp w20, #ERROR_NO_PENDING_CHAR /* may update W20 (NOCHAR has */
+ csel w20, w20, w0, eq /* precedence vs real errors) */
getc_continue:
- ldr x14, [x14] /* X14 = next struct */
- cbnz x14, getc_loop
- cmp w13, #ERROR_NO_PENDING_CHAR /* Keep scanning if at least */
+ ldr x21, [x21] /* X21 = next struct */
+ cbnz x21, getc_loop
+ cmp w20, #ERROR_NO_PENDING_CHAR /* Keep scanning if at least */
b.eq getc_try_again /* one console returns NOCHAR */
- mov w0, w13
+ mov w0, w20
getc_found:
- ret x15
+ ldp x20, x21, [sp], #16
+ ldp x30, xzr, [sp], #16
+ ret
endfunc console_getc
/* ---------------------------------------------
@@ -274,34 +288,37 @@ endfunc console_getc
* data that hasn't been output. Calls all
* console's flush() handlers in succession.
* Out: x0 - 0 on success, < 0 if at least one error
- * Clobber list : x0, x1, x2, x3, x4, x5, x13, x14, x15
+ * Clobber list : x0, x1, x2
* ---------------------------------------------
*/
func console_flush
- mov x15, x30
- mov w13, #ERROR_NO_VALID_CONSOLE /* W13 = current return value */
- adrp x14, console_list
- ldr x14, [x14, :lo12:console_list] /* X14 = first console struct */
+ stp x30, xzr, [sp, #-16]!
+ stp x20, x21, [sp, #-16]!
+ mov w20, #ERROR_NO_VALID_CONSOLE /* W20 = current return value */
+ adrp x21, console_list
+ ldr x21, [x21, :lo12:console_list] /* X21 = first console struct */
flush_loop:
- cbz x14, flush_done
+ cbz x21, flush_done
adrp x1, console_state
ldrb w1, [x1, :lo12:console_state]
- ldr w2, [x14, #CONSOLE_T_FLAGS]
+ ldr w2, [x21, #CONSOLE_T_FLAGS]
tst w1, w2
b.eq flush_continue
- ldr x1, [x14, #CONSOLE_T_FLUSH]
+ ldr x1, [x21, #CONSOLE_T_FLUSH]
cbz x1, flush_continue
- mov x0, x14
+ mov x0, x21
blr x1
- cmp w13, #ERROR_NO_VALID_CONSOLE /* update W13 if it's NOVALID */
+ cmp w20, #ERROR_NO_VALID_CONSOLE /* update W20 if it's NOVALID */
ccmp w0, #0, #0x8, ne /* else update it if W0 < 0 */
- csel w13, w0, w13, lt
+ csel w20, w0, w20, lt
flush_continue:
- ldr x14, [x14] /* X14 = next struct */
+ ldr x21, [x21] /* X21 = next struct */
b flush_loop
flush_done:
- mov w0, w13
- ret x15
+ mov w0, w20
+ ldp x20, x21, [sp], #16
+ ldp x30, xzr, [sp], #16
+ ret
endfunc console_flush
diff --git a/drivers/emmc/emmc.c b/drivers/emmc/emmc.c
deleted file mode 100644
index 92d1e8727..000000000
--- a/drivers/emmc/emmc.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Defines a simple and generic interface to access eMMC device.
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <debug.h>
-#include <emmc.h>
-#include <errno.h>
-#include <string.h>
-#include <utils.h>
-
-static const emmc_ops_t *ops;
-static unsigned int emmc_ocr_value;
-static emmc_csd_t emmc_csd;
-static unsigned int emmc_flags;
-
-static int is_cmd23_enabled(void)
-{
- return (!!(emmc_flags & EMMC_FLAG_CMD23));
-}
-
-static int emmc_device_state(void)
-{
- emmc_cmd_t cmd;
- int ret;
-
- do {
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD13;
- cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- assert((cmd.resp_data[0] & STATUS_SWITCH_ERROR) == 0);
- /* Ignore improbable errors in release builds */
- (void)ret;
- } while ((cmd.resp_data[0] & STATUS_READY_FOR_DATA) == 0);
- return EMMC_GET_STATE(cmd.resp_data[0]);
-}
-
-static void emmc_set_ext_csd(unsigned int ext_cmd, unsigned int value)
-{
- emmc_cmd_t cmd;
- int ret, state;
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD6;
- cmd.cmd_arg = EXTCSD_WRITE_BYTES | EXTCSD_CMD(ext_cmd) |
- EXTCSD_VALUE(value) | 1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- /* wait to exit PRG state */
- do {
- state = emmc_device_state();
- } while (state == EMMC_STATE_PRG);
- /* Ignore improbable errors in release builds */
- (void)ret;
-}
-
-static void emmc_set_ios(int clk, int bus_width)
-{
- int ret;
-
- /* set IO speed & IO bus width */
- if (emmc_csd.spec_vers == 4)
- emmc_set_ext_csd(CMD_EXTCSD_BUS_WIDTH, bus_width);
- ret = ops->set_ios(clk, bus_width);
- assert(ret == 0);
- /* Ignore improbable errors in release builds */
- (void)ret;
-}
-
-static int emmc_enumerate(int clk, int bus_width)
-{
- emmc_cmd_t cmd;
- int ret, state;
-
- ops->init();
-
- /* CMD0: reset to IDLE */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD0;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- while (1) {
- /* CMD1: get OCR register */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD1;
- cmd.cmd_arg = OCR_SECTOR_MODE | OCR_VDD_MIN_2V7 |
- OCR_VDD_MIN_1V7;
- cmd.resp_type = EMMC_RESPONSE_R3;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- emmc_ocr_value = cmd.resp_data[0];
- if (emmc_ocr_value & OCR_POWERUP)
- break;
- }
-
- /* CMD2: Card Identification */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD2;
- cmd.resp_type = EMMC_RESPONSE_R2;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- /* CMD3: Set Relative Address */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD3;
- cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- /* CMD9: CSD Register */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD9;
- cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
- cmd.resp_type = EMMC_RESPONSE_R2;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- memcpy(&emmc_csd, &cmd.resp_data, sizeof(cmd.resp_data));
-
- /* CMD7: Select Card */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD7;
- cmd.cmd_arg = EMMC_FIX_RCA << RCA_SHIFT_OFFSET;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- /* wait to TRAN state */
- do {
- state = emmc_device_state();
- } while (state != EMMC_STATE_TRAN);
-
- emmc_set_ios(clk, bus_width);
- return ret;
-}
-
-size_t emmc_read_blocks(int lba, uintptr_t buf, size_t size)
-{
- emmc_cmd_t cmd;
- int ret;
-
- assert((ops != 0) &&
- (ops->read != 0) &&
- ((buf & EMMC_BLOCK_MASK) == 0) &&
- ((size & EMMC_BLOCK_MASK) == 0));
-
- inv_dcache_range(buf, size);
- ret = ops->prepare(lba, buf, size);
- assert(ret == 0);
-
- if (is_cmd23_enabled()) {
- zeromem(&cmd, sizeof(emmc_cmd_t));
- /* set block count */
- cmd.cmd_idx = EMMC_CMD23;
- cmd.cmd_arg = size / EMMC_BLOCK_SIZE;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD18;
- } else {
- if (size > EMMC_BLOCK_SIZE)
- cmd.cmd_idx = EMMC_CMD18;
- else
- cmd.cmd_idx = EMMC_CMD17;
- }
- if ((emmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE)
- cmd.cmd_arg = lba * EMMC_BLOCK_SIZE;
- else
- cmd.cmd_arg = lba;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- ret = ops->read(lba, buf, size);
- assert(ret == 0);
-
- /* wait buffer empty */
- emmc_device_state();
-
- if (is_cmd23_enabled() == 0) {
- if (size > EMMC_BLOCK_SIZE) {
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD12;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- }
- }
- /* Ignore improbable errors in release builds */
- (void)ret;
- return size;
-}
-
-size_t emmc_write_blocks(int lba, const uintptr_t buf, size_t size)
-{
- emmc_cmd_t cmd;
- int ret;
-
- assert((ops != 0) &&
- (ops->write != 0) &&
- ((buf & EMMC_BLOCK_MASK) == 0) &&
- ((size & EMMC_BLOCK_MASK) == 0));
-
- clean_dcache_range(buf, size);
- ret = ops->prepare(lba, buf, size);
- assert(ret == 0);
-
- if (is_cmd23_enabled()) {
- /* set block count */
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD23;
- cmd.cmd_arg = size / EMMC_BLOCK_SIZE;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD25;
- } else {
- zeromem(&cmd, sizeof(emmc_cmd_t));
- if (size > EMMC_BLOCK_SIZE)
- cmd.cmd_idx = EMMC_CMD25;
- else
- cmd.cmd_idx = EMMC_CMD24;
- }
- if ((emmc_ocr_value & OCR_ACCESS_MODE_MASK) == OCR_BYTE_MODE)
- cmd.cmd_arg = lba * EMMC_BLOCK_SIZE;
- else
- cmd.cmd_arg = lba;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- ret = ops->write(lba, buf, size);
- assert(ret == 0);
-
- /* wait buffer empty */
- emmc_device_state();
-
- if (is_cmd23_enabled() == 0) {
- if (size > EMMC_BLOCK_SIZE) {
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD12;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
- }
- }
- /* Ignore improbable errors in release builds */
- (void)ret;
- return size;
-}
-
-size_t emmc_erase_blocks(int lba, size_t size)
-{
- emmc_cmd_t cmd;
- int ret, state;
-
- assert(ops != 0);
- assert((size != 0) && ((size % EMMC_BLOCK_SIZE) == 0));
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD35;
- cmd.cmd_arg = lba;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD36;
- cmd.cmd_arg = lba + (size / EMMC_BLOCK_SIZE) - 1;
- cmd.resp_type = EMMC_RESPONSE_R1;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- zeromem(&cmd, sizeof(emmc_cmd_t));
- cmd.cmd_idx = EMMC_CMD38;
- cmd.resp_type = EMMC_RESPONSE_R1B;
- ret = ops->send_cmd(&cmd);
- assert(ret == 0);
-
- /* wait to TRAN state */
- do {
- state = emmc_device_state();
- } while (state != EMMC_STATE_TRAN);
- /* Ignore improbable errors in release builds */
- (void)ret;
- return size;
-}
-
-static inline void emmc_rpmb_enable(void)
-{
- emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
- PART_CFG_BOOT_PARTITION1_ENABLE |
- PART_CFG_PARTITION1_ACCESS);
-}
-
-static inline void emmc_rpmb_disable(void)
-{
- emmc_set_ext_csd(CMD_EXTCSD_PARTITION_CONFIG,
- PART_CFG_BOOT_PARTITION1_ENABLE);
-}
-
-size_t emmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size)
-{
- size_t size_read;
-
- emmc_rpmb_enable();
- size_read = emmc_read_blocks(lba, buf, size);
- emmc_rpmb_disable();
- return size_read;
-}
-
-size_t emmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size)
-{
- size_t size_written;
-
- emmc_rpmb_enable();
- size_written = emmc_write_blocks(lba, buf, size);
- emmc_rpmb_disable();
- return size_written;
-}
-
-size_t emmc_rpmb_erase_blocks(int lba, size_t size)
-{
- size_t size_erased;
-
- emmc_rpmb_enable();
- size_erased = emmc_erase_blocks(lba, size);
- emmc_rpmb_disable();
- return size_erased;
-}
-
-void emmc_init(const emmc_ops_t *ops_ptr, int clk, int width,
- unsigned int flags)
-{
- assert((ops_ptr != 0) &&
- (ops_ptr->init != 0) &&
- (ops_ptr->send_cmd != 0) &&
- (ops_ptr->set_ios != 0) &&
- (ops_ptr->prepare != 0) &&
- (ops_ptr->read != 0) &&
- (ops_ptr->write != 0) &&
- (clk != 0) &&
- ((width == EMMC_BUS_WIDTH_1) ||
- (width == EMMC_BUS_WIDTH_4) ||
- (width == EMMC_BUS_WIDTH_8) ||
- (width == EMMC_BUS_WIDTH_DDR_4) ||
- (width == EMMC_BUS_WIDTH_DDR_8)));
- ops = ops_ptr;
- emmc_flags = flags;
-
- emmc_enumerate(clk, width);
-}
diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c
index 6e7103dbe..9d6c763e8 100644
--- a/drivers/io/io_fip.c
+++ b/drivers/io/io_fip.c
@@ -372,7 +372,6 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
uintptr_t backend_handle;
assert(entity != NULL);
- assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL);
assert(entity->info != (uintptr_t)NULL);
diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c
index bf59d6a5c..5595e60a4 100644
--- a/drivers/io/io_memmap.c
+++ b/drivers/io/io_memmap.c
@@ -9,6 +9,7 @@
#include <io_driver.h>
#include <io_memmap.h>
#include <io_storage.h>
+#include <platform_def.h>
#include <string.h>
#include <utils.h>
@@ -169,7 +170,6 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t pos_after;
assert(entity != NULL);
- assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL);
fp = (file_state_t *) entity->info;
@@ -197,7 +197,6 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
size_t pos_after;
assert(entity != NULL);
- assert(buffer != (uintptr_t)NULL);
assert(length_written != NULL);
fp = (file_state_t *) entity->info;
diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c
index 4abf44f7d..9ca0a9dc9 100644
--- a/drivers/io/io_semihosting.c
+++ b/drivers/io/io_semihosting.c
@@ -8,6 +8,7 @@
#include <io_driver.h>
#include <io_semihosting.h>
#include <io_storage.h>
+#include <platform_def.h>
#include <semihosting.h>
@@ -133,7 +134,6 @@ static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
long file_handle;
assert(entity != NULL);
- assert(buffer != (uintptr_t)NULL);
assert(length_read != NULL);
file_handle = (long)entity->info;
@@ -158,7 +158,6 @@ static int sh_file_write(io_entity_t *entity, const uintptr_t buffer,
size_t bytes = length;
assert(entity != NULL);
- assert(buffer != (uintptr_t)NULL);
assert(length_written != NULL);
file_handle = (long)entity->info;
diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c
index 0918de0a2..948f84813 100644
--- a/drivers/io/io_storage.c
+++ b/drivers/io/io_storage.c
@@ -279,7 +279,7 @@ int io_read(uintptr_t handle,
size_t *length_read)
{
int result = -ENODEV;
- assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL));
+ assert(is_valid_entity(handle));
io_entity_t *entity = (io_entity_t *)handle;
@@ -299,7 +299,7 @@ int io_write(uintptr_t handle,
size_t *length_written)
{
int result = -ENODEV;
- assert(is_valid_entity(handle) && (buffer != (uintptr_t)NULL));
+ assert(is_valid_entity(handle));
io_entity_t *entity = (io_entity_t *)handle;
diff --git a/drivers/marvell/amb_adec.c b/drivers/marvell/amb_adec.c
new file mode 100644
index 000000000..3fb2f3890
--- /dev/null
+++ b/drivers/marvell/amb_adec.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */
+
+#include <a8k_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+#define DEBUG_ADDR_MAP
+#endif
+
+/* common defines */
+#define WIN_ENABLE_BIT (0x1)
+
+#define MVEBU_AMB_ADEC_OFFSET (0x70ff00)
+
+#define AMB_WIN_CR_OFFSET(win) (amb_base + 0x0 + (0x8 * win))
+#define AMB_ATTR_OFFSET 8
+#define AMB_ATTR_MASK 0xFF
+#define AMB_SIZE_OFFSET 16
+#define AMB_SIZE_MASK 0xFF
+
+#define AMB_WIN_BASE_OFFSET(win) (amb_base + 0x4 + (0x8 * win))
+#define AMB_BASE_OFFSET 16
+#define AMB_BASE_ADDR_MASK ((1 << (32 - AMB_BASE_OFFSET)) - 1)
+
+#define AMB_WIN_ALIGNMENT_64K (0x10000)
+#define AMB_WIN_ALIGNMENT_1M (0x100000)
+
+uintptr_t amb_base;
+
+static void amb_check_win(struct addr_map_win *win, uint32_t win_num)
+{
+ uint32_t base_addr;
+
+ /* make sure the base address is in 16-bit range */
+ if (win->base_addr > AMB_BASE_ADDR_MASK) {
+ WARN("Window %d: base address is too big 0x%llx\n",
+ win_num, win->base_addr);
+ win->base_addr = AMB_BASE_ADDR_MASK;
+ WARN("Set the base address to 0x%llx\n", win->base_addr);
+ }
+
+ base_addr = win->base_addr << AMB_BASE_OFFSET;
+ /* for AMB The base is always 1M aligned */
+ /* check if address is aligned to 1M */
+ if (IS_NOT_ALIGN(base_addr, AMB_WIN_ALIGNMENT_1M)) {
+ win->base_addr = ALIGN_UP(base_addr, AMB_WIN_ALIGNMENT_1M);
+ WARN("Window %d: base address unaligned to 0x%x\n",
+ win_num, AMB_WIN_ALIGNMENT_1M);
+ WARN("Align up the base address to 0x%llx\n", win->base_addr);
+ }
+
+ /* size parameter validity check */
+ if (!IS_POWER_OF_2(win->win_size)) {
+ WARN("Window %d: window size is not power of 2 (0x%llx)\n",
+ win_num, win->win_size);
+ win->win_size = ROUND_UP_TO_POW_OF_2(win->win_size);
+ WARN("Rounding size to 0x%llx\n", win->win_size);
+ }
+}
+
+static void amb_enable_win(struct addr_map_win *win, uint32_t win_num)
+{
+ uint32_t ctrl, base, size;
+
+ /*
+ * size is 64KB granularity.
+ * The number of ones specifies the size of the
+ * window in 64 KB granularity. 0 is 64KB
+ */
+ size = (win->win_size / AMB_WIN_ALIGNMENT_64K) - 1;
+ ctrl = (size << AMB_SIZE_OFFSET) | (win->target_id << AMB_ATTR_OFFSET);
+ base = win->base_addr << AMB_BASE_OFFSET;
+
+ mmio_write_32(AMB_WIN_BASE_OFFSET(win_num), base);
+ mmio_write_32(AMB_WIN_CR_OFFSET(win_num), ctrl);
+
+ /* enable window after configuring window size (and attributes) */
+ ctrl |= WIN_ENABLE_BIT;
+ mmio_write_32(AMB_WIN_CR_OFFSET(win_num), ctrl);
+}
+
+#ifdef DEBUG_ADDR_MAP
+static void dump_amb_adec(void)
+{
+ uint32_t ctrl, base, win_id, attr;
+ uint32_t size, size_count;
+
+ /* Dump all AMB windows */
+ printf("bank attribute base size\n");
+ printf("--------------------------------------------\n");
+ for (win_id = 0; win_id < AMB_MAX_WIN_ID; win_id++) {
+ ctrl = mmio_read_32(AMB_WIN_CR_OFFSET(win_id));
+ if (ctrl & WIN_ENABLE_BIT) {
+ base = mmio_read_32(AMB_WIN_BASE_OFFSET(win_id));
+ attr = (ctrl >> AMB_ATTR_OFFSET) & AMB_ATTR_MASK;
+ size_count = (ctrl >> AMB_SIZE_OFFSET) & AMB_SIZE_MASK;
+ size = (size_count + 1) * AMB_WIN_ALIGNMENT_64K;
+ printf("amb 0x%04x 0x%08x 0x%08x\n",
+ attr, base, size);
+ }
+ }
+}
+#endif
+
+int init_amb_adec(uintptr_t base)
+{
+ struct addr_map_win *win;
+ uint32_t win_id, win_reg;
+ uint32_t win_count;
+
+ INFO("Initializing AXI to MBus Bridge Address decoding\n");
+
+ /* Get the base address of the AMB address decoding */
+ amb_base = base + MVEBU_AMB_ADEC_OFFSET;
+
+ /* Get the array of the windows and its size */
+ marvell_get_amb_memory_map(&win, &win_count, base);
+ if (win_count <= 0)
+ INFO("no windows configurations found\n");
+
+ if (win_count > AMB_MAX_WIN_ID) {
+ INFO("number of windows is bigger than %d\n", AMB_MAX_WIN_ID);
+ return 0;
+ }
+
+ /* disable all AMB windows */
+ for (win_id = 0; win_id < AMB_MAX_WIN_ID; win_id++) {
+ win_reg = mmio_read_32(AMB_WIN_CR_OFFSET(win_id));
+ win_reg &= ~WIN_ENABLE_BIT;
+ mmio_write_32(AMB_WIN_CR_OFFSET(win_id), win_reg);
+ }
+
+ /* enable relevant windows */
+ for (win_id = 0; win_id < win_count; win_id++, win++) {
+ amb_check_win(win, win_id);
+ amb_enable_win(win, win_id);
+ }
+
+#ifdef DEBUG_ADDR_MAP
+ dump_amb_adec();
+#endif
+
+ INFO("Done AXI to MBus Bridge Address decoding Initializing\n");
+
+ return 0;
+}
diff --git a/drivers/marvell/cache_llc.c b/drivers/marvell/cache_llc.c
new file mode 100644
index 000000000..e13e6ce2f
--- /dev/null
+++ b/drivers/marvell/cache_llc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* LLC driver is the Last Level Cache (L3C) driver
+ * for Marvell SoCs in AP806, AP807, and AP810
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <cache_llc.h>
+#include <ccu.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#define CCU_HTC_CR(ap_index) (MVEBU_CCU_BASE(ap_index) + 0x200)
+#define CCU_SET_POC_OFFSET 5
+
+extern void ca72_l2_enable_unique_clean(void);
+
+void llc_cache_sync(int ap_index)
+{
+ mmio_write_32(LLC_SYNC(ap_index), 0);
+ /* Atomic write, no need to wait */
+}
+
+void llc_flush_all(int ap_index)
+{
+ mmio_write_32(L2X0_CLEAN_INV_WAY(ap_index), LLC_WAY_MASK);
+ llc_cache_sync(ap_index);
+}
+
+void llc_clean_all(int ap_index)
+{
+ mmio_write_32(L2X0_CLEAN_WAY(ap_index), LLC_WAY_MASK);
+ llc_cache_sync(ap_index);
+}
+
+void llc_inv_all(int ap_index)
+{
+ mmio_write_32(L2X0_INV_WAY(ap_index), LLC_WAY_MASK);
+ llc_cache_sync(ap_index);
+}
+
+void llc_disable(int ap_index)
+{
+ llc_flush_all(ap_index);
+ mmio_write_32(LLC_CTRL(ap_index), 0);
+ dsbishst();
+}
+
+void llc_enable(int ap_index, int excl_mode)
+{
+ uint32_t val;
+
+ dsbsy();
+ llc_inv_all(ap_index);
+ dsbsy();
+
+ val = LLC_CTRL_EN;
+ if (excl_mode)
+ val |= LLC_EXCLUSIVE_EN;
+
+ mmio_write_32(LLC_CTRL(ap_index), val);
+ dsbsy();
+}
+
+int llc_is_exclusive(int ap_index)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32(LLC_CTRL(ap_index));
+
+ if ((reg & (LLC_CTRL_EN | LLC_EXCLUSIVE_EN)) ==
+ (LLC_CTRL_EN | LLC_EXCLUSIVE_EN))
+ return 1;
+
+ return 0;
+}
+
+void llc_runtime_enable(int ap_index)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32(LLC_CTRL(ap_index));
+ if (reg & LLC_CTRL_EN)
+ return;
+
+ INFO("Enabling LLC\n");
+
+ /*
+ * Enable L2 UniqueClean evictions with data
+ * Note: this configuration assumes that LLC is configured
+ * in exclusive mode.
+ * Later on in the code this assumption will be validated
+ */
+ ca72_l2_enable_unique_clean();
+ llc_enable(ap_index, 1);
+
+ /* Set point of coherency to DDR.
+ * This is required by units which have SW cache coherency
+ */
+ reg = mmio_read_32(CCU_HTC_CR(ap_index));
+ reg |= (0x1 << CCU_SET_POC_OFFSET);
+ mmio_write_32(CCU_HTC_CR(ap_index), reg);
+}
diff --git a/drivers/marvell/ccu.c b/drivers/marvell/ccu.c
new file mode 100644
index 000000000..1502c3f8b
--- /dev/null
+++ b/drivers/marvell/ccu.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+
+#include <a8k_common.h>
+#include <ccu.h>
+#include <debug.h>
+#include <mmio.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+#define DEBUG_ADDR_MAP
+#endif
+
+/* common defines */
+#define WIN_ENABLE_BIT (0x1)
+/* Physical address of the base of the window = {AddrLow[19:0],20'h0} */
+#define ADDRESS_SHIFT (20 - 4)
+#define ADDRESS_MASK (0xFFFFFFF0)
+#define CCU_WIN_ALIGNMENT (0x100000)
+
+#define IS_DRAM_TARGET(tgt) ((((tgt) == DRAM_0_TID) || \
+ ((tgt) == DRAM_1_TID) || \
+ ((tgt) == RAR_TID)) ? 1 : 0)
+
+/* For storage of CR, SCR, ALR, AHR abd GCR */
+static uint32_t ccu_regs_save[MVEBU_CCU_MAX_WINS * 4 + 1];
+
+#ifdef DEBUG_ADDR_MAP
+static void dump_ccu(int ap_index)
+{
+ uint32_t win_id, win_cr, alr, ahr;
+ uint8_t target_id;
+ uint64_t start, end;
+
+ /* Dump all AP windows */
+ printf("\tbank target start end\n");
+ printf("\t----------------------------------------------------\n");
+ for (win_id = 0; win_id < MVEBU_CCU_MAX_WINS; win_id++) {
+ win_cr = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
+ if (win_cr & WIN_ENABLE_BIT) {
+ target_id = (win_cr >> CCU_TARGET_ID_OFFSET) &
+ CCU_TARGET_ID_MASK;
+ alr = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_index,
+ win_id));
+ ahr = mmio_read_32(CCU_WIN_AHR_OFFSET(ap_index,
+ win_id));
+ start = ((uint64_t)alr << ADDRESS_SHIFT);
+ end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
+ printf("\tccu %02x 0x%016llx 0x%016llx\n",
+ target_id, start, end);
+ }
+ }
+ win_cr = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_index));
+ target_id = (win_cr >> CCU_GCR_TARGET_OFFSET) & CCU_GCR_TARGET_MASK;
+ printf("\tccu GCR %d - all other transactions\n", target_id);
+}
+#endif
+
+void ccu_win_check(struct addr_map_win *win)
+{
+ /* check if address is aligned to 1M */
+ if (IS_NOT_ALIGN(win->base_addr, CCU_WIN_ALIGNMENT)) {
+ win->base_addr = ALIGN_UP(win->base_addr, CCU_WIN_ALIGNMENT);
+ NOTICE("%s: Align up the base address to 0x%llx\n",
+ __func__, win->base_addr);
+ }
+
+ /* size parameter validity check */
+ if (IS_NOT_ALIGN(win->win_size, CCU_WIN_ALIGNMENT)) {
+ win->win_size = ALIGN_UP(win->win_size, CCU_WIN_ALIGNMENT);
+ NOTICE("%s: Aligning size to 0x%llx\n",
+ __func__, win->win_size);
+ }
+}
+
+void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id)
+{
+ uint32_t ccu_win_reg;
+ uint32_t alr, ahr;
+ uint64_t end_addr;
+
+ if ((win_id == 0) || (win_id > MVEBU_CCU_MAX_WINS)) {
+ ERROR("Enabling wrong CCU window %d!\n", win_id);
+ return;
+ }
+
+ end_addr = (win->base_addr + win->win_size - 1);
+ alr = (uint32_t)((win->base_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+ ahr = (uint32_t)((end_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+
+ mmio_write_32(CCU_WIN_ALR_OFFSET(ap_index, win_id), alr);
+ mmio_write_32(CCU_WIN_AHR_OFFSET(ap_index, win_id), ahr);
+
+ ccu_win_reg = WIN_ENABLE_BIT;
+ ccu_win_reg |= (win->target_id & CCU_TARGET_ID_MASK)
+ << CCU_TARGET_ID_OFFSET;
+ mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), ccu_win_reg);
+}
+
+static void ccu_disable_win(int ap_index, uint32_t win_id)
+{
+ uint32_t win_reg;
+
+ if ((win_id == 0) || (win_id > MVEBU_CCU_MAX_WINS)) {
+ ERROR("Disabling wrong CCU window %d!\n", win_id);
+ return;
+ }
+
+ win_reg = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
+ win_reg &= ~WIN_ENABLE_BIT;
+ mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), win_reg);
+}
+
+/* Insert/Remove temporary window for using the out-of reset default
+ * CPx base address to access the CP configuration space prior to
+ * the further base address update in accordance with address mapping
+ * design.
+ *
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void ccu_temp_win_insert(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ for (int i = 0; i < size; i++) {
+ win_id = MVEBU_CCU_MAX_WINS - 1 - i;
+ ccu_win_check(win);
+ ccu_enable_win(ap_index, win, win_id);
+ win++;
+ }
+}
+
+/*
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void ccu_temp_win_remove(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ for (int i = 0; i < size; i++) {
+ uint64_t base;
+ uint32_t target;
+
+ win_id = MVEBU_CCU_MAX_WINS - 1 - i;
+
+ target = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
+ target >>= CCU_TARGET_ID_OFFSET;
+ target &= CCU_TARGET_ID_MASK;
+
+ base = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_index, win_id));
+ base <<= ADDRESS_SHIFT;
+
+ if ((win->target_id != target) || (win->base_addr != base)) {
+ ERROR("%s: Trying to remove bad window-%d!\n",
+ __func__, win_id);
+ continue;
+ }
+ ccu_disable_win(ap_index, win_id);
+ win++;
+ }
+}
+
+/* Returns current DRAM window target (DRAM_0_TID, DRAM_1_TID, RAR_TID)
+ * NOTE: Call only once for each AP.
+ * The AP0 DRAM window is located at index 2 only at the BL31 execution start.
+ * Then it relocated to index 1 for matching the rest of APs DRAM settings.
+ * Calling this function after relocation will produce wrong results on AP0
+ */
+static uint32_t ccu_dram_target_get(int ap_index)
+{
+ /* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
+ * All the rest of detected APs will use window at index 1.
+ * The AP0 DRAM window is moved from index 2 to 1 during
+ * init_ccu() execution.
+ */
+ const uint32_t win_id = (ap_index == 0) ? 2 : 1;
+ uint32_t target;
+
+ target = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
+ target >>= CCU_TARGET_ID_OFFSET;
+ target &= CCU_TARGET_ID_MASK;
+
+ return target;
+}
+
+void ccu_dram_target_set(int ap_index, uint32_t target)
+{
+ /* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
+ * All the rest of detected APs will use window at index 1.
+ * The AP0 DRAM window is moved from index 2 to 1
+ * during init_ccu() execution.
+ */
+ const uint32_t win_id = (ap_index == 0) ? 2 : 1;
+ uint32_t dram_cr;
+
+ dram_cr = mmio_read_32(CCU_WIN_CR_OFFSET(ap_index, win_id));
+ dram_cr &= ~(CCU_TARGET_ID_MASK << CCU_TARGET_ID_OFFSET);
+ dram_cr |= (target & CCU_TARGET_ID_MASK) << CCU_TARGET_ID_OFFSET;
+ mmio_write_32(CCU_WIN_CR_OFFSET(ap_index, win_id), dram_cr);
+}
+
+/* Setup CCU DRAM window and enable it */
+void ccu_dram_win_config(int ap_index, struct addr_map_win *win)
+{
+#if IMAGE_BLE /* BLE */
+ /* On BLE stage the AP0 DRAM window is opened by the BootROM at index 2.
+ * Since the BootROM is not accessing DRAM at BLE stage,
+ * the DRAM window can be temporarely disabled.
+ */
+ const uint32_t win_id = (ap_index == 0) ? 2 : 1;
+#else /* end of BLE */
+ /* At the ccu_init() execution stage, DRAM windows of all APs
+ * are arranged at index 1.
+ * The AP0 still has the old window BootROM DRAM at index 2, so
+ * the window-1 can be safely disabled without breaking the DRAM access.
+ */
+ const uint32_t win_id = 1;
+#endif
+
+ ccu_disable_win(ap_index, win_id);
+ /* enable write secure (and clear read secure) */
+ mmio_write_32(CCU_WIN_SCR_OFFSET(ap_index, win_id),
+ CCU_WIN_ENA_WRITE_SECURE);
+ ccu_win_check(win);
+ ccu_enable_win(ap_index, win, win_id);
+}
+
+/* Save content of CCU window + GCR */
+static void ccu_save_win_range(int ap_id, int win_first,
+ int win_last, uint32_t *buffer)
+{
+ int win_id, idx;
+ /* Save CCU */
+ for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
+ buffer[idx++] = mmio_read_32(CCU_WIN_CR_OFFSET(ap_id, win_id));
+ buffer[idx++] = mmio_read_32(CCU_WIN_SCR_OFFSET(ap_id, win_id));
+ buffer[idx++] = mmio_read_32(CCU_WIN_ALR_OFFSET(ap_id, win_id));
+ buffer[idx++] = mmio_read_32(CCU_WIN_AHR_OFFSET(ap_id, win_id));
+ }
+ buffer[idx] = mmio_read_32(CCU_WIN_GCR_OFFSET(ap_id));
+}
+
+/* Restore content of CCU window + GCR */
+static void ccu_restore_win_range(int ap_id, int win_first,
+ int win_last, uint32_t *buffer)
+{
+ int win_id, idx;
+ /* Restore CCU */
+ for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
+ mmio_write_32(CCU_WIN_CR_OFFSET(ap_id, win_id), buffer[idx++]);
+ mmio_write_32(CCU_WIN_SCR_OFFSET(ap_id, win_id), buffer[idx++]);
+ mmio_write_32(CCU_WIN_ALR_OFFSET(ap_id, win_id), buffer[idx++]);
+ mmio_write_32(CCU_WIN_AHR_OFFSET(ap_id, win_id), buffer[idx++]);
+ }
+ mmio_write_32(CCU_WIN_GCR_OFFSET(ap_id), buffer[idx]);
+}
+
+void ccu_save_win_all(int ap_id)
+{
+ ccu_save_win_range(ap_id, 0, MVEBU_CCU_MAX_WINS - 1, ccu_regs_save);
+}
+
+void ccu_restore_win_all(int ap_id)
+{
+ ccu_restore_win_range(ap_id, 0, MVEBU_CCU_MAX_WINS - 1, ccu_regs_save);
+}
+
+int init_ccu(int ap_index)
+{
+ struct addr_map_win *win, *dram_win;
+ uint32_t win_id, win_reg;
+ uint32_t win_count, array_id;
+ uint32_t dram_target;
+#if IMAGE_BLE
+ /* In BootROM context CCU Window-1
+ * has SRAM_TID target and should not be disabled
+ */
+ const uint32_t win_start = 2;
+#else
+ const uint32_t win_start = 1;
+#endif
+
+ INFO("Initializing CCU Address decoding\n");
+
+ /* Get the array of the windows and fill the map data */
+ marvell_get_ccu_memory_map(ap_index, &win, &win_count);
+ if (win_count <= 0) {
+ INFO("No windows configurations found\n");
+ } else if (win_count > (MVEBU_CCU_MAX_WINS - 1)) {
+ ERROR("CCU mem map array > than max available windows (%d)\n",
+ MVEBU_CCU_MAX_WINS);
+ win_count = MVEBU_CCU_MAX_WINS;
+ }
+
+ /* Need to set GCR to DRAM before all CCU windows are disabled for
+ * securing the normal access to DRAM location, which the ATF is running
+ * from. Once all CCU windows are set, which have to include the
+ * dedicated DRAM window as well, the GCR can be switched to the target
+ * defined by the platform configuration.
+ */
+ dram_target = ccu_dram_target_get(ap_index);
+ win_reg = (dram_target & CCU_GCR_TARGET_MASK) << CCU_GCR_TARGET_OFFSET;
+ mmio_write_32(CCU_WIN_GCR_OFFSET(ap_index), win_reg);
+
+ /* If the DRAM window was already configured at the BLE stage,
+ * only the window target considered valid, the address range should be
+ * updated according to the platform configuration.
+ */
+ for (dram_win = win, array_id = 0; array_id < win_count;
+ array_id++, dram_win++) {
+ if (IS_DRAM_TARGET(dram_win->target_id)) {
+ dram_win->target_id = dram_target;
+ break;
+ }
+ }
+
+ /* Disable all AP CCU windows
+ * Window-0 is always bypassed since it already contains
+ * data allowing the internal configuration space access
+ */
+ for (win_id = win_start; win_id < MVEBU_CCU_MAX_WINS; win_id++) {
+ ccu_disable_win(ap_index, win_id);
+ /* enable write secure (and clear read secure) */
+ mmio_write_32(CCU_WIN_SCR_OFFSET(ap_index, win_id),
+ CCU_WIN_ENA_WRITE_SECURE);
+ }
+
+ /* win_id is the index of the current ccu window
+ * array_id is the index of the current memory map window entry
+ */
+ for (win_id = win_start, array_id = 0;
+ ((win_id < MVEBU_CCU_MAX_WINS) && (array_id < win_count));
+ win_id++) {
+ ccu_win_check(win);
+ ccu_enable_win(ap_index, win, win_id);
+ win++;
+ array_id++;
+ }
+
+ /* Get & set the default target according to board topology */
+ win_reg = (marvell_get_ccu_gcr_target(ap_index) & CCU_GCR_TARGET_MASK)
+ << CCU_GCR_TARGET_OFFSET;
+ mmio_write_32(CCU_WIN_GCR_OFFSET(ap_index), win_reg);
+
+#ifdef DEBUG_ADDR_MAP
+ dump_ccu(ap_index);
+#endif
+
+ INFO("Done CCU Address decoding Initializing\n");
+
+ return 0;
+}
diff --git a/drivers/marvell/comphy.h b/drivers/marvell/comphy.h
new file mode 100644
index 000000000..788b1b605
--- /dev/null
+++ b/drivers/marvell/comphy.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Driver for COMPHY unit that is part or Marvell A8K SoCs */
+
+#ifndef _COMPHY_H_
+#define _COMPHY_H_
+
+/* COMPHY registers */
+#define COMMON_PHY_CFG1_REG 0x0
+#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1
+#define COMMON_PHY_CFG1_PWR_UP_MASK \
+ (0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET)
+#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2
+#define COMMON_PHY_CFG1_PIPE_SELECT_MASK \
+ (0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET)
+#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 13
+#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK \
+ (0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET)
+#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 14
+#define COMMON_PHY_CFG1_CORE_RSTN_MASK \
+ (0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET)
+#define COMMON_PHY_PHY_MODE_OFFSET 15
+#define COMMON_PHY_PHY_MODE_MASK \
+ (0x1 << COMMON_PHY_PHY_MODE_OFFSET)
+
+#define COMMON_SELECTOR_PHY_OFFSET 0x140
+#define COMMON_SELECTOR_PIPE_OFFSET 0x144
+
+#define COMMON_PHY_SD_CTRL1 0x148
+#define COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_OFFSET 0
+#define COMMON_PHY_SD_CTRL1_COMPHY_0_4_PORT_MASK 0xFFFF
+#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET 24
+#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET)
+#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET 25
+#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET)
+
+#define DFX_DEV_GEN_CTRL12 0x80
+#define DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET 7
+#define DFX_DEV_GEN_PCIE_CLK_SRC_MASK \
+ (0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET)
+
+/* HPIPE register */
+#define HPIPE_PWR_PLL_REG 0x4
+#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0
+#define HPIPE_PWR_PLL_REF_FREQ_MASK \
+ (0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET)
+#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5
+#define HPIPE_PWR_PLL_PHY_MODE_MASK \
+ (0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET)
+
+#define HPIPE_DFE_REG0 0x01C
+#define HPIPE_DFE_RES_FORCE_OFFSET 15
+#define HPIPE_DFE_RES_FORCE_MASK \
+ (0x1 << HPIPE_DFE_RES_FORCE_OFFSET)
+
+#define HPIPE_G2_SET_1_REG 0x040
+#define HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET 0
+#define HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK \
+ (0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET 3
+#define HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK \
+ (0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET 6
+#define HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK \
+ (0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET)
+
+#define HPIPE_G3_SETTINGS_1_REG 0x048
+#define HPIPE_G3_RX_SELMUPI_OFFSET 0
+#define HPIPE_G3_RX_SELMUPI_MASK \
+ (0x7 << HPIPE_G3_RX_SELMUPI_OFFSET)
+#define HPIPE_G3_RX_SELMUPF_OFFSET 3
+#define HPIPE_G3_RX_SELMUPF_MASK \
+ (0x7 << HPIPE_G3_RX_SELMUPF_OFFSET)
+#define HPIPE_G3_SETTING_BIT_OFFSET 13
+#define HPIPE_G3_SETTING_BIT_MASK \
+ (0x1 << HPIPE_G3_SETTING_BIT_OFFSET)
+
+#define HPIPE_INTERFACE_REG 0x94
+#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10
+#define HPIPE_INTERFACE_GEN_MAX_MASK \
+ (0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET)
+#define HPIPE_INTERFACE_DET_BYPASS_OFFSET 12
+#define HPIPE_INTERFACE_DET_BYPASS_MASK \
+ (0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET)
+#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14
+#define HPIPE_INTERFACE_LINK_TRAIN_MASK \
+ (0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET)
+
+#define HPIPE_VDD_CAL_CTRL_REG 0x114
+#define HPIPE_EXT_SELLV_RXSAMPL_OFFSET 5
+#define HPIPE_EXT_SELLV_RXSAMPL_MASK \
+ (0x1f << HPIPE_EXT_SELLV_RXSAMPL_OFFSET)
+
+#define HPIPE_PCIE_REG0 0x120
+#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12
+#define HPIPE_PCIE_IDLE_SYNC_MASK \
+ (0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET)
+#define HPIPE_PCIE_SEL_BITS_OFFSET 13
+#define HPIPE_PCIE_SEL_BITS_MASK \
+ (0x3 << HPIPE_PCIE_SEL_BITS_OFFSET)
+
+#define HPIPE_LANE_ALIGN_REG 0x124
+#define HPIPE_LANE_ALIGN_OFF_OFFSET 12
+#define HPIPE_LANE_ALIGN_OFF_MASK \
+ (0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET)
+
+#define HPIPE_MISC_REG 0x13C
+#define HPIPE_MISC_CLK100M_125M_OFFSET 4
+#define HPIPE_MISC_CLK100M_125M_MASK \
+ (0x1 << HPIPE_MISC_CLK100M_125M_OFFSET)
+#define HPIPE_MISC_ICP_FORCE_OFFSET 5
+#define HPIPE_MISC_ICP_FORCE_MASK \
+ (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET)
+#define HPIPE_MISC_TXDCLK_2X_OFFSET 6
+#define HPIPE_MISC_TXDCLK_2X_MASK \
+ (0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET)
+#define HPIPE_MISC_CLK500_EN_OFFSET 7
+#define HPIPE_MISC_CLK500_EN_MASK \
+ (0x1 << HPIPE_MISC_CLK500_EN_OFFSET)
+#define HPIPE_MISC_REFCLK_SEL_OFFSET 10
+#define HPIPE_MISC_REFCLK_SEL_MASK \
+ (0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET)
+
+#define HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG 0x16C
+#define HPIPE_SMAPLER_OFFSET 12
+#define HPIPE_SMAPLER_MASK (0x1 << HPIPE_SMAPLER_OFFSET)
+
+#define HPIPE_PWR_CTR_DTL_REG 0x184
+#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 2
+#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK \
+ (0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET)
+
+#define HPIPE_FRAME_DET_CONTROL_REG 0x220
+#define HPIPE_FRAME_DET_LOCK_LOST_TO_OFFSET 12
+#define HPIPE_FRAME_DET_LOCK_LOST_TO_MASK \
+ (0x1 << HPIPE_FRAME_DET_LOCK_LOST_TO_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_0_REG 0x268
+#define HPIPE_TX_TRAIN_P2P_HOLD_OFFSET 15
+#define HPIPE_TX_TRAIN_P2P_HOLD_MASK \
+ (0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_REG 0x26C
+#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0
+#define HPIPE_TX_TRAIN_CTRL_G1_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET)
+#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1
+#define HPIPE_TX_TRAIN_CTRL_GN1_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET)
+#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2
+#define HPIPE_TX_TRAIN_CTRL_G0_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_4_REG 0x278
+#define HPIPE_TRX_TRAIN_TIMER_OFFSET 0
+#define HPIPE_TRX_TRAIN_TIMER_MASK \
+ (0x3FF << HPIPE_TRX_TRAIN_TIMER_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_5_REG 0x2A4
+#define HPIPE_TX_TRAIN_START_SQ_EN_OFFSET 11
+#define HPIPE_TX_TRAIN_START_SQ_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET)
+#define HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET 12
+#define HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET)
+#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET 13
+#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET)
+#define HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET 14
+#define HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET)
+
+#define HPIPE_TX_TRAIN_REG 0x31C
+#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4
+#define HPIPE_TX_TRAIN_CHK_INIT_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET)
+#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7
+#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK \
+ (0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET)
+
+#define HPIPE_CDR_CONTROL_REG 0x418
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \
+ (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET)
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \
+ (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET)
+#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9
+#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \
+ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET)
+#define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6
+#define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \
+ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_11_REG 0x438
+#define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6
+#define HPIPE_TX_TX_STATUS_CHECK_MODE_MASK \
+ (0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET)
+#define HPIPE_TX_NUM_OF_PRESET_OFFSET 10
+#define HPIPE_TX_NUM_OF_PRESET_MASK \
+ (0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET)
+#define HPIPE_TX_SWEEP_PRESET_EN_OFFSET 15
+#define HPIPE_TX_SWEEP_PRESET_EN_MASK \
+ (0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET)
+#define HPIPE_G2_SETTINGS_4_REG 0x44C
+#define HPIPE_G2_DFE_RES_OFFSET 8
+#define HPIPE_G2_DFE_RES_MASK (0x3 << HPIPE_G2_DFE_RES_OFFSET)
+
+#define HPIPE_G3_SETTING_3_REG 0x450
+#define HPIPE_G3_FFE_CAP_SEL_OFFSET 0
+#define HPIPE_G3_FFE_CAP_SEL_MASK \
+ (0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET)
+#define HPIPE_G3_FFE_RES_SEL_OFFSET 4
+#define HPIPE_G3_FFE_RES_SEL_MASK \
+ (0x7 << HPIPE_G3_FFE_RES_SEL_OFFSET)
+#define HPIPE_G3_FFE_SETTING_FORCE_OFFSET 7
+#define HPIPE_G3_FFE_SETTING_FORCE_MASK \
+ (0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET)
+#define HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET 12
+#define HPIPE_G3_FFE_DEG_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET)
+#define HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET 14
+#define HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET)
+
+#define HPIPE_G3_SETTING_4_REG 0x454
+#define HPIPE_G3_DFE_RES_OFFSET 8
+#define HPIPE_G3_DFE_RES_MASK (0x3 << HPIPE_G3_DFE_RES_OFFSET)
+
+#define HPIPE_DFE_CONTROL_REG 0x470
+#define HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET 14
+#define HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK \
+ (0x3 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET)
+
+#define HPIPE_DFE_CTRL_28_REG 0x49C
+#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7
+#define HPIPE_DFE_CTRL_28_PIPE4_MASK \
+ (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET)
+
+#define HPIPE_G3_SETTING_5_REG 0x548
+#define HPIPE_G3_SETTING_5_G3_ICP_OFFSET 0
+#define HPIPE_G3_SETTING_5_G3_ICP_MASK \
+ (0xf << HPIPE_G3_SETTING_5_G3_ICP_OFFSET)
+
+#define HPIPE_LANE_STATUS1_REG 0x60C
+#define HPIPE_LANE_STATUS1_PCLK_EN_OFFSET 0
+#define HPIPE_LANE_STATUS1_PCLK_EN_MASK \
+ (0x1 << HPIPE_LANE_STATUS1_PCLK_EN_OFFSET)
+
+#define HPIPE_LANE_CFG4_REG 0x620
+#define HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET 3
+#define HPIPE_LANE_CFG4_DFE_EN_SEL_MASK \
+ (0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET)
+
+#define HPIPE_LANE_EQU_CONFIG_0_REG 0x69C
+#define HPIPE_CFG_EQ_FS_OFFSET 0
+#define HPIPE_CFG_EQ_FS_MASK (0x3f << HPIPE_CFG_EQ_FS_OFFSET)
+#define HPIPE_CFG_EQ_LF_OFFSET 6
+#define HPIPE_CFG_EQ_LF_MASK (0x3f << HPIPE_CFG_EQ_LF_OFFSET)
+#define HPIPE_CFG_PHY_RC_EP_OFFSET 12
+#define HPIPE_CFG_PHY_RC_EP_MASK \
+ (0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET)
+
+#define HPIPE_LANE_EQ_CFG1_REG 0x6a0
+#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12
+#define HPIPE_CFG_UPDATE_POLARITY_MASK \
+ (0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET)
+
+#define HPIPE_LANE_EQ_CFG2_REG 0x6a4
+#define HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET 14
+#define HPIPE_CFG_EQ_BUNDLE_DIS_MASK \
+ (0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG0_REG 0x6a8
+#define HPIPE_CFG_CURSOR_PRESET0_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET0_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET0_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET1_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET1_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET1_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG1_REG 0x6ac
+#define HPIPE_CFG_CURSOR_PRESET2_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET2_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET2_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET3_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET3_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET3_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG2_REG 0x6b0
+#define HPIPE_CFG_CURSOR_PRESET4_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET4_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET4_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET5_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET5_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET5_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG3_REG 0x6b4
+#define HPIPE_CFG_CURSOR_PRESET6_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET6_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET6_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET7_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET7_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET7_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG4_REG 0x6b8
+#define HPIPE_CFG_CURSOR_PRESET8_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET8_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET8_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET9_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET9_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET9_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG5_REG 0x6bc
+#define HPIPE_CFG_CURSOR_PRESET10_OFFSET 0
+#define HPIPE_CFG_CURSOR_PRESET10_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET10_OFFSET)
+#define HPIPE_CFG_CURSOR_PRESET11_OFFSET 6
+#define HPIPE_CFG_CURSOR_PRESET11_MASK \
+ (0x3f << HPIPE_CFG_CURSOR_PRESET11_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG6_REG 0x6c0
+#define HPIPE_CFG_PRE_CURSOR_PRESET0_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET0_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET0_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET0_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET0_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET0_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG7_REG 0x6c4
+#define HPIPE_CFG_PRE_CURSOR_PRESET1_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET1_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET1_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET1_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET1_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET1_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG8_REG 0x6c8
+#define HPIPE_CFG_PRE_CURSOR_PRESET2_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET2_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET2_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET2_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET2_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET2_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG9_REG 0x6cc
+#define HPIPE_CFG_PRE_CURSOR_PRESET3_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET3_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET3_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET3_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET3_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET3_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG10_REG 0x6d0
+#define HPIPE_CFG_PRE_CURSOR_PRESET4_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET4_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET4_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET4_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET4_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET4_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG11_REG 0x6d4
+#define HPIPE_CFG_PRE_CURSOR_PRESET5_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET5_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET5_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET5_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET5_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET5_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG12_REG 0x6d8
+#define HPIPE_CFG_PRE_CURSOR_PRESET6_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET6_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET6_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET6_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET6_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET6_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG13_REG 0x6dc
+#define HPIPE_CFG_PRE_CURSOR_PRESET7_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET7_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET7_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET7_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET7_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET7_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG14_REG 0x6e0
+#define HPIPE_CFG_PRE_CURSOR_PRESET8_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET8_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET8_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET8_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET8_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET8_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG15_REG 0x6e4
+#define HPIPE_CFG_PRE_CURSOR_PRESET9_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET9_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET9_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET9_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET9_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET9_OFFSET)
+
+#define HPIPE_LANE_PRESET_CFG16_REG 0x6e8
+#define HPIPE_CFG_PRE_CURSOR_PRESET10_OFFSET 0
+#define HPIPE_CFG_PRE_CURSOR_PRESET10_MASK \
+ (0x3f << HPIPE_CFG_PRE_CURSOR_PRESET10_OFFSET)
+#define HPIPE_CFG_POST_CURSOR_PRESET10_OFFSET 6
+#define HPIPE_CFG_POST_CURSOR_PRESET10_MASK \
+ (0x3f << HPIPE_CFG_POST_CURSOR_PRESET10_OFFSET)
+
+#define HPIPE_LANE_EQ_REMOTE_SETTING_REG 0x6f8
+#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET 0
+#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK \
+ (0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET)
+#define HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET 1
+#define HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK \
+ (0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET)
+#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET 2
+#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK \
+ (0xf << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET)
+
+#define HPIPE_RST_CLK_CTRL_REG 0x704
+#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0
+#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET)
+#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2
+#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET)
+#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3
+#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET)
+#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9
+#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET)
+
+#define HPIPE_CLK_SRC_LO_REG 0x70c
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET 1
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK \
+ (0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET)
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET 2
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK \
+ (0x3 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET)
+#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5
+#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK \
+ (0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET)
+
+#define HPIPE_CLK_SRC_HI_REG 0x710
+#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0
+#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET)
+#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1
+#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET)
+#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2
+#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET)
+#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7
+#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET)
+
+#define HPIPE_GLOBAL_PM_CTRL 0x740
+#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0
+#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK \
+ (0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET)
+
+#endif /* _COMPHY_H_ */
+
diff --git a/drivers/marvell/comphy/comphy-cp110.h b/drivers/marvell/comphy/comphy-cp110.h
new file mode 100644
index 000000000..925abb5e5
--- /dev/null
+++ b/drivers/marvell/comphy/comphy-cp110.h
@@ -0,0 +1,775 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Marvell CP110 SoC COMPHY unit driver */
+
+#ifndef _PHY_COMPHY_CP110_H
+#define _PHY_COMPHY_CP110_H
+
+#define SD_ADDR(base, lane) (base + 0x1000 * lane)
+#define HPIPE_ADDR(base, lane) (SD_ADDR(base, lane) + 0x800)
+#define COMPHY_ADDR(base, lane) (base + 0x28 * lane)
+
+#define MAX_NUM_OF_FFE 8
+#define RX_TRAINING_TIMEOUT 500
+
+/* Comphy registers */
+#define COMMON_PHY_CFG1_REG 0x0
+#define COMMON_PHY_CFG1_PWR_UP_OFFSET 1
+#define COMMON_PHY_CFG1_PWR_UP_MASK \
+ (0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET)
+#define COMMON_PHY_CFG1_PIPE_SELECT_OFFSET 2
+#define COMMON_PHY_CFG1_PIPE_SELECT_MASK \
+ (0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET)
+#define COMMON_PHY_CFG1_CORE_RSTN_OFFSET 13
+#define COMMON_PHY_CFG1_CORE_RSTN_MASK \
+ (0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET)
+#define COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET 14
+#define COMMON_PHY_CFG1_PWR_ON_RESET_MASK \
+ (0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET)
+#define COMMON_PHY_PHY_MODE_OFFSET 15
+#define COMMON_PHY_PHY_MODE_MASK \
+ (0x1 << COMMON_PHY_PHY_MODE_OFFSET)
+
+#define COMMON_PHY_CFG6_REG 0x14
+#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18
+#define COMMON_PHY_CFG6_IF_40_SEL_MASK \
+ (0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET)
+
+#define COMMON_PHY_CFG6_REG 0x14
+#define COMMON_PHY_CFG6_IF_40_SEL_OFFSET 18
+#define COMMON_PHY_CFG6_IF_40_SEL_MASK \
+ (0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET)
+
+#define COMMON_SELECTOR_PHY_REG_OFFSET 0x140
+#define COMMON_SELECTOR_PIPE_REG_OFFSET 0x144
+#define COMMON_SELECTOR_COMPHY_MASK 0xf
+#define COMMON_SELECTOR_COMPHYN_FIELD_WIDTH 4
+#define COMMON_SELECTOR_COMPHYN_SATA 0x4
+#define COMMON_SELECTOR_PIPE_COMPHY_PCIE 0x4
+#define COMMON_SELECTOR_PIPE_COMPHY_USBH 0x1
+#define COMMON_SELECTOR_PIPE_COMPHY_USBD 0x2
+
+/* SGMII/HS-SGMII/SFI/RXAUI */
+#define COMMON_SELECTOR_COMPHY0_1_2_NETWORK 0x1
+#define COMMON_SELECTOR_COMPHY3_RXAUI 0x1
+#define COMMON_SELECTOR_COMPHY3_SGMII 0x2
+#define COMMON_SELECTOR_COMPHY4_PORT1 0x1
+#define COMMON_SELECTOR_COMPHY4_ALL_OTHERS 0x2
+#define COMMON_SELECTOR_COMPHY5_RXAUI 0x2
+#define COMMON_SELECTOR_COMPHY5_SGMII 0x1
+
+#define COMMON_PHY_SD_CTRL1 0x148
+#define COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET 0
+#define COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET 4
+#define COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET 8
+#define COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET 12
+#define COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK 0xFFFF
+#define COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK 0xFF
+#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET 24
+#define COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET)
+#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET 25
+#define COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET)
+#define COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET 26
+#define COMMON_PHY_SD_CTRL1_RXAUI1_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET)
+#define COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET 27
+#define COMMON_PHY_SD_CTRL1_RXAUI0_MASK \
+ (0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET)
+
+/* DFX register */
+#define DFX_BASE (0x400000)
+#define DFX_DEV_GEN_CTRL12_REG (0x280)
+#define DFX_DEV_GEN_PCIE_CLK_SRC_MUX (0x3)
+#define DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET 7
+#define DFX_DEV_GEN_PCIE_CLK_SRC_MASK \
+ (0x3 << DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET)
+
+/* SerDes IP registers */
+#define SD_EXTERNAL_CONFIG0_REG 0
+#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET 1
+#define SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK \
+ (1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET)
+#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET 3
+#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK \
+ (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET)
+#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET 7
+#define SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK \
+ (0xf << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET)
+#define SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET 11
+#define SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK \
+ (1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET)
+#define SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET 12
+#define SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK \
+ (1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET)
+#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET 14
+#define SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK \
+ (1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET)
+#define SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET 15
+#define SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET)
+
+#define SD_EXTERNAL_CONFIG1_REG 0x4
+#define SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET 3
+#define SD_EXTERNAL_CONFIG1_RESET_IN_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET)
+#define SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET 4
+#define SD_EXTERNAL_CONFIG1_RX_INIT_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET)
+#define SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET 5
+#define SD_EXTERNAL_CONFIG1_RESET_CORE_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET)
+#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET 6
+#define SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET)
+
+#define SD_EXTERNAL_CONFIG2_REG 0x8
+#define SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET 4
+#define SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET)
+#define SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET 7
+#define SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK \
+ (0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET)
+
+#define SD_EXTERNAL_STATUS_REG 0xc
+#define SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET 7
+#define SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK \
+ (1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET)
+
+#define SD_EXTERNAL_STATUS0_REG 0x18
+#define SD_EXTERNAL_STATUS0_PLL_TX_OFFSET 2
+#define SD_EXTERNAL_STATUS0_PLL_TX_MASK \
+ (0x1 << SD_EXTERNAL_STATUS0_PLL_TX_OFFSET)
+#define SD_EXTERNAL_STATUS0_PLL_RX_OFFSET 3
+#define SD_EXTERNAL_STATUS0_PLL_RX_MASK \
+ (0x1 << SD_EXTERNAL_STATUS0_PLL_RX_OFFSET)
+#define SD_EXTERNAL_STATUS0_RX_INIT_OFFSET 4
+#define SD_EXTERNAL_STATUS0_RX_INIT_MASK \
+ (0x1 << SD_EXTERNAL_STATUS0_RX_INIT_OFFSET)
+
+#define SD_EXTERNAL_STATAUS1_REG 0x1c
+#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_OFFSET 0
+#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_MASK \
+ (1 << SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_OFFSET)
+#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_OFFSET 1
+#define SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_MASK \
+ (1 << SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_OFFSET)
+
+/* HPIPE registers */
+#define HPIPE_PWR_PLL_REG 0x4
+#define HPIPE_PWR_PLL_REF_FREQ_OFFSET 0
+#define HPIPE_PWR_PLL_REF_FREQ_MASK \
+ (0x1f << HPIPE_PWR_PLL_REF_FREQ_OFFSET)
+#define HPIPE_PWR_PLL_PHY_MODE_OFFSET 5
+#define HPIPE_PWR_PLL_PHY_MODE_MASK \
+ (0x7 << HPIPE_PWR_PLL_PHY_MODE_OFFSET)
+
+#define HPIPE_CAL_REG1_REG 0xc
+#define HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET 10
+#define HPIPE_CAL_REG_1_EXT_TXIMP_MASK \
+ (0x1f << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET)
+#define HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET 15
+#define HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK \
+ (0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET)
+
+#define HPIPE_SQUELCH_FFE_SETTING_REG 0x18
+#define HPIPE_SQUELCH_THRESH_IN_OFFSET 8
+#define HPIPE_SQUELCH_THRESH_IN_MASK \
+ (0xf << HPIPE_SQUELCH_THRESH_IN_OFFSET)
+#define HPIPE_SQUELCH_DETECTED_OFFSET 14
+#define HPIPE_SQUELCH_DETECTED_MASK \
+ (0x1 << HPIPE_SQUELCH_DETECTED_OFFSET)
+
+#define HPIPE_DFE_REG0 0x1c
+#define HPIPE_DFE_RES_FORCE_OFFSET 15
+#define HPIPE_DFE_RES_FORCE_MASK \
+ (0x1 << HPIPE_DFE_RES_FORCE_OFFSET)
+
+#define HPIPE_DFE_F3_F5_REG 0x28
+#define HPIPE_DFE_F3_F5_DFE_EN_OFFSET 14
+#define HPIPE_DFE_F3_F5_DFE_EN_MASK \
+ (0x1 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET)
+#define HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET 15
+#define HPIPE_DFE_F3_F5_DFE_CTRL_MASK \
+ (0x1 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET)
+
+#define HPIPE_G1_SET_0_REG 0x34
+#define HPIPE_G1_SET_0_G1_TX_AMP_OFFSET 1
+#define HPIPE_G1_SET_0_G1_TX_AMP_MASK \
+ (0x1f << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET)
+#define HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET 6
+#define HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK \
+ (0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET)
+#define HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET 7
+#define HPIPE_G1_SET_0_G1_TX_EMPH1_MASK \
+ (0xf << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET)
+#define HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET 11
+#define HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK \
+ (0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET)
+
+#define HPIPE_G1_SET_1_REG 0x38
+#define HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET 0
+#define HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK \
+ (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET)
+#define HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET 3
+#define HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK \
+ (0x7 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET)
+#define HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET 6
+#define HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK \
+ (0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET)
+#define HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET 8
+#define HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK \
+ (0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET)
+#define HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET 10
+#define HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK \
+ (0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET)
+#define HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET 11
+#define HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK \
+ (0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET)
+
+#define HPIPE_G2_SET_0_REG 0x3c
+#define HPIPE_G2_SET_0_G2_TX_AMP_OFFSET 1
+#define HPIPE_G2_SET_0_G2_TX_AMP_MASK \
+ (0x1f << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET)
+#define HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET 6
+#define HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK \
+ (0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET)
+#define HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET 7
+#define HPIPE_G2_SET_0_G2_TX_EMPH1_MASK \
+ (0xf << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET)
+#define HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET 11
+#define HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK \
+ (0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET)
+
+#define HPIPE_G2_SET_1_REG 0x40
+#define HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET 0
+#define HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK \
+ (0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET 3
+#define HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK \
+ (0x7 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET 6
+#define HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK \
+ (0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET 8
+#define HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK \
+ (0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_DFE_EN_OFFSET 10
+#define HPIPE_G2_SET_1_G2_RX_DFE_EN_MASK \
+ (0x1 << HPIPE_G2_SET_1_G2_RX_DFE_EN_OFFSET)
+#define HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET 11
+#define HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK \
+ (0x3 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET)
+
+#define HPIPE_G3_SET_0_REG 0x44
+#define HPIPE_G3_SET_0_G3_TX_AMP_OFFSET 1
+#define HPIPE_G3_SET_0_G3_TX_AMP_MASK \
+ (0x1f << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET)
+#define HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET 6
+#define HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK \
+ (0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET)
+#define HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET 7
+#define HPIPE_G3_SET_0_G3_TX_EMPH1_MASK \
+ (0xf << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET)
+#define HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET 11
+#define HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK \
+ (0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET)
+#define HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET 12
+#define HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK \
+ (0x7 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET)
+#define HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET 15
+#define HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK \
+ (0x1 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET)
+
+#define HPIPE_G3_SET_1_REG 0x48
+#define HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET 0
+#define HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK \
+ (0x7 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET)
+#define HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET 3
+#define HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK \
+ (0x7 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET)
+#define HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET 6
+#define HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK \
+ (0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET)
+#define HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET 8
+#define HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK \
+ (0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET)
+#define HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET 10
+#define HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK \
+ (0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET)
+#define HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET 11
+#define HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK \
+ (0x3 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET)
+#define HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET 13
+#define HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK \
+ (0x1 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET)
+
+#define HPIPE_PHY_TEST_CONTROL_REG 0x54
+#define HPIPE_PHY_TEST_PATTERN_SEL_OFFSET 4
+#define HPIPE_PHY_TEST_PATTERN_SEL_MASK \
+ (0xf << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET)
+#define HPIPE_PHY_TEST_RESET_OFFSET 14
+#define HPIPE_PHY_TEST_RESET_MASK \
+ (0x1 << HPIPE_PHY_TEST_RESET_OFFSET)
+#define HPIPE_PHY_TEST_EN_OFFSET 15
+#define HPIPE_PHY_TEST_EN_MASK \
+ (0x1 << HPIPE_PHY_TEST_EN_OFFSET)
+
+#define HPIPE_PHY_TEST_DATA_REG 0x6c
+#define HPIPE_PHY_TEST_DATA_OFFSET 0
+#define HPIPE_PHY_TEST_DATA_MASK \
+ (0xffff << HPIPE_PHY_TEST_DATA_OFFSET)
+
+#define HPIPE_LOOPBACK_REG 0x8c
+#define HPIPE_LOOPBACK_SEL_OFFSET 1
+#define HPIPE_LOOPBACK_SEL_MASK \
+ (0x7 << HPIPE_LOOPBACK_SEL_OFFSET)
+#define HPIPE_CDR_LOCK_OFFSET 7
+#define HPIPE_CDR_LOCK_MASK \
+ (0x1 << HPIPE_CDR_LOCK_OFFSET)
+#define HPIPE_CDR_LOCK_DET_EN_OFFSET 8
+#define HPIPE_CDR_LOCK_DET_EN_MASK \
+ (0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET)
+
+#define HPIPE_INTERFACE_REG 0x94
+#define HPIPE_INTERFACE_GEN_MAX_OFFSET 10
+#define HPIPE_INTERFACE_GEN_MAX_MASK \
+ (0x3 << HPIPE_INTERFACE_GEN_MAX_OFFSET)
+#define HPIPE_INTERFACE_DET_BYPASS_OFFSET 12
+#define HPIPE_INTERFACE_DET_BYPASS_MASK \
+ (0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET)
+#define HPIPE_INTERFACE_LINK_TRAIN_OFFSET 14
+#define HPIPE_INTERFACE_LINK_TRAIN_MASK \
+ (0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET)
+
+#define HPIPE_G1_SET_2_REG 0xf4
+#define HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET 0
+#define HPIPE_G1_SET_2_G1_TX_EMPH0_MASK \
+ (0xf << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET)
+#define HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET 4
+#define HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK \
+ (0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET)
+
+#define HPIPE_G2_SET_2_REG 0xf8
+#define HPIPE_G2_TX_SSC_AMP_OFFSET 9
+#define HPIPE_G2_TX_SSC_AMP_MASK \
+ (0x7f << HPIPE_G2_TX_SSC_AMP_OFFSET)
+
+#define HPIPE_VDD_CAL_0_REG 0x108
+#define HPIPE_CAL_VDD_CONT_MODE_OFFSET 15
+#define HPIPE_CAL_VDD_CONT_MODE_MASK \
+ (0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET)
+
+#define HPIPE_VDD_CAL_CTRL_REG 0x114
+#define HPIPE_EXT_SELLV_RXSAMPL_OFFSET 5
+#define HPIPE_EXT_SELLV_RXSAMPL_MASK \
+ (0x1f << HPIPE_EXT_SELLV_RXSAMPL_OFFSET)
+
+#define HPIPE_PCIE_REG0 0x120
+#define HPIPE_PCIE_IDLE_SYNC_OFFSET 12
+#define HPIPE_PCIE_IDLE_SYNC_MASK \
+ (0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET)
+#define HPIPE_PCIE_SEL_BITS_OFFSET 13
+#define HPIPE_PCIE_SEL_BITS_MASK \
+ (0x3 << HPIPE_PCIE_SEL_BITS_OFFSET)
+
+#define HPIPE_LANE_ALIGN_REG 0x124
+#define HPIPE_LANE_ALIGN_OFF_OFFSET 12
+#define HPIPE_LANE_ALIGN_OFF_MASK \
+ (0x1 << HPIPE_LANE_ALIGN_OFF_OFFSET)
+
+#define HPIPE_MISC_REG 0x13C
+#define HPIPE_MISC_CLK100M_125M_OFFSET 4
+#define HPIPE_MISC_CLK100M_125M_MASK \
+ (0x1 << HPIPE_MISC_CLK100M_125M_OFFSET)
+#define HPIPE_MISC_ICP_FORCE_OFFSET 5
+#define HPIPE_MISC_ICP_FORCE_MASK \
+ (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET)
+#define HPIPE_MISC_TXDCLK_2X_OFFSET 6
+#define HPIPE_MISC_TXDCLK_2X_MASK \
+ (0x1 << HPIPE_MISC_TXDCLK_2X_OFFSET)
+#define HPIPE_MISC_CLK500_EN_OFFSET 7
+#define HPIPE_MISC_CLK500_EN_MASK \
+ (0x1 << HPIPE_MISC_CLK500_EN_OFFSET)
+#define HPIPE_MISC_REFCLK_SEL_OFFSET 10
+#define HPIPE_MISC_REFCLK_SEL_MASK \
+ (0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET)
+
+#define HPIPE_RX_CONTROL_1_REG 0x140
+#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET 11
+#define HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK \
+ (0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET)
+#define HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET 12
+#define HPIPE_RX_CONTROL_1_CLK8T_EN_MASK \
+ (0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET)
+
+#define HPIPE_PWR_CTR_REG 0x148
+#define HPIPE_PWR_CTR_RST_DFE_OFFSET 0
+#define HPIPE_PWR_CTR_RST_DFE_MASK \
+ (0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET)
+#define HPIPE_PWR_CTR_SFT_RST_OFFSET 10
+#define HPIPE_PWR_CTR_SFT_RST_MASK \
+ (0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET)
+
+#define HPIPE_SPD_DIV_FORCE_REG 0x154
+#define HPIPE_TXDIGCK_DIV_FORCE_OFFSET 7
+#define HPIPE_TXDIGCK_DIV_FORCE_MASK \
+ (0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET)
+#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET 8
+#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK \
+ (0x3 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET)
+#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET 10
+#define HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK \
+ (0x1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET)
+#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET 13
+#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK \
+ (0x3 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET)
+#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET 15
+#define HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK \
+ (0x1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET)
+
+#define HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG 0x16C
+#define HPIPE_RX_SAMPLER_OS_GAIN_OFFSET 6
+#define HPIPE_RX_SAMPLER_OS_GAIN_MASK \
+ (0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET)
+#define HPIPE_SMAPLER_OFFSET 12
+#define HPIPE_SMAPLER_MASK \
+ (0x1 << HPIPE_SMAPLER_OFFSET)
+
+#define HPIPE_TX_REG1_REG 0x174
+#define HPIPE_TX_REG1_TX_EMPH_RES_OFFSET 5
+#define HPIPE_TX_REG1_TX_EMPH_RES_MASK \
+ (0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET)
+#define HPIPE_TX_REG1_SLC_EN_OFFSET 10
+#define HPIPE_TX_REG1_SLC_EN_MASK \
+ (0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET)
+
+#define HPIPE_PWR_CTR_DTL_REG 0x184
+#define HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET 0
+#define HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK \
+ (0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET)
+#define HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET 1
+#define HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK \
+ (0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET)
+#define HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET 2
+#define HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK \
+ (0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET)
+#define HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET 4
+#define HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK \
+ (0x7 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET)
+#define HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET 10
+#define HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK \
+ (0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET)
+#define HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET 12
+#define HPIPE_PWR_CTR_DTL_CLK_MODE_MASK \
+ (0x3 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET)
+#define HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET 14
+#define HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK \
+ (1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET)
+
+#define HPIPE_PHASE_CONTROL_REG 0x188
+#define HPIPE_OS_PH_OFFSET_OFFSET 0
+#define HPIPE_OS_PH_OFFSET_MASK \
+ (0x7f << HPIPE_OS_PH_OFFSET_OFFSET)
+#define HPIPE_OS_PH_OFFSET_FORCE_OFFSET 7
+#define HPIPE_OS_PH_OFFSET_FORCE_MASK \
+ (0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET)
+#define HPIPE_OS_PH_VALID_OFFSET 8
+#define HPIPE_OS_PH_VALID_MASK \
+ (0x1 << HPIPE_OS_PH_VALID_OFFSET)
+
+#define HPIPE_SQ_GLITCH_FILTER_CTRL 0x1c8
+#define HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET 0
+#define HPIPE_SQ_DEGLITCH_WIDTH_P_MASK \
+ (0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET)
+#define HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET 4
+#define HPIPE_SQ_DEGLITCH_WIDTH_N_MASK \
+ (0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET)
+#define HPIPE_SQ_DEGLITCH_EN_OFFSET 8
+#define HPIPE_SQ_DEGLITCH_EN_MASK \
+ (0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET)
+
+#define HPIPE_FRAME_DETECT_CTRL_0_REG 0x214
+#define HPIPE_TRAIN_PAT_NUM_OFFSET 0x7
+#define HPIPE_TRAIN_PAT_NUM_MASK \
+ (0x1FF << HPIPE_TRAIN_PAT_NUM_OFFSET)
+
+#define HPIPE_FRAME_DETECT_CTRL_3_REG 0x220
+#define HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET 12
+#define HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK \
+ (0x1 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET)
+
+#define HPIPE_DME_REG 0x228
+#define HPIPE_DME_ETHERNET_MODE_OFFSET 7
+#define HPIPE_DME_ETHERNET_MODE_MASK \
+ (0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_0_REG 0x268
+#define HPIPE_TX_TRAIN_P2P_HOLD_OFFSET 15
+#define HPIPE_TX_TRAIN_P2P_HOLD_MASK \
+ (0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_REG 0x26C
+#define HPIPE_TX_TRAIN_CTRL_G1_OFFSET 0
+#define HPIPE_TX_TRAIN_CTRL_G1_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET)
+#define HPIPE_TX_TRAIN_CTRL_GN1_OFFSET 1
+#define HPIPE_TX_TRAIN_CTRL_GN1_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET)
+#define HPIPE_TX_TRAIN_CTRL_G0_OFFSET 2
+#define HPIPE_TX_TRAIN_CTRL_G0_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_4_REG 0x278
+#define HPIPE_TRX_TRAIN_TIMER_OFFSET 0
+#define HPIPE_TRX_TRAIN_TIMER_MASK \
+ (0x3FF << HPIPE_TRX_TRAIN_TIMER_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_5_REG 0x2A4
+#define HPIPE_RX_TRAIN_TIMER_OFFSET 0
+#define HPIPE_RX_TRAIN_TIMER_MASK \
+ (0x3ff << HPIPE_RX_TRAIN_TIMER_OFFSET)
+#define HPIPE_TX_TRAIN_START_SQ_EN_OFFSET 11
+#define HPIPE_TX_TRAIN_START_SQ_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET)
+#define HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET 12
+#define HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET)
+#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET 13
+#define HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET)
+#define HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET 14
+#define HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET)
+
+#define HPIPE_TX_TRAIN_REG 0x31C
+#define HPIPE_TX_TRAIN_CHK_INIT_OFFSET 4
+#define HPIPE_TX_TRAIN_CHK_INIT_MASK \
+ (0x1 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET)
+#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET 7
+#define HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK \
+ (0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET)
+#define HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET 8
+#define HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK \
+ (0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET)
+#define HPIPE_TX_TRAIN_PAT_SEL_OFFSET 9
+#define HPIPE_TX_TRAIN_PAT_SEL_MASK \
+ (0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET)
+
+#define HPIPE_SAVED_DFE_VALUES_REG 0x328
+#define HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET 10
+#define HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK \
+ (0x3f << HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET)
+
+#define HPIPE_CDR_CONTROL_REG 0x418
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET 14
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK \
+ (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET)
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET 12
+#define HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK \
+ (0x3 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET)
+#define HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET 9
+#define HPIPE_CDR_MAX_DFE_ADAPT_0_MASK \
+ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET)
+#define HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET 6
+#define HPIPE_CDR_MAX_DFE_ADAPT_1_MASK \
+ (0x7 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET)
+
+#define HPIPE_TX_TRAIN_CTRL_11_REG 0x438
+#define HPIPE_TX_STATUS_CHECK_MODE_OFFSET 6
+#define HPIPE_TX_TX_STATUS_CHECK_MODE_MASK \
+ (0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET)
+#define HPIPE_TX_NUM_OF_PRESET_OFFSET 10
+#define HPIPE_TX_NUM_OF_PRESET_MASK \
+ (0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET)
+#define HPIPE_TX_SWEEP_PRESET_EN_OFFSET 15
+#define HPIPE_TX_SWEEP_PRESET_EN_MASK \
+ (0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET)
+
+#define HPIPE_G1_SETTINGS_3_REG 0x440
+#define HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET 0
+#define HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK \
+ (0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET)
+#define HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET 4
+#define HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK \
+ (0x7 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET)
+#define HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET 7
+#define HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK \
+ (0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET)
+#define HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET 9
+#define HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK \
+ (0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET)
+#define HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET 12
+#define HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET)
+#define HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET 14
+#define HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET)
+
+#define HPIPE_G1_SETTINGS_4_REG 0x444
+#define HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET 8
+#define HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK \
+ (0x3 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET)
+
+#define HPIPE_G2_SETTINGS_4_REG 0x44c
+#define HPIPE_G2_DFE_RES_OFFSET 8
+#define HPIPE_G2_DFE_RES_MASK \
+ (0x3 << HPIPE_G2_DFE_RES_OFFSET)
+
+#define HPIPE_G3_SETTING_3_REG 0x450
+#define HPIPE_G3_FFE_CAP_SEL_OFFSET 0
+#define HPIPE_G3_FFE_CAP_SEL_MASK \
+ (0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET)
+#define HPIPE_G3_FFE_RES_SEL_OFFSET 4
+#define HPIPE_G3_FFE_RES_SEL_MASK \
+ (0x7 << HPIPE_G3_FFE_RES_SEL_OFFSET)
+#define HPIPE_G3_FFE_SETTING_FORCE_OFFSET 7
+#define HPIPE_G3_FFE_SETTING_FORCE_MASK \
+ (0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET)
+#define HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET 12
+#define HPIPE_G3_FFE_DEG_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET)
+#define HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET 14
+#define HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK \
+ (0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET)
+
+#define HPIPE_G3_SETTING_4_REG 0x454
+#define HPIPE_G3_DFE_RES_OFFSET 8
+#define HPIPE_G3_DFE_RES_MASK (0x3 << HPIPE_G3_DFE_RES_OFFSET)
+
+#define HPIPE_TX_PRESET_INDEX_REG 0x468
+#define HPIPE_TX_PRESET_INDEX_OFFSET 0
+#define HPIPE_TX_PRESET_INDEX_MASK \
+ (0xf << HPIPE_TX_PRESET_INDEX_OFFSET)
+
+#define HPIPE_DFE_CONTROL_REG 0x470
+#define HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET 14
+#define HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK \
+ (0x3 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET)
+
+#define HPIPE_DFE_CTRL_28_REG 0x49C
+#define HPIPE_DFE_CTRL_28_PIPE4_OFFSET 7
+#define HPIPE_DFE_CTRL_28_PIPE4_MASK \
+ (0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET)
+
+#define HPIPE_G1_SETTING_5_REG 0x538
+#define HPIPE_G1_SETTING_5_G1_ICP_OFFSET 0
+#define HPIPE_G1_SETTING_5_G1_ICP_MASK \
+ (0xf << HPIPE_G1_SETTING_5_G1_ICP_OFFSET)
+
+#define HPIPE_G3_SETTING_5_REG 0x548
+#define HPIPE_G3_SETTING_5_G3_ICP_OFFSET 0
+#define HPIPE_G3_SETTING_5_G3_ICP_MASK \
+ (0xf << HPIPE_G3_SETTING_5_G3_ICP_OFFSET)
+
+#define HPIPE_LANE_CONFIG0_REG 0x600
+#define HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET 0
+#define HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK \
+ (0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET)
+
+#define HPIPE_LANE_STATUS1_REG 0x60C
+#define HPIPE_LANE_STATUS1_PCLK_EN_OFFSET 0
+#define HPIPE_LANE_STATUS1_PCLK_EN_MASK \
+ (0x1 << HPIPE_LANE_STATUS1_PCLK_EN_OFFSET)
+
+#define HPIPE_LANE_CFG4_REG 0x620
+#define HPIPE_LANE_CFG4_DFE_CTRL_OFFSET 0
+#define HPIPE_LANE_CFG4_DFE_CTRL_MASK \
+ (0x7 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET)
+#define HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET 3
+#define HPIPE_LANE_CFG4_DFE_EN_SEL_MASK \
+ (0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET)
+#define HPIPE_LANE_CFG4_DFE_OVER_OFFSET 6
+#define HPIPE_LANE_CFG4_DFE_OVER_MASK \
+ (0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET)
+#define HPIPE_LANE_CFG4_SSC_CTRL_OFFSET 7
+#define HPIPE_LANE_CFG4_SSC_CTRL_MASK \
+ (0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET)
+
+#define HPIPE_LANE_EQ_REMOTE_SETTING_REG 0x6f8
+#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET 0
+#define HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK \
+ (0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET)
+#define HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET 1
+#define HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK \
+ (0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET)
+#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET 2
+#define HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK \
+ (0xf << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET)
+
+#define HPIPE_LANE_EQU_CONFIG_0_REG 0x69C
+#define HPIPE_CFG_PHY_RC_EP_OFFSET 12
+#define HPIPE_CFG_PHY_RC_EP_MASK \
+ (0x1 << HPIPE_CFG_PHY_RC_EP_OFFSET)
+
+#define HPIPE_LANE_EQ_CFG1_REG 0x6a0
+#define HPIPE_CFG_UPDATE_POLARITY_OFFSET 12
+#define HPIPE_CFG_UPDATE_POLARITY_MASK \
+ (0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET)
+
+#define HPIPE_LANE_EQ_CFG2_REG 0x6a4
+#define HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET 14
+#define HPIPE_CFG_EQ_BUNDLE_DIS_MASK \
+ (0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET)
+
+#define HPIPE_RST_CLK_CTRL_REG 0x704
+#define HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET 0
+#define HPIPE_RST_CLK_CTRL_PIPE_RST_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET)
+#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET 2
+#define HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET)
+#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET 3
+#define HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET)
+#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET 9
+#define HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK \
+ (0x1 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET)
+
+#define HPIPE_TST_MODE_CTRL_REG 0x708
+#define HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET 2
+#define HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK \
+ (0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET)
+
+#define HPIPE_CLK_SRC_LO_REG 0x70c
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET 1
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK \
+ (0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET)
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET 2
+#define HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK \
+ (0x3 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET)
+#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET 5
+#define HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK \
+ (0x7 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET)
+
+#define HPIPE_CLK_SRC_HI_REG 0x710
+#define HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET 0
+#define HPIPE_CLK_SRC_HI_LANE_STRT_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET)
+#define HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET 1
+#define HPIPE_CLK_SRC_HI_LANE_BREAK_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET)
+#define HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET 2
+#define HPIPE_CLK_SRC_HI_LANE_MASTER_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET)
+#define HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET 7
+#define HPIPE_CLK_SRC_HI_MODE_PIPE_MASK \
+ (0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET)
+
+#define HPIPE_GLOBAL_MISC_CTRL 0x718
+#define HPIPE_GLOBAL_PM_CTRL 0x740
+#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET 0
+#define HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK \
+ (0xFF << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET)
+
+/* General defines */
+#define PLL_LOCK_TIMEOUT 15000
+
+#endif /* _PHY_COMPHY_CP110_H */
+
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.c b/drivers/marvell/comphy/phy-comphy-cp110.c
new file mode 100644
index 000000000..8b78280b5
--- /dev/null
+++ b/drivers/marvell/comphy/phy-comphy-cp110.c
@@ -0,0 +1,2319 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Marvell CP110 SoC COMPHY unit driver */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+#include <spinlock.h>
+#include "mvebu.h"
+#include "comphy-cp110.h"
+
+/* #define DEBUG_COMPHY */
+#ifdef DEBUG_COMPHY
+#define debug(format...) printf(format)
+#else
+#define debug(format, arg...)
+#endif
+
+/* A lane is described by 4 fields:
+ * - bit 1~0 represent comphy polarity invert
+ * - bit 7~2 represent comphy speed
+ * - bit 11~8 represent unit index
+ * - bit 16~12 represent mode
+ * - bit 17 represent comphy indication of clock source
+ * - bit 19-18 represents pcie width (in case of pcie comphy config.)
+ * - bit 31~20 reserved
+ */
+
+#define COMPHY_INVERT_OFFSET 0
+#define COMPHY_INVERT_LEN 2
+#define COMPHY_INVERT_MASK COMPHY_MASK(COMPHY_INVERT_OFFSET, \
+ COMPHY_INVERT_LEN)
+#define COMPHY_SPEED_OFFSET (COMPHY_INVERT_OFFSET + COMPHY_INVERT_LEN)
+#define COMPHY_SPEED_LEN 6
+#define COMPHY_SPEED_MASK COMPHY_MASK(COMPHY_SPEED_OFFSET, \
+ COMPHY_SPEED_LEN)
+#define COMPHY_UNIT_ID_OFFSET (COMPHY_SPEED_OFFSET + COMPHY_SPEED_LEN)
+#define COMPHY_UNIT_ID_LEN 4
+#define COMPHY_UNIT_ID_MASK COMPHY_MASK(COMPHY_UNIT_ID_OFFSET, \
+ COMPHY_UNIT_ID_LEN)
+#define COMPHY_MODE_OFFSET (COMPHY_UNIT_ID_OFFSET + COMPHY_UNIT_ID_LEN)
+#define COMPHY_MODE_LEN 5
+#define COMPHY_MODE_MASK COMPHY_MASK(COMPHY_MODE_OFFSET, COMPHY_MODE_LEN)
+#define COMPHY_CLK_SRC_OFFSET (COMPHY_MODE_OFFSET + COMPHY_MODE_LEN)
+#define COMPHY_CLK_SRC_LEN 1
+#define COMPHY_CLK_SRC_MASK COMPHY_MASK(COMPHY_CLK_SRC_OFFSET, \
+ COMPHY_CLK_SRC_LEN)
+#define COMPHY_PCI_WIDTH_OFFSET (COMPHY_CLK_SRC_OFFSET + COMPHY_CLK_SRC_LEN)
+#define COMPHY_PCI_WIDTH_LEN 3
+#define COMPHY_PCI_WIDTH_MASK COMPHY_MASK(COMPHY_PCI_WIDTH_OFFSET, \
+ COMPHY_PCI_WIDTH_LEN)
+
+#define COMPHY_MASK(offset, len) (((1 << (len)) - 1) << (offset))
+
+/* Macro which extracts mode from lane description */
+#define COMPHY_GET_MODE(x) (((x) & COMPHY_MODE_MASK) >> \
+ COMPHY_MODE_OFFSET)
+/* Macro which extracts unit index from lane description */
+#define COMPHY_GET_ID(x) (((x) & COMPHY_UNIT_ID_MASK) >> \
+ COMPHY_UNIT_ID_OFFSET)
+/* Macro which extracts speed from lane description */
+#define COMPHY_GET_SPEED(x) (((x) & COMPHY_SPEED_MASK) >> \
+ COMPHY_SPEED_OFFSET)
+/* Macro which extracts clock source indication from lane description */
+#define COMPHY_GET_CLK_SRC(x) (((x) & COMPHY_CLK_SRC_MASK) >> \
+ COMPHY_CLK_SRC_OFFSET)
+/* Macro which extracts pcie width indication from lane description */
+#define COMPHY_GET_PCIE_WIDTH(x) (((x) & COMPHY_PCI_WIDTH_MASK) >> \
+ COMPHY_PCI_WIDTH_OFFSET)
+
+#define COMPHY_SATA_MODE 0x1
+#define COMPHY_SGMII_MODE 0x2 /* SGMII 1G */
+#define COMPHY_HS_SGMII_MODE 0x3 /* SGMII 2.5G */
+#define COMPHY_USB3H_MODE 0x4
+#define COMPHY_USB3D_MODE 0x5
+#define COMPHY_PCIE_MODE 0x6
+#define COMPHY_RXAUI_MODE 0x7
+#define COMPHY_XFI_MODE 0x8
+#define COMPHY_SFI_MODE 0x9
+#define COMPHY_USB3_MODE 0xa
+#define COMPHY_AP_MODE 0xb
+
+/* COMPHY speed macro */
+#define COMPHY_SPEED_1_25G 0 /* SGMII 1G */
+#define COMPHY_SPEED_2_5G 1
+#define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */
+#define COMPHY_SPEED_5G 3
+#define COMPHY_SPEED_5_15625G 4 /* XFI 5G */
+#define COMPHY_SPEED_6G 5
+#define COMPHY_SPEED_10_3125G 6 /* XFI 10G */
+#define COMPHY_SPEED_MAX 0x3F
+/* The default speed for IO with fixed known speed */
+#define COMPHY_SPEED_DEFAULT COMPHY_SPEED_MAX
+
+/* Commands for comphy driver */
+#define COMPHY_COMMAND_DIGITAL_PWR_OFF 0x00000001
+#define COMPHY_COMMAND_DIGITAL_PWR_ON 0x00000002
+
+#define COMPHY_PIPE_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x120000)
+
+/* System controller registers */
+#define PCIE_MAC_RESET_MASK_PORT0 BIT(13)
+#define PCIE_MAC_RESET_MASK_PORT1 BIT(11)
+#define PCIE_MAC_RESET_MASK_PORT2 BIT(12)
+#define SYS_CTRL_UINIT_SOFT_RESET_REG 0x268
+#define SYS_CTRL_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + 0x440000)
+
+/* DFX register spaces */
+#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET (0)
+#define SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK (0x1 << \
+ SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET)
+#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET (1)
+#define SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK (0x1 << \
+ SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET)
+#define SAR_STATUS_0_REG 200
+#define DFX_FROM_COMPHY_ADDR(x) ((x & ~0xffffff) + DFX_BASE)
+
+/* The same Units Soft Reset Config register are accessed in all PCIe ports
+ * initialization, so a spin lock is defined in case when more than 1 CPUs
+ * resets PCIe MAC and need to access the register in the same time. The spin
+ * lock is shared by all CP110 units.
+ */
+spinlock_t cp110_mac_reset_lock;
+
+enum reg_width_type {
+ REG_16BIT = 0,
+ REG_32BIT,
+};
+
+enum {
+ COMPHY_LANE0 = 0,
+ COMPHY_LANE1,
+ COMPHY_LANE2,
+ COMPHY_LANE3,
+ COMPHY_LANE4,
+ COMPHY_LANE5,
+ COMPHY_LANE_MAX,
+};
+
+/* These values come from the PCI Express Spec */
+enum pcie_link_width {
+ PCIE_LNK_WIDTH_RESRV = 0x00,
+ PCIE_LNK_X1 = 0x01,
+ PCIE_LNK_X2 = 0x02,
+ PCIE_LNK_X4 = 0x04,
+ PCIE_LNK_X8 = 0x08,
+ PCIE_LNK_X12 = 0x0C,
+ PCIE_LNK_X16 = 0x10,
+ PCIE_LNK_X32 = 0x20,
+ PCIE_LNK_WIDTH_UNKNOWN = 0xFF,
+};
+
+static inline uint32_t polling_with_timeout(uintptr_t addr,
+ uint32_t val,
+ uint32_t mask,
+ uint32_t usec_timeout,
+ enum reg_width_type type)
+{
+ uint32_t data;
+
+ do {
+ udelay(1);
+ if (type == REG_16BIT)
+ data = mmio_read_16(addr) & mask;
+ else
+ data = mmio_read_32(addr) & mask;
+ } while (data != val && --usec_timeout > 0);
+
+ if (usec_timeout == 0)
+ return data;
+
+ return 0;
+}
+
+static inline void reg_set(uintptr_t addr, uint32_t data, uint32_t mask)
+{
+ debug("<atf>: WR to addr = %#010lx, data = %#010x (mask = %#010x) - ",
+ addr, data, mask);
+ debug("old value = %#010x ==> ", mmio_read_32(addr));
+ mmio_clrsetbits_32(addr, mask, data);
+
+ debug("new val %#010x\n", mmio_read_32(addr));
+}
+
+/* Clear PIPE selector - avoid collision with previous configuration */
+static void mvebu_cp110_comphy_clr_pipe_selector(uint64_t comphy_base,
+ uint8_t comphy_index)
+{
+ uint32_t reg, mask, field;
+ uint32_t comphy_offset =
+ COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
+
+ mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
+ reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
+ field = reg & mask;
+
+ if (field) {
+ reg &= ~mask;
+ mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET,
+ reg);
+ }
+}
+
+/* Clear PHY selector - avoid collision with previous configuration */
+static void mvebu_cp110_comphy_clr_phy_selector(uint64_t comphy_base,
+ uint8_t comphy_index)
+{
+ uint32_t reg, mask, field;
+ uint32_t comphy_offset =
+ COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
+
+ mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
+ reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
+ field = reg & mask;
+
+ /* Clear comphy selector - if it was already configured.
+ * (might be that this comphy was configured as PCIe/USB,
+ * in such case, no need to clear comphy selector because PCIe/USB
+ * are controlled by hpipe selector).
+ */
+ if (field) {
+ reg &= ~mask;
+ mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET,
+ reg);
+ }
+}
+
+/* PHY selector configures SATA and Network modes */
+static void mvebu_cp110_comphy_set_phy_selector(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uint32_t reg, mask;
+ uint32_t comphy_offset =
+ COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
+ int mode;
+
+ /* If phy selector is used the pipe selector should be marked as
+ * unconnected.
+ */
+ mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
+
+ /* Comphy mode (compound of the IO mode and id). Here, only the IO mode
+ * is required to distinguish between SATA and network modes.
+ */
+ mode = COMPHY_GET_MODE(comphy_mode);
+
+ mask = COMMON_SELECTOR_COMPHY_MASK << comphy_offset;
+ reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET);
+ reg &= ~mask;
+
+ /* SATA port 0/1 require the same configuration */
+ if (mode == COMPHY_SATA_MODE) {
+ /* SATA selector values is always 4 */
+ reg |= COMMON_SELECTOR_COMPHYN_SATA << comphy_offset;
+ } else {
+ switch (comphy_index) {
+ case(0):
+ case(1):
+ case(2):
+ /* For comphy 0,1, and 2:
+ * Network selector value is always 1.
+ */
+ reg |= COMMON_SELECTOR_COMPHY0_1_2_NETWORK <<
+ comphy_offset;
+ break;
+ case(3):
+ /* For comphy 3:
+ * 0x1 = RXAUI_Lane1
+ * 0x2 = SGMII/HS-SGMII Port1
+ */
+ if (mode == COMPHY_RXAUI_MODE)
+ reg |= COMMON_SELECTOR_COMPHY3_RXAUI <<
+ comphy_offset;
+ else
+ reg |= COMMON_SELECTOR_COMPHY3_SGMII <<
+ comphy_offset;
+ break;
+ case(4):
+ /* For comphy 4:
+ * 0x1 = SGMII/HS-SGMII Port1, XFI1/SFI1
+ * 0x2 = SGMII/HS-SGMII Port0: XFI0/SFI0, RXAUI_Lane0
+ *
+ * We want to check if SGMII1/HS_SGMII1 is the
+ * requested mode in order to determine which value
+ * should be set (all other modes use the same value)
+ * so we need to strip the mode, and check the ID
+ * because we might handle SGMII0/HS_SGMII0 too.
+ */
+ /* TODO: need to distinguish between CP110 and CP115
+ * as SFI1/XFI1 available only for CP115.
+ */
+ if ((mode == COMPHY_SGMII_MODE ||
+ mode == COMPHY_HS_SGMII_MODE ||
+ mode == COMPHY_SFI_MODE) &&
+ COMPHY_GET_ID(comphy_mode) == 1)
+ reg |= COMMON_SELECTOR_COMPHY4_PORT1 <<
+ comphy_offset;
+ else
+ reg |= COMMON_SELECTOR_COMPHY4_ALL_OTHERS <<
+ comphy_offset;
+ break;
+ case(5):
+ /* For comphy 5:
+ * 0x1 = SGMII/HS-SGMII Port2
+ * 0x2 = RXAUI Lane1
+ */
+ if (mode == COMPHY_RXAUI_MODE)
+ reg |= COMMON_SELECTOR_COMPHY5_RXAUI <<
+ comphy_offset;
+ else
+ reg |= COMMON_SELECTOR_COMPHY5_SGMII <<
+ comphy_offset;
+ break;
+ }
+ }
+
+ mmio_write_32(comphy_base + COMMON_SELECTOR_PHY_REG_OFFSET, reg);
+}
+
+/* PIPE selector configures for PCIe, USB 3.0 Host, and USB 3.0 Device mode */
+static void mvebu_cp110_comphy_set_pipe_selector(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uint32_t reg;
+ uint32_t shift = COMMON_SELECTOR_COMPHYN_FIELD_WIDTH * comphy_index;
+ int mode = COMPHY_GET_MODE(comphy_mode);
+ uint32_t mask = COMMON_SELECTOR_COMPHY_MASK << shift;
+ uint32_t pipe_sel = 0x0;
+
+ /* If pipe selector is used the phy selector should be marked as
+ * unconnected.
+ */
+ mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
+
+ reg = mmio_read_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET);
+ reg &= ~mask;
+
+ switch (mode) {
+ case (COMPHY_PCIE_MODE):
+ /* For lanes support PCIE, selector value are all same */
+ pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_PCIE;
+ break;
+
+ case (COMPHY_USB3H_MODE):
+ /* Only lane 1-4 support USB host, selector value is same */
+ if (comphy_index == COMPHY_LANE0 ||
+ comphy_index == COMPHY_LANE5)
+ ERROR("COMPHY[%d] mode[%d] is invalid\n",
+ comphy_index, mode);
+ else
+ pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBH;
+ break;
+
+ case (COMPHY_USB3D_MODE):
+ /* Lane 1 and 4 support USB device, selector value is same */
+ if (comphy_index == COMPHY_LANE1 ||
+ comphy_index == COMPHY_LANE4)
+ pipe_sel = COMMON_SELECTOR_PIPE_COMPHY_USBD;
+ else
+ ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index,
+ mode);
+ break;
+
+ default:
+ ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
+ break;
+ }
+
+ mmio_write_32(comphy_base + COMMON_SELECTOR_PIPE_REG_OFFSET, reg |
+ (pipe_sel << shift));
+}
+
+int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base, uint8_t comphy_index)
+{
+ uintptr_t sd_ip_addr, addr;
+ uint32_t mask, data;
+ int ret = 0;
+
+ debug_enter();
+
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_PLL_TX_MASK &
+ SD_EXTERNAL_STATUS0_PLL_RX_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask,
+ PLL_LOCK_TIMEOUT, REG_32BIT);
+ if (data != 0) {
+ if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
+ ERROR("RX PLL is not locked\n");
+ if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
+ ERROR("TX PLL is not locked\n");
+
+ ret = -ETIMEDOUT;
+ }
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_sata_power_on(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uintptr_t hpipe_addr, sd_ip_addr, comphy_addr;
+ uint32_t mask, data;
+ int ret = 0;
+
+ debug_enter();
+
+ /* configure phy selector for SATA */
+ mvebu_cp110_comphy_set_phy_selector(comphy_base,
+ comphy_index, comphy_mode);
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+
+ debug(" add hpipe 0x%lx, sd 0x%lx, comphy 0x%lx\n",
+ hpipe_addr, sd_ip_addr, comphy_addr);
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Set select data width 40Bit - SATA mode only */
+ reg_set(comphy_addr + COMMON_PHY_CFG6_REG,
+ 0x1 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET,
+ COMMON_PHY_CFG6_IF_40_SEL_MASK);
+
+ /* release from hard reset in SD external */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+
+ debug("stage: Comphy configuration\n");
+ /* Start comphy Configuration */
+ /* Set reference clock to comes from group 1 - choose 25Mhz */
+ reg_set(hpipe_addr + HPIPE_MISC_REG,
+ 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
+ HPIPE_MISC_REFCLK_SEL_MASK);
+ /* Reference frequency select set 1 (for SATA = 25Mhz) */
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ /* PHY mode select (set SATA = 0x0 */
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x0 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+ /* Set max PHY generation setting - 6Gbps */
+ reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
+ 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
+ HPIPE_INTERFACE_GEN_MAX_MASK);
+ /* Set select data width 40Bit (SEL_BITS[2:0]) */
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
+ 0x2 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
+
+ debug("stage: Analog parameters from ETP(HW)\n");
+ /* G1 settings */
+ mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
+ data = 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
+ data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
+ data |= 0x3 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
+
+ mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
+ data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
+ data |= 0x2 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
+ data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_MASK;
+ data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_DEG_RES_LEVEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_MASK;
+ data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_LOAD_RES_LEVEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
+
+ /* G2 settings */
+ mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
+ data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
+ data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
+ data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_SELMUFF_MASK;
+ data |= 0x3 << HPIPE_G2_SET_1_G2_RX_SELMUFF_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_MASK;
+ data |= 0x1 << HPIPE_G2_SET_1_G2_RX_DIGCK_DIV_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
+
+ /* G3 settings */
+ mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
+ data = 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
+ data |= 0x2 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_RX_SELMUFI_MASK;
+ data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFI_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_RX_SELMUFF_MASK;
+ data |= 0x3 << HPIPE_G3_SET_1_G3_RX_SELMUFF_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_RX_DFE_EN_MASK;
+ data |= 0x1 << HPIPE_G3_SET_1_G3_RX_DFE_EN_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_MASK;
+ data |= 0x2 << HPIPE_G3_SET_1_G3_RX_DIGCK_DIV_OFFSET;
+ mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
+ data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
+
+ /* DTL Control */
+ mask = HPIPE_PWR_CTR_DTL_SQ_DET_EN_MASK;
+ data = 0x1 << HPIPE_PWR_CTR_DTL_SQ_DET_EN_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_SQ_PLOOP_EN_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_CLAMPING_SEL_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_CLAMPING_SEL_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_INTPCLK_DIV_FORCE_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_OFFSET;
+ mask |= HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_MASK;
+ data |= 0x1 << HPIPE_PWR_CTR_DTL_CLK_MODE_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
+
+ /* Trigger sampler enable pulse */
+ mask = HPIPE_SMAPLER_MASK;
+ data = 0x1 << HPIPE_SMAPLER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
+ mask = HPIPE_SMAPLER_MASK;
+ data = 0x0 << HPIPE_SMAPLER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
+
+ /* VDD Calibration Control 3 */
+ mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
+ data = 0x10 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
+
+ /* DFE Resolution Control */
+ mask = HPIPE_DFE_RES_FORCE_MASK;
+ data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
+
+ /* DFE F3-F5 Coefficient Control */
+ mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
+ data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
+ mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
+ data = 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
+
+ /* G3 Setting 3 */
+ mask = HPIPE_G3_FFE_CAP_SEL_MASK;
+ data = 0xf << HPIPE_G3_FFE_CAP_SEL_OFFSET;
+ mask |= HPIPE_G3_FFE_RES_SEL_MASK;
+ data |= 0x4 << HPIPE_G3_FFE_RES_SEL_OFFSET;
+ mask |= HPIPE_G3_FFE_SETTING_FORCE_MASK;
+ data |= 0x1 << HPIPE_G3_FFE_SETTING_FORCE_OFFSET;
+ mask |= HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
+ data |= 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
+ mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
+ data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
+
+ /* G3 Setting 4 */
+ mask = HPIPE_G3_DFE_RES_MASK;
+ data = 0x1 << HPIPE_G3_DFE_RES_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
+
+ /* Offset Phase Control */
+ mask = HPIPE_OS_PH_OFFSET_MASK;
+ data = 0x61 << HPIPE_OS_PH_OFFSET_OFFSET;
+ mask |= HPIPE_OS_PH_OFFSET_FORCE_MASK;
+ data |= 0x1 << HPIPE_OS_PH_OFFSET_FORCE_OFFSET;
+ mask |= HPIPE_OS_PH_VALID_MASK;
+ data |= 0x0 << HPIPE_OS_PH_VALID_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
+ mask = HPIPE_OS_PH_VALID_MASK;
+ data = 0x1 << HPIPE_OS_PH_VALID_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
+ mask = HPIPE_OS_PH_VALID_MASK;
+ data = 0x0 << HPIPE_OS_PH_VALID_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHASE_CONTROL_REG, data, mask);
+
+ /* Set G1 TX amplitude and TX post emphasis value */
+ mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
+ data = 0x8 << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
+ mask |= HPIPE_G1_SET_0_G1_TX_AMP_ADJ_MASK;
+ data |= 0x1 << HPIPE_G1_SET_0_G1_TX_AMP_ADJ_OFFSET;
+ mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
+ data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
+ mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_EN_MASK;
+ data |= 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
+
+ /* Set G2 TX amplitude and TX post emphasis value */
+ mask = HPIPE_G2_SET_0_G2_TX_AMP_MASK;
+ data = 0xa << HPIPE_G2_SET_0_G2_TX_AMP_OFFSET;
+ mask |= HPIPE_G2_SET_0_G2_TX_AMP_ADJ_MASK;
+ data |= 0x1 << HPIPE_G2_SET_0_G2_TX_AMP_ADJ_OFFSET;
+ mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_MASK;
+ data |= 0x2 << HPIPE_G2_SET_0_G2_TX_EMPH1_OFFSET;
+ mask |= HPIPE_G2_SET_0_G2_TX_EMPH1_EN_MASK;
+ data |= 0x1 << HPIPE_G2_SET_0_G2_TX_EMPH1_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G2_SET_0_REG, data, mask);
+
+ /* Set G3 TX amplitude and TX post emphasis value */
+ mask = HPIPE_G3_SET_0_G3_TX_AMP_MASK;
+ data = 0x1e << HPIPE_G3_SET_0_G3_TX_AMP_OFFSET;
+ mask |= HPIPE_G3_SET_0_G3_TX_AMP_ADJ_MASK;
+ data |= 0x1 << HPIPE_G3_SET_0_G3_TX_AMP_ADJ_OFFSET;
+ mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_MASK;
+ data |= 0xe << HPIPE_G3_SET_0_G3_TX_EMPH1_OFFSET;
+ mask |= HPIPE_G3_SET_0_G3_TX_EMPH1_EN_MASK;
+ data |= 0x1 << HPIPE_G3_SET_0_G3_TX_EMPH1_EN_OFFSET;
+ mask |= HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_MASK;
+ data |= 0x4 << HPIPE_G3_SET_0_G3_TX_SLEW_RATE_SEL_OFFSET;
+ mask |= HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_MASK;
+ data |= 0x0 << HPIPE_G3_SET_0_G3_TX_SLEW_CTRL_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SET_0_REG, data, mask);
+
+ /* SERDES External Configuration 2 register */
+ mask = SD_EXTERNAL_CONFIG2_SSC_ENABLE_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG2_SSC_ENABLE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
+
+ /* DFE reset sequence */
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
+ 0x1 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
+ HPIPE_PWR_CTR_RST_DFE_MASK);
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
+ 0x0 << HPIPE_PWR_CTR_RST_DFE_OFFSET,
+ HPIPE_PWR_CTR_RST_DFE_MASK);
+ /* SW reset for interrupt logic */
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
+ 0x1 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
+ HPIPE_PWR_CTR_SFT_RST_MASK);
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_REG,
+ 0x0 << HPIPE_PWR_CTR_SFT_RST_OFFSET,
+ HPIPE_PWR_CTR_SFT_RST_MASK);
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_sgmii_power_on(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
+ uint32_t mask, data, sgmii_speed = COMPHY_GET_SPEED(comphy_mode);
+ int ret = 0;
+
+ debug_enter();
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+
+ /* configure phy selector for SGMII */
+ mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
+ comphy_mode);
+
+ /* Confiugre the lane */
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
+
+ if (sgmii_speed == COMPHY_SPEED_1_25G) {
+ /* SGMII 1G, SerDes speed 1.25G */
+ data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
+ data |= 0x6 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
+ } else if (sgmii_speed == COMPHY_SPEED_3_125G) {
+ /* HS SGMII (2.5G), SerDes speed 3.125G */
+ data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
+ data |= 0x8 << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
+ } else {
+ /* Other rates are not supported */
+ ERROR("unsupported SGMII speed on comphy%d\n", comphy_index);
+ return -EINVAL;
+ }
+
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
+ data |= 1 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+ /* Set hard reset */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* Release hard reset */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+
+ /* Make sure that 40 data bits is disabled
+ * This bit is not cleared by reset
+ */
+ mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
+ data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
+
+ /* Start comphy Configuration */
+ debug("stage: Comphy configuration\n");
+ /* set reference clock */
+ mask = HPIPE_MISC_REFCLK_SEL_MASK;
+ data = 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
+ /* Power and PLL Control */
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+ /* Loopback register */
+ mask = HPIPE_LOOPBACK_SEL_MASK;
+ data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
+ /* rx control 1 */
+ mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
+ data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
+ mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
+ data |= 0x0 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
+ /* DTL Control */
+ mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
+ data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
+
+ /* Set analog parameters from ETP(HW) - for now use the default datas */
+ debug("stage: Analog parameters from ETP(HW)\n");
+
+ reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
+ 0x1 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
+ HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
+
+ debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
+ /* SERDES External Configuration */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+ ret = mvebu_cp110_comphy_is_pll_locked(comphy_base, comphy_index);
+ if (ret)
+ return ret;
+
+ /* RX init */
+ mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* check that RX init done */
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
+ if (data != 0) {
+ ERROR("RX init failed\n");
+ ret = -ETIMEDOUT;
+ }
+
+ debug("stage: RF Reset\n");
+ /* RF Reset */
+ mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_xfi_power_on(uint64_t comphy_base,
+ uint8_t comphy_index,
+ uint32_t comphy_mode)
+{
+ uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
+ uint32_t mask, data, speed = COMPHY_GET_SPEED(comphy_mode);
+ int ret = 0;
+
+ debug_enter();
+
+ if ((speed != COMPHY_SPEED_5_15625G) &&
+ (speed != COMPHY_SPEED_10_3125G) &&
+ (speed != COMPHY_SPEED_DEFAULT)) {
+ ERROR("comphy:%d: unsupported sfi/xfi speed\n", comphy_index);
+ return -EINVAL;
+ }
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+
+ /* configure phy selector for XFI/SFI */
+ mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
+ comphy_mode);
+
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Make sure that 40 data bits is disabled
+ * This bit is not cleared by reset
+ */
+ mask = COMMON_PHY_CFG6_IF_40_SEL_MASK;
+ data = 0 << COMMON_PHY_CFG6_IF_40_SEL_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG6_REG, data, mask);
+
+ /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
+ data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
+ data |= 0xE << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
+ data |= 0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+ /* release from hard reset */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+
+ /* Start comphy Configuration */
+ debug("stage: Comphy configuration\n");
+ /* set reference clock */
+ mask = HPIPE_MISC_ICP_FORCE_MASK;
+ data = (speed == COMPHY_SPEED_5_15625G) ?
+ (0x0 << HPIPE_MISC_ICP_FORCE_OFFSET) :
+ (0x1 << HPIPE_MISC_ICP_FORCE_OFFSET);
+ mask |= HPIPE_MISC_REFCLK_SEL_MASK;
+ data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
+ /* Power and PLL Control */
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+ /* Loopback register */
+ mask = HPIPE_LOOPBACK_SEL_MASK;
+ data = 0x1 << HPIPE_LOOPBACK_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
+ /* rx control 1 */
+ mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
+ data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
+ mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
+ data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
+ /* DTL Control */
+ mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
+ data = 0x1 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
+
+ /* Transmitter/Receiver Speed Divider Force */
+ if (speed == COMPHY_SPEED_5_15625G) {
+ mask = HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_MASK;
+ data = 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_OFFSET;
+ mask |= HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_MASK;
+ data |= 1 << HPIPE_SPD_DIV_FORCE_RX_SPD_DIV_FORCE_OFFSET;
+ mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_MASK;
+ data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_OFFSET;
+ mask |= HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_MASK;
+ data |= 1 << HPIPE_SPD_DIV_FORCE_TX_SPD_DIV_FORCE_OFFSET;
+ } else {
+ mask = HPIPE_TXDIGCK_DIV_FORCE_MASK;
+ data = 0x1 << HPIPE_TXDIGCK_DIV_FORCE_OFFSET;
+ }
+ reg_set(hpipe_addr + HPIPE_SPD_DIV_FORCE_REG, data, mask);
+
+ /* Set analog parameters from ETP(HW) */
+ debug("stage: Analog parameters from ETP(HW)\n");
+ /* SERDES External Configuration 2 */
+ mask = SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG, data, mask);
+ /* 0x7-DFE Resolution control */
+ mask = HPIPE_DFE_RES_FORCE_MASK;
+ data = 0x1 << HPIPE_DFE_RES_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
+ /* 0xd-G1_Setting_0 */
+ if (speed == COMPHY_SPEED_5_15625G) {
+ mask = HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
+ data = 0x6 << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
+ } else {
+ mask = HPIPE_G1_SET_0_G1_TX_AMP_MASK;
+ data = 0x1c << HPIPE_G1_SET_0_G1_TX_AMP_OFFSET;
+ mask |= HPIPE_G1_SET_0_G1_TX_EMPH1_MASK;
+ data |= 0xe << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET;
+ }
+ reg_set(hpipe_addr + HPIPE_G1_SET_0_REG, data, mask);
+ /* Genration 1 setting 2 (G1_Setting_2) */
+ mask = HPIPE_G1_SET_2_G1_TX_EMPH0_MASK;
+ data = 0x0 << HPIPE_G1_SET_2_G1_TX_EMPH0_OFFSET;
+ mask |= HPIPE_G1_SET_2_G1_TX_EMPH0_EN_MASK;
+ data |= 0x1 << HPIPE_G1_SET_2_G1_TX_EMPH0_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SET_2_REG, data, mask);
+ /* Transmitter Slew Rate Control register (tx_reg1) */
+ mask = HPIPE_TX_REG1_TX_EMPH_RES_MASK;
+ data = 0x3 << HPIPE_TX_REG1_TX_EMPH_RES_OFFSET;
+ mask |= HPIPE_TX_REG1_SLC_EN_MASK;
+ data |= 0x3f << HPIPE_TX_REG1_SLC_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_REG1_REG, data, mask);
+ /* Impedance Calibration Control register (cal_reg1) */
+ mask = HPIPE_CAL_REG_1_EXT_TXIMP_MASK;
+ data = 0xe << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
+ mask |= HPIPE_CAL_REG_1_EXT_TXIMP_EN_MASK;
+ data |= 0x1 << HPIPE_CAL_REG_1_EXT_TXIMP_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_CAL_REG1_REG, data, mask);
+ /* Generation 1 Setting 5 (g1_setting_5) */
+ mask = HPIPE_G1_SETTING_5_G1_ICP_MASK;
+ data = 0 << HPIPE_CAL_REG_1_EXT_TXIMP_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTING_5_REG, data, mask);
+
+ /* 0xE-G1_Setting_1 */
+ mask = HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
+ data = 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
+ if (speed == COMPHY_SPEED_5_15625G) {
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
+ } else {
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
+ data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
+ data |= 0x2 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUFI_MASK;
+ data |= 0x0 << HPIPE_G1_SET_1_G1_RX_SELMUFI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUFF_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUFF_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_MASK;
+ data |= 0x3 << HPIPE_G1_SET_1_G1_RX_DIGCK_DIV_OFFSET;
+ }
+ reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
+
+ /* 0xA-DFE_Reg3 */
+ mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
+ data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
+ mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
+ data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
+
+ /* 0x111-G1_Setting_4 */
+ mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
+ data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
+ /* Genration 1 setting 3 (G1_Setting_3) */
+ mask = HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_MASK;
+ data = 0x1 << HPIPE_G1_SETTINGS_3_G1_FBCK_SEL_OFFSET;
+ if (speed == COMPHY_SPEED_5_15625G) {
+ /* Force FFE (Feed Forward Equalization) to 5G */
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
+ data |= 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
+ data |= 0x4 << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
+ data |= 0x1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
+ }
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
+
+ /* Connfigure RX training timer */
+ mask = HPIPE_RX_TRAIN_TIMER_MASK;
+ data = 0x13 << HPIPE_RX_TRAIN_TIMER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
+
+ /* Enable TX train peak to peak hold */
+ mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
+ data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
+
+ /* Configure TX preset index */
+ mask = HPIPE_TX_PRESET_INDEX_MASK;
+ data = 0x2 << HPIPE_TX_PRESET_INDEX_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_PRESET_INDEX_REG, data, mask);
+
+ /* Disable pattern lock lost timeout */
+ mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
+ data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
+
+ /* Configure TX training pattern and TX training 16bit auto */
+ mask = HPIPE_TX_TRAIN_16BIT_AUTO_EN_MASK;
+ data = 0x1 << HPIPE_TX_TRAIN_16BIT_AUTO_EN_OFFSET;
+ mask |= HPIPE_TX_TRAIN_PAT_SEL_MASK;
+ data |= 0x1 << HPIPE_TX_TRAIN_PAT_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
+
+ /* Configure Training patten number */
+ mask = HPIPE_TRAIN_PAT_NUM_MASK;
+ data = 0x88 << HPIPE_TRAIN_PAT_NUM_OFFSET;
+ reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_0_REG, data, mask);
+
+ /* Configure differencial manchester encoter to ethernet mode */
+ mask = HPIPE_DME_ETHERNET_MODE_MASK;
+ data = 0x1 << HPIPE_DME_ETHERNET_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DME_REG, data, mask);
+
+ /* Configure VDD Continuous Calibration */
+ mask = HPIPE_CAL_VDD_CONT_MODE_MASK;
+ data = 0x1 << HPIPE_CAL_VDD_CONT_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_VDD_CAL_0_REG, data, mask);
+
+ /* Trigger sampler enable pulse (by toggleing the bit) */
+ mask = HPIPE_RX_SAMPLER_OS_GAIN_MASK;
+ data = 0x3 << HPIPE_RX_SAMPLER_OS_GAIN_OFFSET;
+ mask |= HPIPE_SMAPLER_MASK;
+ data |= 0x1 << HPIPE_SMAPLER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
+ mask = HPIPE_SMAPLER_MASK;
+ data = 0x0 << HPIPE_SMAPLER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
+
+ /* Set External RX Regulator Control */
+ mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
+ data = 0x1A << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
+
+ debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
+ /* SERDES External Configuration */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+ /* check PLL rx & tx ready */
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
+ SD_EXTERNAL_STATUS0_PLL_TX_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask,
+ PLL_LOCK_TIMEOUT, REG_32BIT);
+ if (data != 0) {
+ if (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK)
+ ERROR("RX PLL is not locked\n");
+ if (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK)
+ ERROR("TX PLL is not locked\n");
+
+ ret = -ETIMEDOUT;
+ }
+
+ /* RX init */
+ mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* check that RX init done */
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
+ if (data != 0) {
+ ERROR("RX init failed\n");
+ ret = -ETIMEDOUT;
+ }
+
+ debug("stage: RF Reset\n");
+ /* RF Reset */
+ mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_pcie_power_on(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ int ret = 0;
+ uint32_t reg, mask, data, pcie_width;
+ uint32_t clk_dir;
+ uintptr_t hpipe_addr, comphy_addr, addr;
+ _Bool clk_src = COMPHY_GET_CLK_SRC(comphy_mode);
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+ pcie_width = COMPHY_GET_PCIE_WIDTH(comphy_mode);
+
+ debug_enter();
+
+ spin_lock(&cp110_mac_reset_lock);
+
+ reg = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
+ SYS_CTRL_UINIT_SOFT_RESET_REG);
+ switch (comphy_index) {
+ case COMPHY_LANE0:
+ reg |= PCIE_MAC_RESET_MASK_PORT0;
+ break;
+ case COMPHY_LANE4:
+ reg |= PCIE_MAC_RESET_MASK_PORT1;
+ break;
+ case COMPHY_LANE5:
+ reg |= PCIE_MAC_RESET_MASK_PORT2;
+ break;
+ }
+
+ mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
+ SYS_CTRL_UINIT_SOFT_RESET_REG, reg);
+ spin_unlock(&cp110_mac_reset_lock);
+
+ /* Configure PIPE selector for PCIE */
+ mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
+ comphy_mode);
+
+ /*
+ * Read SAR (Sample-At-Reset) configuration for the PCIe clock
+ * direction.
+ *
+ * SerDes Lane 4/5 got the PCIe ref-clock #1,
+ * and SerDes Lane 0 got PCIe ref-clock #0
+ */
+ reg = mmio_read_32(DFX_FROM_COMPHY_ADDR(comphy_base) +
+ SAR_STATUS_0_REG);
+ if (comphy_index == COMPHY_LANE4 || comphy_index == COMPHY_LANE5)
+ clk_dir = (reg & SAR_RST_PCIE1_CLOCK_CONFIG_CP1_MASK) >>
+ SAR_RST_PCIE1_CLOCK_CONFIG_CP1_OFFSET;
+ else
+ clk_dir = (reg & SAR_RST_PCIE0_CLOCK_CONFIG_CP1_MASK) >>
+ SAR_RST_PCIE0_CLOCK_CONFIG_CP1_OFFSET;
+
+ debug("On lane %d\n", comphy_index);
+ debug("PCIe clock direction = %x\n", clk_dir);
+ debug("PCIe Width = %d\n", pcie_width);
+
+ /* enable PCIe X4 and X2 */
+ if (comphy_index == COMPHY_LANE0) {
+ if (pcie_width == PCIE_LNK_X4) {
+ data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X4_EN_OFFSET;
+ mask = COMMON_PHY_SD_CTRL1_PCIE_X4_EN_MASK;
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
+ data, mask);
+ } else if (pcie_width == PCIE_LNK_X2) {
+ data = 0x1 << COMMON_PHY_SD_CTRL1_PCIE_X2_EN_OFFSET;
+ mask = COMMON_PHY_SD_CTRL1_PCIE_X2_EN_MASK;
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
+ }
+ }
+
+ /* If PCIe clock is output and clock source from SerDes lane 5,
+ * need to configure the clock-source MUX.
+ * By default, the clock source is from lane 4
+ */
+ if (clk_dir && clk_src && (comphy_index == COMPHY_LANE5)) {
+ data = DFX_DEV_GEN_PCIE_CLK_SRC_MUX <<
+ DFX_DEV_GEN_PCIE_CLK_SRC_OFFSET;
+ mask = DFX_DEV_GEN_PCIE_CLK_SRC_MASK;
+ reg_set(DFX_FROM_COMPHY_ADDR(comphy_base) +
+ DFX_DEV_GEN_CTRL12_REG, data, mask);
+ }
+
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ mask |= COMMON_PHY_PHY_MODE_MASK;
+ data |= 0x0 << COMMON_PHY_PHY_MODE_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* release from hard reset */
+ mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+ /* Start comphy Configuration */
+ debug("stage: Comphy configuration\n");
+ /* Set PIPE soft reset */
+ mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
+ data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
+ /* Set PHY datapath width mode for V0 */
+ mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
+ data |= 0x1 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
+ /* Set Data bus width USB mode for V0 */
+ mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
+ data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
+ /* Set CORE_CLK output frequency for 250Mhz */
+ mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
+ data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
+ /* Set PLL ready delay for 0x2 */
+ data = 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET;
+ mask = HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK;
+ if (pcie_width != PCIE_LNK_X1) {
+ data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_OFFSET;
+ mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SEL_MASK;
+ data |= 0x1 << HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_OFFSET;
+ mask |= HPIPE_CLK_SRC_LO_BUNDLE_PERIOD_SCALE_MASK;
+ }
+ reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG, data, mask);
+
+ /* Set PIPE mode interface to PCIe3 - 0x1 & set lane order */
+ data = 0x1 << HPIPE_CLK_SRC_HI_MODE_PIPE_OFFSET;
+ mask = HPIPE_CLK_SRC_HI_MODE_PIPE_MASK;
+ if (pcie_width != PCIE_LNK_X1) {
+ mask |= HPIPE_CLK_SRC_HI_LANE_STRT_MASK;
+ mask |= HPIPE_CLK_SRC_HI_LANE_MASTER_MASK;
+ mask |= HPIPE_CLK_SRC_HI_LANE_BREAK_MASK;
+ if (comphy_index == 0) {
+ data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_STRT_OFFSET;
+ data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_MASTER_OFFSET;
+ } else if (comphy_index == (pcie_width - 1)) {
+ data |= 0x1 << HPIPE_CLK_SRC_HI_LANE_BREAK_OFFSET;
+ }
+ }
+ reg_set(hpipe_addr + HPIPE_CLK_SRC_HI_REG, data, mask);
+ /* Config update polarity equalization */
+ data = 0x1 << HPIPE_CFG_UPDATE_POLARITY_OFFSET;
+ mask = HPIPE_CFG_UPDATE_POLARITY_MASK;
+ reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG1_REG, data, mask);
+ /* Set PIPE version 4 to mode enable */
+ data = 0x1 << HPIPE_DFE_CTRL_28_PIPE4_OFFSET;
+ mask = HPIPE_DFE_CTRL_28_PIPE4_MASK;
+ reg_set(hpipe_addr + HPIPE_DFE_CTRL_28_REG, data, mask);
+ /* TODO: check if pcie clock is output/input - for bringup use input*/
+ /* Enable PIN clock 100M_125M */
+ mask = 0;
+ data = 0;
+ /* Only if clock is output, configure the clock-source mux */
+ if (clk_dir) {
+ mask |= HPIPE_MISC_CLK100M_125M_MASK;
+ data |= 0x1 << HPIPE_MISC_CLK100M_125M_OFFSET;
+ }
+ /* Set PIN_TXDCLK_2X Clock Freq. Selection for outputs 500MHz clock */
+ mask |= HPIPE_MISC_TXDCLK_2X_MASK;
+ data |= 0x0 << HPIPE_MISC_TXDCLK_2X_OFFSET;
+ /* Enable 500MHz Clock */
+ mask |= HPIPE_MISC_CLK500_EN_MASK;
+ data |= 0x1 << HPIPE_MISC_CLK500_EN_OFFSET;
+ if (clk_dir) { /* output */
+ /* Set reference clock comes from group 1 */
+ mask |= HPIPE_MISC_REFCLK_SEL_MASK;
+ data |= 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET;
+ } else {
+ /* Set reference clock comes from group 2 */
+ mask |= HPIPE_MISC_REFCLK_SEL_MASK;
+ data |= 0x1 << HPIPE_MISC_REFCLK_SEL_OFFSET;
+ }
+ mask |= HPIPE_MISC_ICP_FORCE_MASK;
+ data |= 0x1 << HPIPE_MISC_ICP_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_MISC_REG, data, mask);
+ if (clk_dir) { /* output */
+ /* Set reference frequcency select - 0x2 for 25MHz*/
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ } else {
+ /* Set reference frequcency select - 0x0 for 100MHz*/
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x0 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ }
+ /* Set PHY mode to PCIe */
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x3 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+
+ /* ref clock alignment */
+ if (pcie_width != PCIE_LNK_X1) {
+ mask = HPIPE_LANE_ALIGN_OFF_MASK;
+ data = 0x0 << HPIPE_LANE_ALIGN_OFF_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LANE_ALIGN_REG, data, mask);
+ }
+
+ /* Set the amount of time spent in the LoZ state - set for 0x7 only if
+ * the PCIe clock is output
+ */
+ if (clk_dir)
+ reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
+ 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
+ HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
+
+ /* Set Maximal PHY Generation Setting(8Gbps) */
+ mask = HPIPE_INTERFACE_GEN_MAX_MASK;
+ data = 0x2 << HPIPE_INTERFACE_GEN_MAX_OFFSET;
+ /* Bypass frame detection and sync detection for RX DATA */
+ mask |= HPIPE_INTERFACE_DET_BYPASS_MASK;
+ data |= 0x1 << HPIPE_INTERFACE_DET_BYPASS_OFFSET;
+ /* Set Link Train Mode (Tx training control pins are used) */
+ mask |= HPIPE_INTERFACE_LINK_TRAIN_MASK;
+ data |= 0x1 << HPIPE_INTERFACE_LINK_TRAIN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_INTERFACE_REG, data, mask);
+
+ /* Set Idle_sync enable */
+ mask = HPIPE_PCIE_IDLE_SYNC_MASK;
+ data = 0x1 << HPIPE_PCIE_IDLE_SYNC_OFFSET;
+ /* Select bits for PCIE Gen3(32bit) */
+ mask |= HPIPE_PCIE_SEL_BITS_MASK;
+ data |= 0x2 << HPIPE_PCIE_SEL_BITS_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PCIE_REG0, data, mask);
+
+ /* Enable Tx_adapt_g1 */
+ mask = HPIPE_TX_TRAIN_CTRL_G1_MASK;
+ data = 0x1 << HPIPE_TX_TRAIN_CTRL_G1_OFFSET;
+ /* Enable Tx_adapt_gn1 */
+ mask |= HPIPE_TX_TRAIN_CTRL_GN1_MASK;
+ data |= 0x1 << HPIPE_TX_TRAIN_CTRL_GN1_OFFSET;
+ /* Disable Tx_adapt_g0 */
+ mask |= HPIPE_TX_TRAIN_CTRL_G0_MASK;
+ data |= 0x0 << HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
+
+ /* Set reg_tx_train_chk_init */
+ mask = HPIPE_TX_TRAIN_CHK_INIT_MASK;
+ data = 0x0 << HPIPE_TX_TRAIN_CHK_INIT_OFFSET;
+ /* Enable TX_COE_FM_PIN_PCIE3_EN */
+ mask |= HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_MASK;
+ data |= 0x1 << HPIPE_TX_TRAIN_COE_FM_PIN_PCIE3_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_REG, data, mask);
+
+ debug("stage: TRx training parameters\n");
+ /* Set Preset sweep configurations */
+ mask = HPIPE_TX_TX_STATUS_CHECK_MODE_MASK;
+ data = 0x1 << HPIPE_TX_STATUS_CHECK_MODE_OFFSET;
+ mask |= HPIPE_TX_NUM_OF_PRESET_MASK;
+ data |= 0x7 << HPIPE_TX_NUM_OF_PRESET_OFFSET;
+ mask |= HPIPE_TX_SWEEP_PRESET_EN_MASK;
+ data |= 0x1 << HPIPE_TX_SWEEP_PRESET_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_11_REG, data, mask);
+
+ /* Tx train start configuration */
+ mask = HPIPE_TX_TRAIN_START_SQ_EN_MASK;
+ data = 0x1 << HPIPE_TX_TRAIN_START_SQ_EN_OFFSET;
+ mask |= HPIPE_TX_TRAIN_START_FRM_DET_EN_MASK;
+ data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_DET_EN_OFFSET;
+ mask |= HPIPE_TX_TRAIN_START_FRM_LOCK_EN_MASK;
+ data |= 0x0 << HPIPE_TX_TRAIN_START_FRM_LOCK_EN_OFFSET;
+ mask |= HPIPE_TX_TRAIN_WAIT_TIME_EN_MASK;
+ data |= 0x1 << HPIPE_TX_TRAIN_WAIT_TIME_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_5_REG, data, mask);
+
+ /* Enable Tx train P2P */
+ mask = HPIPE_TX_TRAIN_P2P_HOLD_MASK;
+ data = 0x1 << HPIPE_TX_TRAIN_P2P_HOLD_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_0_REG, data, mask);
+
+ /* Configure Tx train timeout */
+ mask = HPIPE_TRX_TRAIN_TIMER_MASK;
+ data = 0x17 << HPIPE_TRX_TRAIN_TIMER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_4_REG, data, mask);
+
+ /* Disable G0/G1/GN1 adaptation */
+ mask = HPIPE_TX_TRAIN_CTRL_G1_MASK | HPIPE_TX_TRAIN_CTRL_GN1_MASK
+ | HPIPE_TX_TRAIN_CTRL_G0_OFFSET;
+ data = 0;
+ reg_set(hpipe_addr + HPIPE_TX_TRAIN_CTRL_REG, data, mask);
+
+ /* Disable DTL frequency loop */
+ mask = HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK;
+ data = 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG, data, mask);
+
+ /* Configure G3 DFE */
+ mask = HPIPE_G3_DFE_RES_MASK;
+ data = 0x3 << HPIPE_G3_DFE_RES_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SETTING_4_REG, data, mask);
+
+ /* Use TX/RX training result for DFE */
+ mask = HPIPE_DFE_RES_FORCE_MASK;
+ data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
+
+ /* Configure initial and final coefficient value for receiver */
+ mask = HPIPE_G3_SET_1_G3_RX_SELMUPI_MASK;
+ data = 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPI_OFFSET;
+
+ mask |= HPIPE_G3_SET_1_G3_RX_SELMUPF_MASK;
+ data |= 0x1 << HPIPE_G3_SET_1_G3_RX_SELMUPF_OFFSET;
+
+ mask |= HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_MASK;
+ data |= 0x0 << HPIPE_G3_SET_1_G3_SAMPLER_INPAIRX2_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SET_1_REG, data, mask);
+
+ /* Trigger sampler enable pulse */
+ mask = HPIPE_SMAPLER_MASK;
+ data = 0x1 << HPIPE_SMAPLER_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, data, mask);
+ udelay(5);
+ reg_set(hpipe_addr + HPIPE_SAMPLER_N_PROC_CALIB_CTRL_REG, 0, mask);
+
+ /* FFE resistor tuning for different bandwidth */
+ mask = HPIPE_G3_FFE_DEG_RES_LEVEL_MASK;
+ data = 0x1 << HPIPE_G3_FFE_DEG_RES_LEVEL_OFFSET;
+ mask |= HPIPE_G3_FFE_LOAD_RES_LEVEL_MASK;
+ data |= 0x3 << HPIPE_G3_FFE_LOAD_RES_LEVEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SETTING_3_REG, data, mask);
+
+ /* Pattern lock lost timeout disable */
+ mask = HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_MASK;
+ data = 0x0 << HPIPE_PATTERN_LOCK_LOST_TIMEOUT_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_FRAME_DETECT_CTRL_3_REG, data, mask);
+
+ /* Configure DFE adaptations */
+ mask = HPIPE_CDR_RX_MAX_DFE_ADAPT_0_MASK;
+ data = 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_0_OFFSET;
+ mask |= HPIPE_CDR_RX_MAX_DFE_ADAPT_1_MASK;
+ data |= 0x0 << HPIPE_CDR_RX_MAX_DFE_ADAPT_1_OFFSET;
+ mask |= HPIPE_CDR_MAX_DFE_ADAPT_0_MASK;
+ data |= 0x0 << HPIPE_CDR_MAX_DFE_ADAPT_0_OFFSET;
+ mask |= HPIPE_CDR_MAX_DFE_ADAPT_1_MASK;
+ data |= 0x1 << HPIPE_CDR_MAX_DFE_ADAPT_1_OFFSET;
+ reg_set(hpipe_addr + HPIPE_CDR_CONTROL_REG, data, mask);
+
+ mask = HPIPE_DFE_TX_MAX_DFE_ADAPT_MASK;
+ data = 0x0 << HPIPE_DFE_TX_MAX_DFE_ADAPT_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_CONTROL_REG, data, mask);
+
+ /* Genration 2 setting 1*/
+ mask = HPIPE_G2_SET_1_G2_RX_SELMUPI_MASK;
+ data = 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_SELMUPP_MASK;
+ data |= 0x1 << HPIPE_G2_SET_1_G2_RX_SELMUPP_OFFSET;
+ mask |= HPIPE_G2_SET_1_G2_RX_SELMUFI_MASK;
+ data |= 0x0 << HPIPE_G2_SET_1_G2_RX_SELMUFI_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G2_SET_1_REG, data, mask);
+
+ /* DFE enable */
+ mask = HPIPE_G2_DFE_RES_MASK;
+ data = 0x3 << HPIPE_G2_DFE_RES_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G2_SETTINGS_4_REG, data, mask);
+
+ /* Configure DFE Resolution */
+ mask = HPIPE_LANE_CFG4_DFE_EN_SEL_MASK;
+ data = 0x1 << HPIPE_LANE_CFG4_DFE_EN_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
+
+ /* VDD calibration control */
+ mask = HPIPE_EXT_SELLV_RXSAMPL_MASK;
+ data = 0x16 << HPIPE_EXT_SELLV_RXSAMPL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_VDD_CAL_CTRL_REG, data, mask);
+
+ /* Set PLL Charge-pump Current Control */
+ mask = HPIPE_G3_SETTING_5_G3_ICP_MASK;
+ data = 0x4 << HPIPE_G3_SETTING_5_G3_ICP_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G3_SETTING_5_REG, data, mask);
+
+ /* Set lane rqualization remote setting */
+ mask = HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_MASK;
+ data = 0x1 << HPIPE_LANE_CFG_FOM_DIRN_OVERRIDE_OFFSET;
+ mask |= HPIPE_LANE_CFG_FOM_ONLY_MODE_MASK;
+ data |= 0x1 << HPIPE_LANE_CFG_FOM_ONLY_MODE_OFFFSET;
+ mask |= HPIPE_LANE_CFG_FOM_PRESET_VECTOR_MASK;
+ data |= 0x6 << HPIPE_LANE_CFG_FOM_PRESET_VECTOR_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LANE_EQ_REMOTE_SETTING_REG, data, mask);
+
+ mask = HPIPE_CFG_EQ_BUNDLE_DIS_MASK;
+ data = 0x1 << HPIPE_CFG_EQ_BUNDLE_DIS_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LANE_EQ_CFG2_REG, data, mask);
+
+ debug("stage: Comphy power up\n");
+
+ /* For PCIe X4 or X2:
+ * release from reset only after finish to configure all lanes
+ */
+ if ((pcie_width == PCIE_LNK_X1) || (comphy_index == (pcie_width - 1))) {
+ uint32_t i, start_lane, end_lane;
+
+ if (pcie_width != PCIE_LNK_X1) {
+ /* allows writing to all lanes in one write */
+ data = 0x0;
+ if (pcie_width == PCIE_LNK_X2)
+ mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
+ else if (pcie_width == PCIE_LNK_X4)
+ mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1, data, mask);
+ start_lane = 0;
+ end_lane = pcie_width;
+
+ /* Release from PIPE soft reset
+ * For PCIe by4 or by2:
+ * release from soft reset all lanes - can't use
+ * read modify write
+ */
+ reg_set(HPIPE_ADDR(
+ COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), 0) +
+ HPIPE_RST_CLK_CTRL_REG, 0x24, 0xffffffff);
+ } else {
+ start_lane = comphy_index;
+ end_lane = comphy_index + 1;
+
+ /* Release from PIPE soft reset
+ * for PCIe by4 or by2:
+ * release from soft reset all lanes
+ */
+ reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
+ 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
+ HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
+ }
+
+ if (pcie_width != PCIE_LNK_X1) {
+ /* disable writing to all lanes with one write */
+ if (pcie_width == PCIE_LNK_X2) {
+ data = (COMPHY_LANE0 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
+ (COMPHY_LANE1 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET);
+ mask = COMMON_PHY_SD_CTRL1_COMPHY_0_1_PORT_MASK;
+ } else if (pcie_width == PCIE_LNK_X4) {
+ data = (COMPHY_LANE0 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_0_PORT_OFFSET) |
+ (COMPHY_LANE1 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_1_PORT_OFFSET) |
+ (COMPHY_LANE2 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_2_PORT_OFFSET) |
+ (COMPHY_LANE3 <<
+ COMMON_PHY_SD_CTRL1_COMPHY_3_PORT_OFFSET);
+ mask = COMMON_PHY_SD_CTRL1_COMPHY_0_3_PORT_MASK;
+ }
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
+ data, mask);
+ }
+
+ debug("stage: Check PLL\n");
+ /* Read lane status */
+ for (i = start_lane; i < end_lane; i++) {
+ addr = HPIPE_ADDR(
+ COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base), i) +
+ HPIPE_LANE_STATUS1_REG;
+ data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
+ mask = data;
+ ret = polling_with_timeout(addr, data, mask,
+ PLL_LOCK_TIMEOUT,
+ REG_32BIT);
+ if (ret)
+ ERROR("Failed to lock PCIE PLL\n");
+ }
+ }
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_rxaui_power_on(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uintptr_t hpipe_addr, sd_ip_addr, comphy_addr, addr;
+ uint32_t mask, data;
+ int ret = 0;
+
+ debug_enter();
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ /* configure phy selector for RXAUI */
+ mvebu_cp110_comphy_set_phy_selector(comphy_base, comphy_index,
+ comphy_mode);
+
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ if (comphy_index == 2) {
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
+ 0x1 << COMMON_PHY_SD_CTRL1_RXAUI0_OFFSET,
+ COMMON_PHY_SD_CTRL1_RXAUI0_MASK);
+ }
+ if (comphy_index == 4) {
+ reg_set(comphy_base + COMMON_PHY_SD_CTRL1,
+ 0x1 << COMMON_PHY_SD_CTRL1_RXAUI1_OFFSET,
+ COMMON_PHY_SD_CTRL1_RXAUI1_MASK);
+ }
+
+ /* Select Baud Rate of Comphy And PD_PLL/Tx/Rx */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_MASK;
+ data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_MASK;
+ data |= 0xB << SD_EXTERNAL_CONFIG0_SD_PHY_GEN_TX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG0_HALF_BUS_MODE_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_MEDIA_MODE_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_MEDIA_MODE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+ /* release from hard reset */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+
+ /* Start comphy Configuration */
+ debug("stage: Comphy configuration\n");
+ /* set reference clock */
+ reg_set(hpipe_addr + HPIPE_MISC_REG,
+ 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
+ HPIPE_MISC_REFCLK_SEL_MASK);
+ /* Power and PLL Control */
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x1 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x4 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+ /* Loopback register */
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
+ 0x1 << HPIPE_LOOPBACK_SEL_OFFSET, HPIPE_LOOPBACK_SEL_MASK);
+ /* rx control 1 */
+ mask = HPIPE_RX_CONTROL_1_RXCLK2X_SEL_MASK;
+ data = 0x1 << HPIPE_RX_CONTROL_1_RXCLK2X_SEL_OFFSET;
+ mask |= HPIPE_RX_CONTROL_1_CLK8T_EN_MASK;
+ data |= 0x1 << HPIPE_RX_CONTROL_1_CLK8T_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_RX_CONTROL_1_REG, data, mask);
+ /* DTL Control */
+ reg_set(hpipe_addr + HPIPE_PWR_CTR_DTL_REG,
+ 0x0 << HPIPE_PWR_CTR_DTL_FLOOP_EN_OFFSET,
+ HPIPE_PWR_CTR_DTL_FLOOP_EN_MASK);
+
+ /* Set analog parameters from ETP(HW) */
+ debug("stage: Analog parameters from ETP(HW)\n");
+ /* SERDES External Configuration 2 */
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG2_REG,
+ 0x1 << SD_EXTERNAL_CONFIG2_PIN_DFE_EN_OFFSET,
+ SD_EXTERNAL_CONFIG2_PIN_DFE_EN_MASK);
+ /* 0x7-DFE Resolution control */
+ reg_set(hpipe_addr + HPIPE_DFE_REG0, 0x1 << HPIPE_DFE_RES_FORCE_OFFSET,
+ HPIPE_DFE_RES_FORCE_MASK);
+ /* 0xd-G1_Setting_0 */
+ reg_set(hpipe_addr + HPIPE_G1_SET_0_REG,
+ 0xd << HPIPE_G1_SET_0_G1_TX_EMPH1_OFFSET,
+ HPIPE_G1_SET_0_G1_TX_EMPH1_MASK);
+ /* 0xE-G1_Setting_1 */
+ mask = HPIPE_G1_SET_1_G1_RX_SELMUPI_MASK;
+ data = 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPI_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_SELMUPP_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_SELMUPP_OFFSET;
+ mask |= HPIPE_G1_SET_1_G1_RX_DFE_EN_MASK;
+ data |= 0x1 << HPIPE_G1_SET_1_G1_RX_DFE_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SET_1_REG, data, mask);
+ /* 0xA-DFE_Reg3 */
+ mask = HPIPE_DFE_F3_F5_DFE_EN_MASK;
+ data = 0x0 << HPIPE_DFE_F3_F5_DFE_EN_OFFSET;
+ mask |= HPIPE_DFE_F3_F5_DFE_CTRL_MASK;
+ data |= 0x0 << HPIPE_DFE_F3_F5_DFE_CTRL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_F3_F5_REG, data, mask);
+
+ /* 0x111-G1_Setting_4 */
+ mask = HPIPE_G1_SETTINGS_4_G1_DFE_RES_MASK;
+ data = 0x1 << HPIPE_G1_SETTINGS_4_G1_DFE_RES_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_4_REG, data, mask);
+
+ debug("stage: RFU configurations- Power Up PLL,Tx,Rx\n");
+ /* SERDES External Configuration */
+ mask = SD_EXTERNAL_CONFIG0_SD_PU_PLL_MASK;
+ data = 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_PLL_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_RX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_RX_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG0_SD_PU_TX_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG0_SD_PU_TX_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG0_REG, data, mask);
+
+
+ /* check PLL rx & tx ready */
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_PLL_RX_MASK |
+ SD_EXTERNAL_STATUS0_PLL_TX_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
+ if (data != 0) {
+ debug("Read from reg = %lx - value = 0x%x\n",
+ sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
+ ERROR("SD_EXTERNAL_STATUS0_PLL_RX is %d, -\"-_PLL_TX is %d\n",
+ (data & SD_EXTERNAL_STATUS0_PLL_RX_MASK),
+ (data & SD_EXTERNAL_STATUS0_PLL_TX_MASK));
+ ret = -ETIMEDOUT;
+ }
+
+ /* RX init */
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG,
+ 0x1 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET,
+ SD_EXTERNAL_CONFIG1_RX_INIT_MASK);
+
+ /* check that RX init done */
+ addr = sd_ip_addr + SD_EXTERNAL_STATUS0_REG;
+ data = SD_EXTERNAL_STATUS0_RX_INIT_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask, 100, REG_32BIT);
+ if (data != 0) {
+ debug("Read from reg = %lx - value = 0x%x\n",
+ sd_ip_addr + SD_EXTERNAL_STATUS0_REG, data);
+ ERROR("SD_EXTERNAL_STATUS0_RX_INIT is 0\n");
+ ret = -ETIMEDOUT;
+ }
+
+ debug("stage: RF Reset\n");
+ /* RF Reset */
+ mask = SD_EXTERNAL_CONFIG1_RX_INIT_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RX_INIT_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x1 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ debug_exit();
+
+ return ret;
+}
+
+static int mvebu_cp110_comphy_usb3_power_on(uint64_t comphy_base,
+ uint8_t comphy_index, uint32_t comphy_mode)
+{
+ uintptr_t hpipe_addr, comphy_addr, addr;
+ uint32_t mask, data;
+ int ret = 0;
+
+ debug_enter();
+
+ /* Configure PIPE selector for USB3 */
+ mvebu_cp110_comphy_set_pipe_selector(comphy_base, comphy_index,
+ comphy_mode);
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_addr = COMPHY_ADDR(comphy_base, comphy_index);
+
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x1 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ mask |= COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ mask |= COMMON_PHY_PHY_MODE_MASK;
+ data |= 0x1 << COMMON_PHY_PHY_MODE_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* release from hard reset */
+ mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x1 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Wait 1ms - until band gap and ref clock ready */
+ mdelay(1);
+
+ /* Start comphy Configuration */
+ debug("stage: Comphy configuration\n");
+ /* Set PIPE soft reset */
+ mask = HPIPE_RST_CLK_CTRL_PIPE_RST_MASK;
+ data = 0x1 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET;
+ /* Set PHY datapath width mode for V0 */
+ mask |= HPIPE_RST_CLK_CTRL_FIXED_PCLK_MASK;
+ data |= 0x0 << HPIPE_RST_CLK_CTRL_FIXED_PCLK_OFFSET;
+ /* Set Data bus width USB mode for V0 */
+ mask |= HPIPE_RST_CLK_CTRL_PIPE_WIDTH_MASK;
+ data |= 0x0 << HPIPE_RST_CLK_CTRL_PIPE_WIDTH_OFFSET;
+ /* Set CORE_CLK output frequency for 250Mhz */
+ mask |= HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_MASK;
+ data |= 0x0 << HPIPE_RST_CLK_CTRL_CORE_FREQ_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG, data, mask);
+ /* Set PLL ready delay for 0x2 */
+ reg_set(hpipe_addr + HPIPE_CLK_SRC_LO_REG,
+ 0x2 << HPIPE_CLK_SRC_LO_PLL_RDY_DL_OFFSET,
+ HPIPE_CLK_SRC_LO_PLL_RDY_DL_MASK);
+ /* Set reference clock to come from group 1 - 25Mhz */
+ reg_set(hpipe_addr + HPIPE_MISC_REG,
+ 0x0 << HPIPE_MISC_REFCLK_SEL_OFFSET,
+ HPIPE_MISC_REFCLK_SEL_MASK);
+ /* Set reference frequcency select - 0x2 */
+ mask = HPIPE_PWR_PLL_REF_FREQ_MASK;
+ data = 0x2 << HPIPE_PWR_PLL_REF_FREQ_OFFSET;
+ /* Set PHY mode to USB - 0x5 */
+ mask |= HPIPE_PWR_PLL_PHY_MODE_MASK;
+ data |= 0x5 << HPIPE_PWR_PLL_PHY_MODE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PWR_PLL_REG, data, mask);
+ /* Set the amount of time spent in the LoZ state - set for 0x7 */
+ reg_set(hpipe_addr + HPIPE_GLOBAL_PM_CTRL,
+ 0x7 << HPIPE_GLOBAL_PM_RXDLOZ_WAIT_OFFSET,
+ HPIPE_GLOBAL_PM_RXDLOZ_WAIT_MASK);
+ /* Set max PHY generation setting - 5Gbps */
+ reg_set(hpipe_addr + HPIPE_INTERFACE_REG,
+ 0x1 << HPIPE_INTERFACE_GEN_MAX_OFFSET,
+ HPIPE_INTERFACE_GEN_MAX_MASK);
+ /* Set select data width 20Bit (SEL_BITS[2:0]) */
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG,
+ 0x1 << HPIPE_LOOPBACK_SEL_OFFSET,
+ HPIPE_LOOPBACK_SEL_MASK);
+ /* select de-emphasize 3.5db */
+ reg_set(hpipe_addr + HPIPE_LANE_CONFIG0_REG,
+ 0x1 << HPIPE_LANE_CONFIG0_TXDEEMPH0_OFFSET,
+ HPIPE_LANE_CONFIG0_TXDEEMPH0_MASK);
+ /* override tx margining from the MAC */
+ reg_set(hpipe_addr + HPIPE_TST_MODE_CTRL_REG,
+ 0x1 << HPIPE_TST_MODE_CTRL_MODE_MARGIN_OFFSET,
+ HPIPE_TST_MODE_CTRL_MODE_MARGIN_MASK);
+
+ /* Start analog parameters from ETP(HW) */
+ debug("stage: Analog parameters from ETP(HW)\n");
+ /* Set Pin DFE_PAT_DIS -> Bit[1]: PIN_DFE_PAT_DIS = 0x0 */
+ mask = HPIPE_LANE_CFG4_DFE_CTRL_MASK;
+ data = 0x1 << HPIPE_LANE_CFG4_DFE_CTRL_OFFSET;
+ /* Set Override PHY DFE control pins for 0x1 */
+ mask |= HPIPE_LANE_CFG4_DFE_OVER_MASK;
+ data |= 0x1 << HPIPE_LANE_CFG4_DFE_OVER_OFFSET;
+ /* Set Spread Spectrum Clock Enable fot 0x1 */
+ mask |= HPIPE_LANE_CFG4_SSC_CTRL_MASK;
+ data |= 0x1 << HPIPE_LANE_CFG4_SSC_CTRL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LANE_CFG4_REG, data, mask);
+ /* Confifure SSC amplitude */
+ mask = HPIPE_G2_TX_SSC_AMP_MASK;
+ data = 0x1f << HPIPE_G2_TX_SSC_AMP_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G2_SET_2_REG, data, mask);
+ /* End of analog parameters */
+
+ debug("stage: Comphy power up\n");
+ /* Release from PIPE soft reset */
+ reg_set(hpipe_addr + HPIPE_RST_CLK_CTRL_REG,
+ 0x0 << HPIPE_RST_CLK_CTRL_PIPE_RST_OFFSET,
+ HPIPE_RST_CLK_CTRL_PIPE_RST_MASK);
+
+ /* wait 15ms - for comphy calibration done */
+ debug("stage: Check PLL\n");
+ /* Read lane status */
+ addr = hpipe_addr + HPIPE_LANE_STATUS1_REG;
+ data = HPIPE_LANE_STATUS1_PCLK_EN_MASK;
+ mask = data;
+ data = polling_with_timeout(addr, data, mask, 15000, REG_32BIT);
+ if (data != 0) {
+ debug("Read from reg = %lx - value = 0x%x\n",
+ hpipe_addr + HPIPE_LANE_STATUS1_REG, data);
+ ERROR("HPIPE_LANE_STATUS1_PCLK_EN_MASK is 0\n");
+ ret = -ETIMEDOUT;
+ }
+
+ debug_exit();
+
+ return ret;
+}
+
+/* This function performs RX training for one Feed Forward Equalization (FFE)
+ * value.
+ * The RX traiing result is stored in 'Saved DFE values Register' (SAV_F0D).
+ *
+ * Return '0' on success, error code in a case of failure.
+ */
+static int mvebu_cp110_comphy_test_single_ffe(uint64_t comphy_base,
+ uint8_t comphy_index,
+ uint32_t ffe, uint32_t *result)
+{
+ uint32_t mask, data, timeout;
+ uintptr_t hpipe_addr, sd_ip_addr;
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ /* Configure PRBS counters */
+ mask = HPIPE_PHY_TEST_PATTERN_SEL_MASK;
+ data = 0xe << HPIPE_PHY_TEST_PATTERN_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
+
+ mask = HPIPE_PHY_TEST_DATA_MASK;
+ data = 0x64 << HPIPE_PHY_TEST_DATA_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHY_TEST_DATA_REG, data, mask);
+
+ mask = HPIPE_PHY_TEST_EN_MASK;
+ data = 0x1 << HPIPE_PHY_TEST_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
+
+ mdelay(50);
+
+ /* Set the FFE value */
+ mask = HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_MASK;
+ data = ffe << HPIPE_G1_SETTINGS_3_G1_FFE_RES_SEL_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
+
+ /* Start RX training */
+ mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
+ data = 1 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
+
+ /* Check the result of RX training */
+ timeout = RX_TRAINING_TIMEOUT;
+ while (timeout) {
+ data = mmio_read_32(sd_ip_addr + SD_EXTERNAL_STATAUS1_REG);
+ if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_COMP_MASK)
+ break;
+ mdelay(1);
+ timeout--;
+ }
+
+ if (timeout == 0)
+ return -ETIMEDOUT;
+
+ if (data & SD_EXTERNAL_STATAUS1_REG_RX_TRAIN_FAILED_MASK)
+ return -EINVAL;
+
+ /* Stop RX training */
+ mask = SD_EXTERNAL_STATUS_START_RX_TRAINING_MASK;
+ data = 0 << SD_EXTERNAL_STATUS_START_RX_TRAINING_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_STATUS_REG, data, mask);
+
+ /* Read the result */
+ data = mmio_read_32(hpipe_addr + HPIPE_SAVED_DFE_VALUES_REG);
+ data &= HPIPE_SAVED_DFE_VALUES_SAV_F0D_MASK;
+ data >>= HPIPE_SAVED_DFE_VALUES_SAV_F0D_OFFSET;
+ *result = data;
+
+ mask = HPIPE_PHY_TEST_RESET_MASK;
+ data = 0x1 << HPIPE_PHY_TEST_RESET_OFFSET;
+ mask |= HPIPE_PHY_TEST_EN_MASK;
+ data |= 0x0 << HPIPE_PHY_TEST_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
+
+ mask = HPIPE_PHY_TEST_RESET_MASK;
+ data = 0x0 << HPIPE_PHY_TEST_RESET_OFFSET;
+ reg_set(hpipe_addr + HPIPE_PHY_TEST_CONTROL_REG, data, mask);
+
+ return 0;
+}
+
+/* This function runs complete RX training sequence:
+ * - Run RX training for all possible Feed Forward Equalization values
+ * - Choose the FFE which gives the best result.
+ * - Run RX training again with the best result.
+ *
+ * Return '0' on success, error code in a case of failure.
+ */
+int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
+ uint8_t comphy_index)
+{
+ uint32_t mask, data, max_rx_train = 0, max_rx_train_index = 0;
+ uintptr_t hpipe_addr;
+ uint32_t rx_train_result;
+ int ret, i;
+
+ hpipe_addr = HPIPE_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ debug_enter();
+
+ /* Configure SQ threshold and CDR lock */
+ mask = HPIPE_SQUELCH_THRESH_IN_MASK;
+ data = 0xc << HPIPE_SQUELCH_THRESH_IN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG, data, mask);
+
+ mask = HPIPE_SQ_DEGLITCH_WIDTH_P_MASK;
+ data = 0xf << HPIPE_SQ_DEGLITCH_WIDTH_P_OFFSET;
+ mask |= HPIPE_SQ_DEGLITCH_WIDTH_N_MASK;
+ data |= 0xf << HPIPE_SQ_DEGLITCH_WIDTH_N_OFFSET;
+ mask |= HPIPE_SQ_DEGLITCH_EN_MASK;
+ data |= 0x1 << HPIPE_SQ_DEGLITCH_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_SQ_GLITCH_FILTER_CTRL, data, mask);
+
+ mask = HPIPE_CDR_LOCK_DET_EN_MASK;
+ data = 0x1 << HPIPE_CDR_LOCK_DET_EN_OFFSET;
+ reg_set(hpipe_addr + HPIPE_LOOPBACK_REG, data, mask);
+
+ udelay(100);
+
+ /* Determine if we have a cable attached to this comphy, if not,
+ * we can't perform RX training.
+ */
+ data = mmio_read_32(hpipe_addr + HPIPE_SQUELCH_FFE_SETTING_REG);
+ if (data & HPIPE_SQUELCH_DETECTED_MASK) {
+ ERROR("Squelsh is not detected, can't perform RX training\n");
+ return -EINVAL;
+ }
+
+ data = mmio_read_32(hpipe_addr + HPIPE_LOOPBACK_REG);
+ if (!(data & HPIPE_CDR_LOCK_MASK)) {
+ ERROR("CDR is not locked, can't perform RX training\n");
+ return -EINVAL;
+ }
+
+ /* Do preparations for RX training */
+ mask = HPIPE_DFE_RES_FORCE_MASK;
+ data = 0x0 << HPIPE_DFE_RES_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_DFE_REG0, data, mask);
+
+ mask = HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_MASK;
+ data = 0xf << HPIPE_G1_SETTINGS_3_G1_FFE_CAP_SEL_OFFSET;
+ mask |= HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_MASK;
+ data |= 1 << HPIPE_G1_SETTINGS_3_G1_FFE_SETTING_FORCE_OFFSET;
+ reg_set(hpipe_addr + HPIPE_G1_SETTINGS_3_REG, data, mask);
+
+ /* Perform RX training for all possible FFE (Feed Forward
+ * Equalization, possible values are 0-7).
+ * We update the best value reached and the FFE which gave this value.
+ */
+ for (i = 0; i < MAX_NUM_OF_FFE; i++) {
+ rx_train_result = 0;
+ ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
+ comphy_index, i,
+ &rx_train_result);
+
+ if ((!ret) && (rx_train_result > max_rx_train)) {
+ max_rx_train = rx_train_result;
+ max_rx_train_index = i;
+ }
+ }
+
+ /* If we were able to determine which FFE gives the best value,
+ * now we need to set it and run RX training again (only for this
+ * FFE).
+ */
+ if (max_rx_train) {
+ ret = mvebu_cp110_comphy_test_single_ffe(comphy_base,
+ comphy_index,
+ max_rx_train_index,
+ &rx_train_result);
+
+ if (ret == 0)
+ debug("RX Training passed (FFE = %d, result = 0x%x)\n",
+ max_rx_train_index, rx_train_result);
+ } else {
+ ERROR("RX Training failed for comphy%d\n", comphy_index);
+ ret = -EINVAL;
+ }
+
+ debug_exit();
+
+ return ret;
+}
+
+/* During AP the proper mode is auto-negotiated and the mac, pcs and serdes
+ * configuration are done by the firmware loaded to the MG's CM3 for appropriate
+ * negotiated mode. Therefore there is no need to configure the mac, pcs and
+ * serdes from u-boot. The only thing that need to be setup is powering up
+ * the comphy, which is done through Common PHY<n> Configuration 1 Register
+ * (CP0: 0xF2441000, CP1: 0xF4441000). This step can't be done by MG's CM3,
+ * since it doesn't have an access to this register-set (but it has access to
+ * the network registers like: MG, AP, MAC, PCS, Serdes etc.)
+ */
+static int mvebu_cp110_comphy_ap_power_on(uint64_t comphy_base,
+ uint8_t comphy_index)
+{
+ uint32_t mask, data;
+ uintptr_t comphy_addr = comphy_addr =
+ COMPHY_ADDR(comphy_base, comphy_index);
+
+ debug_enter();
+ debug("stage: RFU configurations - hard reset comphy\n");
+ /* RFU configurations - hard reset comphy */
+ mask = COMMON_PHY_CFG1_PWR_UP_MASK;
+ data = 0x1 << COMMON_PHY_CFG1_PWR_UP_OFFSET;
+ mask |= COMMON_PHY_CFG1_PIPE_SELECT_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_PIPE_SELECT_OFFSET;
+ reg_set(comphy_addr + COMMON_PHY_CFG1_REG, data, mask);
+ debug_exit();
+
+ return 0;
+}
+
+/*
+ * This function allows to reset the digital synchronizers between
+ * the MAC and the PHY, it is required when the MAC changes its state.
+ */
+int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base,
+ uint8_t comphy_index,
+ uint32_t comphy_mode, uint32_t command)
+{
+ int mode = COMPHY_GET_MODE(comphy_mode);
+ uintptr_t sd_ip_addr;
+ uint32_t mask, data;
+
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+
+ switch (mode) {
+ case (COMPHY_SGMII_MODE):
+ case (COMPHY_HS_SGMII_MODE):
+ case (COMPHY_XFI_MODE):
+ case (COMPHY_SFI_MODE):
+ case (COMPHY_RXAUI_MODE):
+ mask = SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data = ((command == COMPHY_COMMAND_DIGITAL_PWR_OFF) ?
+ 0x0 : 0x1) << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+ break;
+ default:
+ ERROR("comphy%d: Digital PWR ON/OFF is not supported\n",
+ comphy_index);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int mvebu_cp110_comphy_power_on(uint64_t comphy_base, uint64_t comphy_index,
+ uint64_t comphy_mode)
+{
+ int mode = COMPHY_GET_MODE(comphy_mode);
+ int err = 0;
+
+ debug_enter();
+
+ switch (mode) {
+ case(COMPHY_SATA_MODE):
+ err = mvebu_cp110_comphy_sata_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ break;
+ case(COMPHY_SGMII_MODE):
+ case(COMPHY_HS_SGMII_MODE):
+ err = mvebu_cp110_comphy_sgmii_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ break;
+ /* From comphy perspective, XFI and SFI are the same */
+ case (COMPHY_XFI_MODE):
+ case (COMPHY_SFI_MODE):
+ err = mvebu_cp110_comphy_xfi_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ break;
+ case (COMPHY_PCIE_MODE):
+ err = mvebu_cp110_comphy_pcie_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ break;
+ case (COMPHY_RXAUI_MODE):
+ err = mvebu_cp110_comphy_rxaui_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ case (COMPHY_USB3H_MODE):
+ case (COMPHY_USB3D_MODE):
+ err = mvebu_cp110_comphy_usb3_power_on(comphy_base,
+ comphy_index,
+ comphy_mode);
+ break;
+ case (COMPHY_AP_MODE):
+ err = mvebu_cp110_comphy_ap_power_on(comphy_base, comphy_index);
+ break;
+ default:
+ ERROR("comphy%lld: unsupported comphy mode\n", comphy_index);
+ err = -EINVAL;
+ break;
+ }
+
+ debug_exit();
+
+ return err;
+}
+
+int mvebu_cp110_comphy_power_off(uint64_t comphy_base, uint64_t comphy_index)
+{
+ uintptr_t sd_ip_addr, comphy_ip_addr;
+ uint32_t mask, data;
+
+ debug_enter();
+
+ sd_ip_addr = SD_ADDR(COMPHY_PIPE_FROM_COMPHY_ADDR(comphy_base),
+ comphy_index);
+ comphy_ip_addr = COMPHY_ADDR(comphy_base, comphy_index);
+
+ /* Hard reset the comphy, for Ethernet modes and Sata */
+ mask = SD_EXTERNAL_CONFIG1_RESET_IN_MASK;
+ data = 0x0 << SD_EXTERNAL_CONFIG1_RESET_IN_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RESET_CORE_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RESET_CORE_OFFSET;
+ mask |= SD_EXTERNAL_CONFIG1_RF_RESET_IN_MASK;
+ data |= 0x0 << SD_EXTERNAL_CONFIG1_RF_RESET_IN_OFFSET;
+ reg_set(sd_ip_addr + SD_EXTERNAL_CONFIG1_REG, data, mask);
+
+ /* PCIe reset */
+ spin_lock(&cp110_mac_reset_lock);
+
+ /* The mvebu_cp110_comphy_power_off will be called only from Linux (to
+ * override settings done by bootloader) and it will be relevant only
+ * to PCIe (called before check if to skip pcie power off or not).
+ */
+ data = mmio_read_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
+ SYS_CTRL_UINIT_SOFT_RESET_REG);
+ switch (comphy_index) {
+ case COMPHY_LANE0:
+ data &= ~PCIE_MAC_RESET_MASK_PORT0;
+ break;
+ case COMPHY_LANE4:
+ data &= ~PCIE_MAC_RESET_MASK_PORT1;
+ break;
+ case COMPHY_LANE5:
+ data &= ~PCIE_MAC_RESET_MASK_PORT2;
+ break;
+ }
+
+ mmio_write_32(SYS_CTRL_FROM_COMPHY_ADDR(comphy_base) +
+ SYS_CTRL_UINIT_SOFT_RESET_REG, data);
+ spin_unlock(&cp110_mac_reset_lock);
+
+ /* Hard reset the comphy, for PCIe and usb3 */
+ mask = COMMON_PHY_CFG1_PWR_ON_RESET_MASK;
+ data = 0x0 << COMMON_PHY_CFG1_PWR_ON_RESET_OFFSET;
+ mask |= COMMON_PHY_CFG1_CORE_RSTN_MASK;
+ data |= 0x0 << COMMON_PHY_CFG1_CORE_RSTN_OFFSET;
+ reg_set(comphy_ip_addr + COMMON_PHY_CFG1_REG, data, mask);
+
+ /* Clear comphy PHY and PIPE selector, can't rely on previous config. */
+ mvebu_cp110_comphy_clr_phy_selector(comphy_base, comphy_index);
+ mvebu_cp110_comphy_clr_pipe_selector(comphy_base, comphy_index);
+
+ debug_exit();
+
+ return 0;
+}
diff --git a/drivers/marvell/comphy/phy-comphy-cp110.h b/drivers/marvell/comphy/phy-comphy-cp110.h
new file mode 100644
index 000000000..ada6aecae
--- /dev/null
+++ b/drivers/marvell/comphy/phy-comphy-cp110.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Marvell CP110 SoC COMPHY unit driver */
+
+int mvebu_cp110_comphy_is_pll_locked(uint64_t comphy_base,
+ uint64_t comphy_index);
+int mvebu_cp110_comphy_power_off(uint64_t comphy_base,
+ uint64_t comphy_index);
+int mvebu_cp110_comphy_power_on(uint64_t comphy_base,
+ uint64_t comphy_index, uint64_t comphy_mode);
+int mvebu_cp110_comphy_xfi_rx_training(uint64_t comphy_base,
+ uint8_t comphy_index);
+int mvebu_cp110_comphy_digital_reset(uint64_t comphy_base, uint8_t comphy_index,
+ uint32_t comphy_mode, uint32_t command);
diff --git a/drivers/marvell/gwin.c b/drivers/marvell/gwin.c
new file mode 100644
index 000000000..b5705f7a4
--- /dev/null
+++ b/drivers/marvell/gwin.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* GWIN unit device driver for Marvell AP810 SoC */
+
+#include <a8k_common.h>
+#include <debug.h>
+#include <gwin.h>
+#include <mmio.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+#define DEBUG_ADDR_MAP
+#endif
+
+/* common defines */
+#define WIN_ENABLE_BIT (0x1)
+#define WIN_TARGET_MASK (0xF)
+#define WIN_TARGET_SHIFT (0x8)
+#define WIN_TARGET(tgt) (((tgt) & WIN_TARGET_MASK) \
+ << WIN_TARGET_SHIFT)
+
+/* Bits[43:26] of the physical address are the window base,
+ * which is aligned to 64MB
+ */
+#define ADDRESS_RSHIFT (26)
+#define ADDRESS_LSHIFT (10)
+#define GWIN_ALIGNMENT_64M (0x4000000)
+
+/* AP registers */
+#define GWIN_CR_OFFSET(ap, win) (MVEBU_GWIN_BASE(ap) + 0x0 + \
+ (0x10 * (win)))
+#define GWIN_ALR_OFFSET(ap, win) (MVEBU_GWIN_BASE(ap) + 0x8 + \
+ (0x10 * (win)))
+#define GWIN_AHR_OFFSET(ap, win) (MVEBU_GWIN_BASE(ap) + 0xc + \
+ (0x10 * (win)))
+
+#define CCU_GRU_CR_OFFSET(ap) (MVEBU_CCU_GRU_BASE(ap))
+#define CCR_GRU_CR_GWIN_MBYPASS (1 << 1)
+
+static void gwin_check(struct addr_map_win *win)
+{
+ /* The base is always 64M aligned */
+ if (IS_NOT_ALIGN(win->base_addr, GWIN_ALIGNMENT_64M)) {
+ win->base_addr &= ~(GWIN_ALIGNMENT_64M - 1);
+ NOTICE("%s: Align the base address to 0x%llx\n",
+ __func__, win->base_addr);
+ }
+
+ /* size parameter validity check */
+ if (IS_NOT_ALIGN(win->win_size, GWIN_ALIGNMENT_64M)) {
+ win->win_size = ALIGN_UP(win->win_size, GWIN_ALIGNMENT_64M);
+ NOTICE("%s: Aligning window size to 0x%llx\n",
+ __func__, win->win_size);
+ }
+}
+
+static void gwin_enable_window(int ap_index, struct addr_map_win *win,
+ uint32_t win_num)
+{
+ uint32_t alr, ahr;
+ uint64_t end_addr;
+
+ if ((win->target_id & WIN_TARGET_MASK) != win->target_id) {
+ ERROR("target ID = %d, is invalid\n", win->target_id);
+ return;
+ }
+
+ /* calculate 64bit end-address */
+ end_addr = (win->base_addr + win->win_size - 1);
+
+ alr = (uint32_t)((win->base_addr >> ADDRESS_RSHIFT) << ADDRESS_LSHIFT);
+ ahr = (uint32_t)((end_addr >> ADDRESS_RSHIFT) << ADDRESS_LSHIFT);
+
+ /* write start address and end address for GWIN */
+ mmio_write_32(GWIN_ALR_OFFSET(ap_index, win_num), alr);
+ mmio_write_32(GWIN_AHR_OFFSET(ap_index, win_num), ahr);
+
+ /* write the target ID and enable the window */
+ mmio_write_32(GWIN_CR_OFFSET(ap_index, win_num),
+ WIN_TARGET(win->target_id) | WIN_ENABLE_BIT);
+}
+
+static void gwin_disable_window(int ap_index, uint32_t win_num)
+{
+ uint32_t win_reg;
+
+ win_reg = mmio_read_32(GWIN_CR_OFFSET(ap_index, win_num));
+ win_reg &= ~WIN_ENABLE_BIT;
+ mmio_write_32(GWIN_CR_OFFSET(ap_index, win_num), win_reg);
+}
+
+/* Insert/Remove temporary window for using the out-of reset default
+ * CPx base address to access the CP configuration space prior to
+ * the further base address update in accordance with address mapping
+ * design.
+ *
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void gwin_temp_win_insert(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ for (int i = 0; i < size; i++) {
+ win_id = MVEBU_GWIN_MAX_WINS - i - 1;
+ gwin_check(win);
+ gwin_enable_window(ap_index, win, win_id);
+ win++;
+ }
+}
+
+/*
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void gwin_temp_win_remove(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ for (int i = 0; i < size; i++) {
+ uint64_t base;
+ uint32_t target;
+
+ win_id = MVEBU_GWIN_MAX_WINS - i - 1;
+
+ target = mmio_read_32(GWIN_CR_OFFSET(ap_index, win_id));
+ target >>= WIN_TARGET_SHIFT;
+ target &= WIN_TARGET_MASK;
+
+ base = mmio_read_32(GWIN_ALR_OFFSET(ap_index, win_id));
+ base >>= ADDRESS_LSHIFT;
+ base <<= ADDRESS_RSHIFT;
+
+ if (win->target_id != target) {
+ ERROR("%s: Trying to remove bad window-%d!\n",
+ __func__, win_id);
+ continue;
+ }
+ gwin_disable_window(ap_index, win_id);
+ win++;
+ }
+}
+
+#ifdef DEBUG_ADDR_MAP
+static void dump_gwin(int ap_index)
+{
+ uint32_t win_num;
+
+ /* Dump all GWIN windows */
+ printf("\tbank target start end\n");
+ printf("\t----------------------------------------------------\n");
+ for (win_num = 0; win_num < MVEBU_GWIN_MAX_WINS; win_num++) {
+ uint32_t cr;
+ uint64_t alr, ahr;
+
+ cr = mmio_read_32(GWIN_CR_OFFSET(ap_index, win_num));
+ /* Window enabled */
+ if (cr & WIN_ENABLE_BIT) {
+ alr = mmio_read_32(GWIN_ALR_OFFSET(ap_index, win_num));
+ alr = (alr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
+ ahr = mmio_read_32(GWIN_AHR_OFFSET(ap_index, win_num));
+ ahr = (ahr >> ADDRESS_LSHIFT) << ADDRESS_RSHIFT;
+ printf("\tgwin %d 0x%016llx 0x%016llx\n",
+ (cr >> 8) & 0xF, alr, ahr);
+ }
+ }
+}
+#endif
+
+int init_gwin(int ap_index)
+{
+ struct addr_map_win *win;
+ uint32_t win_id;
+ uint32_t win_count;
+ uint32_t win_reg;
+
+ INFO("Initializing GWIN Address decoding\n");
+
+ /* Get the array of the windows and its size */
+ marvell_get_gwin_memory_map(ap_index, &win, &win_count);
+ if (win_count <= 0) {
+ INFO("no windows configurations found\n");
+ return 0;
+ }
+
+ if (win_count > MVEBU_GWIN_MAX_WINS) {
+ ERROR("number of windows is bigger than %d\n",
+ MVEBU_GWIN_MAX_WINS);
+ return 0;
+ }
+
+ /* disable all windows */
+ for (win_id = 0; win_id < MVEBU_GWIN_MAX_WINS; win_id++)
+ gwin_disable_window(ap_index, win_id);
+
+ /* enable relevant windows */
+ for (win_id = 0; win_id < win_count; win_id++, win++) {
+ gwin_check(win);
+ gwin_enable_window(ap_index, win, win_id);
+ }
+
+ /* GWIN Miss feature has not verified, therefore any access towards
+ * remote AP should be accompanied with proper configuration to
+ * GWIN registers group and therefore the GWIN Miss feature
+ * should be set into Bypass mode, need to make sure all GWIN regions
+ * are defined correctly that will assure no GWIN miss occurrance
+ * JIRA-AURORA2-1630
+ */
+ INFO("Update GWIN miss bypass\n");
+ win_reg = mmio_read_32(CCU_GRU_CR_OFFSET(ap_index));
+ win_reg |= CCR_GRU_CR_GWIN_MBYPASS;
+ mmio_write_32(CCU_GRU_CR_OFFSET(ap_index), win_reg);
+
+#ifdef DEBUG_ADDR_MAP
+ dump_gwin(ap_index);
+#endif
+
+ INFO("Done GWIN Address decoding Initializing\n");
+
+ return 0;
+}
diff --git a/drivers/marvell/i2c/a8k_i2c.c b/drivers/marvell/i2c/a8k_i2c.c
new file mode 100644
index 000000000..737dd0a72
--- /dev/null
+++ b/drivers/marvell/i2c/a8k_i2c.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* This driver provides I2C support for Marvell A8K and compatible SoCs */
+
+#include <a8k_i2c.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+#define DEBUG_I2C
+#endif
+
+#define CONFIG_SYS_TCLK 250000000
+#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_SYS_I2C_SLAVE 0x0
+#define I2C_TIMEOUT_VALUE 0x500
+#define I2C_MAX_RETRY_CNT 1000
+#define I2C_CMD_WRITE 0x0
+#define I2C_CMD_READ 0x1
+
+#define I2C_DATA_ADDR_7BIT_OFFS 0x1
+#define I2C_DATA_ADDR_7BIT_MASK (0xFF << I2C_DATA_ADDR_7BIT_OFFS)
+
+#define I2C_CONTROL_ACK 0x00000004
+#define I2C_CONTROL_IFLG 0x00000008
+#define I2C_CONTROL_STOP 0x00000010
+#define I2C_CONTROL_START 0x00000020
+#define I2C_CONTROL_TWSIEN 0x00000040
+#define I2C_CONTROL_INTEN 0x00000080
+
+#define I2C_STATUS_START 0x08
+#define I2C_STATUS_REPEATED_START 0x10
+#define I2C_STATUS_ADDR_W_ACK 0x18
+#define I2C_STATUS_DATA_W_ACK 0x28
+#define I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER 0x38
+#define I2C_STATUS_ADDR_R_ACK 0x40
+#define I2C_STATUS_DATA_R_ACK 0x50
+#define I2C_STATUS_DATA_R_NAK 0x58
+#define I2C_STATUS_LOST_ARB_GENERAL_CALL 0x78
+#define I2C_STATUS_IDLE 0xF8
+
+#define I2C_UNSTUCK_TRIGGER 0x1
+#define I2C_UNSTUCK_ONGOING 0x2
+#define I2C_UNSTUCK_ERROR 0x4
+struct marvell_i2c_regs {
+ uint32_t slave_address;
+ uint32_t data;
+ uint32_t control;
+ union {
+ uint32_t status; /* when reading */
+ uint32_t baudrate; /* when writing */
+ } u;
+ uint32_t xtnd_slave_addr;
+ uint32_t reserved[2];
+ uint32_t soft_reset;
+ uint8_t reserved2[0xa0 - 0x20];
+ uint32_t unstuck;
+};
+
+static struct marvell_i2c_regs *base;
+
+static int marvell_i2c_lost_arbitration(uint32_t *status)
+{
+ *status = mmio_read_32((uintptr_t)&base->u.status);
+ if ((*status == I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER) ||
+ (*status == I2C_STATUS_LOST_ARB_GENERAL_CALL))
+ return -EAGAIN;
+
+ return 0;
+}
+
+static void marvell_i2c_interrupt_clear(void)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32((uintptr_t)&base->control);
+ reg &= ~(I2C_CONTROL_IFLG);
+ mmio_write_32((uintptr_t)&base->control, reg);
+ /* Wait for 1 us for the clear to take effect */
+ udelay(1);
+}
+
+static int marvell_i2c_interrupt_get(void)
+{
+ uint32_t reg;
+
+ /* get the interrupt flag bit */
+ reg = mmio_read_32((uintptr_t)&base->control);
+ reg &= I2C_CONTROL_IFLG;
+ return reg && I2C_CONTROL_IFLG;
+}
+
+static int marvell_i2c_wait_interrupt(void)
+{
+ uint32_t timeout = 0;
+
+ while (!marvell_i2c_interrupt_get() && (timeout++ < I2C_TIMEOUT_VALUE))
+ ;
+ if (timeout >= I2C_TIMEOUT_VALUE)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int marvell_i2c_start_bit_set(void)
+{
+ int is_int_flag = 0;
+ uint32_t status;
+
+ if (marvell_i2c_interrupt_get())
+ is_int_flag = 1;
+
+ /* set start bit */
+ mmio_write_32((uintptr_t)&base->control,
+ mmio_read_32((uintptr_t)&base->control) |
+ I2C_CONTROL_START);
+
+ /* in case that the int flag was set before i.e. repeated start bit */
+ if (is_int_flag) {
+ VERBOSE("%s: repeated start Bit\n", __func__);
+ marvell_i2c_interrupt_clear();
+ }
+
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* check that start bit went down */
+ if ((mmio_read_32((uintptr_t)&base->control) &
+ I2C_CONTROL_START) != 0) {
+ ERROR("Start bit didn't went down\n");
+ return -EPERM;
+ }
+
+ /* check the status */
+ if (marvell_i2c_lost_arbitration(&status)) {
+ ERROR("%s - %d: Lost arbitration, got status %x\n",
+ __func__, __LINE__, status);
+ return -EAGAIN;
+ }
+ if ((status != I2C_STATUS_START) &&
+ (status != I2C_STATUS_REPEATED_START)) {
+ ERROR("Got status %x after enable start bit.\n", status);
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+static int marvell_i2c_stop_bit_set(void)
+{
+ int timeout;
+ uint32_t status;
+
+ /* Generate stop bit */
+ mmio_write_32((uintptr_t)&base->control,
+ mmio_read_32((uintptr_t)&base->control) |
+ I2C_CONTROL_STOP);
+ marvell_i2c_interrupt_clear();
+
+ timeout = 0;
+ /* Read control register, check the control stop bit */
+ while ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) &&
+ (timeout++ < I2C_TIMEOUT_VALUE))
+ ;
+ if (timeout >= I2C_TIMEOUT_VALUE) {
+ ERROR("Stop bit didn't went down\n");
+ return -ETIMEDOUT;
+ }
+
+ /* check that stop bit went down */
+ if ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) != 0) {
+ ERROR("Stop bit didn't went down\n");
+ return -EPERM;
+ }
+
+ /* check the status */
+ if (marvell_i2c_lost_arbitration(&status)) {
+ ERROR("%s - %d: Lost arbitration, got status %x\n",
+ __func__, __LINE__, status);
+ return -EAGAIN;
+ }
+ if (status != I2C_STATUS_IDLE) {
+ ERROR("Got status %x after enable stop bit.\n", status);
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+static int marvell_i2c_address_set(uint8_t chain, int command)
+{
+ uint32_t reg, status;
+
+ reg = (chain << I2C_DATA_ADDR_7BIT_OFFS) & I2C_DATA_ADDR_7BIT_MASK;
+ reg |= command;
+ mmio_write_32((uintptr_t)&base->data, reg);
+ udelay(1);
+
+ marvell_i2c_interrupt_clear();
+
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* check the status */
+ if (marvell_i2c_lost_arbitration(&status)) {
+ ERROR("%s - %d: Lost arbitration, got status %x\n",
+ __func__, __LINE__, status);
+ return -EAGAIN;
+ }
+ if (((status != I2C_STATUS_ADDR_R_ACK) && (command == I2C_CMD_READ)) ||
+ ((status != I2C_STATUS_ADDR_W_ACK) && (command == I2C_CMD_WRITE))) {
+ /* only in debug, since in boot we try to read the SPD
+ * of both DRAM, and we don't want error messages in cas
+ * DIMM doesn't exist.
+ */
+ INFO("%s: ERROR - status %x addr in %s mode.\n", __func__,
+ status, (command == I2C_CMD_WRITE) ? "Write" : "Read");
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+/*
+ * The I2C module contains a clock divider to generate the SCL clock.
+ * This function calculates and sets the <N> and <M> fields in the I2C Baud
+ * Rate Register (t=01) to obtain given 'requested_speed'.
+ * The requested_speed will be equal to:
+ * CONFIG_SYS_TCLK / (10 * (M + 1) * (2 << N))
+ * Where M is the value represented by bits[6:3] and N is the value represented
+ * by bits[2:0] of "I2C Baud Rate Register".
+ * Therefore max M which can be set is 16 (2^4) and max N is 8 (2^3). So the
+ * lowest possible baudrate is:
+ * CONFIG_SYS_TCLK/(10 * (16 +1) * (2 << 8), which equals to:
+ * CONFIG_SYS_TCLK/87040. Assuming that CONFIG_SYS_TCLK=250MHz, the lowest
+ * possible frequency is ~2,872KHz.
+ */
+static unsigned int marvell_i2c_bus_speed_set(unsigned int requested_speed)
+{
+ unsigned int n, m, freq, margin, min_margin = 0xffffffff;
+ unsigned int actual_n = 0, actual_m = 0;
+ int val;
+
+ /* Calculate N and M for the TWSI clock baud rate */
+ for (n = 0; n < 8; n++) {
+ for (m = 0; m < 16; m++) {
+ freq = CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
+ val = requested_speed - freq;
+ margin = (val > 0) ? val : -val;
+
+ if ((freq <= requested_speed) &&
+ (margin < min_margin)) {
+ min_margin = margin;
+ actual_n = n;
+ actual_m = m;
+ }
+ }
+ }
+ VERBOSE("%s: actual_n = %u, actual_m = %u\n",
+ __func__, actual_n, actual_m);
+ /* Set the baud rate */
+ mmio_write_32((uintptr_t)&base->u.baudrate, (actual_m << 3) | actual_n);
+
+ return 0;
+}
+
+#ifdef DEBUG_I2C
+static int marvell_i2c_probe(uint8_t chip)
+{
+ int ret = 0;
+
+ ret = marvell_i2c_start_bit_set();
+ if (ret != 0) {
+ marvell_i2c_stop_bit_set();
+ ERROR("%s - %d: %s", __func__, __LINE__,
+ "marvell_i2c_start_bit_set failed\n");
+ return -EPERM;
+ }
+
+ ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
+ if (ret != 0) {
+ marvell_i2c_stop_bit_set();
+ ERROR("%s - %d: %s", __func__, __LINE__,
+ "marvell_i2c_address_set failed\n");
+ return -EPERM;
+ }
+
+ marvell_i2c_stop_bit_set();
+
+ VERBOSE("%s: successful I2C probe\n", __func__);
+
+ return ret;
+}
+#endif
+
+/* regular i2c transaction */
+static int marvell_i2c_data_receive(uint8_t *p_block, uint32_t block_size)
+{
+ uint32_t reg, status, block_size_read = block_size;
+
+ /* Wait for cause interrupt */
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+ while (block_size_read) {
+ if (block_size_read == 1) {
+ reg = mmio_read_32((uintptr_t)&base->control);
+ reg &= ~(I2C_CONTROL_ACK);
+ mmio_write_32((uintptr_t)&base->control, reg);
+ }
+ marvell_i2c_interrupt_clear();
+
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+ /* check the status */
+ if (marvell_i2c_lost_arbitration(&status)) {
+ ERROR("%s - %d: Lost arbitration, got status %x\n",
+ __func__, __LINE__, status);
+ return -EAGAIN;
+ }
+ if ((status != I2C_STATUS_DATA_R_ACK) &&
+ (block_size_read != 1)) {
+ ERROR("Status %x in read transaction\n", status);
+ return -EPERM;
+ }
+ if ((status != I2C_STATUS_DATA_R_NAK) &&
+ (block_size_read == 1)) {
+ ERROR("Status %x in Rd Terminate\n", status);
+ return -EPERM;
+ }
+
+ /* read the data */
+ *p_block = (uint8_t) mmio_read_32((uintptr_t)&base->data);
+ VERBOSE("%s: place %d read %x\n", __func__,
+ block_size - block_size_read, *p_block);
+ p_block++;
+ block_size_read--;
+ }
+
+ return 0;
+}
+
+static int marvell_i2c_data_transmit(uint8_t *p_block, uint32_t block_size)
+{
+ uint32_t status, block_size_write = block_size;
+
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ while (block_size_write) {
+ /* write the data */
+ mmio_write_32((uintptr_t)&base->data, (uint32_t) *p_block);
+ VERBOSE("%s: index = %d, data = %x\n", __func__,
+ block_size - block_size_write, *p_block);
+ p_block++;
+ block_size_write--;
+
+ marvell_i2c_interrupt_clear();
+
+ if (marvell_i2c_wait_interrupt()) {
+ ERROR("Start clear bit timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* check the status */
+ if (marvell_i2c_lost_arbitration(&status)) {
+ ERROR("%s - %d: Lost arbitration, got status %x\n",
+ __func__, __LINE__, status);
+ return -EAGAIN;
+ }
+ if (status != I2C_STATUS_DATA_W_ACK) {
+ ERROR("Status %x in write transaction\n", status);
+ return -EPERM;
+ }
+ }
+
+ return 0;
+}
+
+static int marvell_i2c_target_offset_set(uint8_t chip, uint32_t addr, int alen)
+{
+ uint8_t off_block[2];
+ uint32_t off_size;
+
+ if (alen == 2) { /* 2-byte addresses support */
+ off_block[0] = (addr >> 8) & 0xff;
+ off_block[1] = addr & 0xff;
+ off_size = 2;
+ } else { /* 1-byte addresses support */
+ off_block[0] = addr & 0xff;
+ off_size = 1;
+ }
+ VERBOSE("%s: off_size = %x addr1 = %x addr2 = %x\n", __func__,
+ off_size, off_block[0], off_block[1]);
+ return marvell_i2c_data_transmit(off_block, off_size);
+}
+
+static int marvell_i2c_unstuck(int ret)
+{
+ uint32_t v;
+
+ if (ret != -ETIMEDOUT)
+ return ret;
+ VERBOSE("Trying to \"unstuck i2c\"... ");
+ i2c_init(base);
+ mmio_write_32((uintptr_t)&base->unstuck, I2C_UNSTUCK_TRIGGER);
+ do {
+ v = mmio_read_32((uintptr_t)&base->unstuck);
+ } while (v & I2C_UNSTUCK_ONGOING);
+
+ if (v & I2C_UNSTUCK_ERROR) {
+ VERBOSE("failed - soft reset i2c\n");
+ ret = -EPERM;
+ } else {
+ VERBOSE("ok\n");
+ i2c_init(base);
+ ret = -EAGAIN;
+ }
+ return ret;
+}
+
+/*
+ * API Functions
+ */
+void i2c_init(void *i2c_base)
+{
+ /* For I2C speed and slave address, now we do not set them since
+ * we just provide the working speed and slave address in plat_def.h
+ * for i2c_init
+ */
+ base = (struct marvell_i2c_regs *)i2c_base;
+
+ /* Reset the I2C logic */
+ mmio_write_32((uintptr_t)&base->soft_reset, 0);
+
+ udelay(200);
+
+ marvell_i2c_bus_speed_set(CONFIG_SYS_I2C_SPEED);
+
+ /* Enable the I2C and slave */
+ mmio_write_32((uintptr_t)&base->control,
+ I2C_CONTROL_TWSIEN | I2C_CONTROL_ACK);
+
+ /* set the I2C slave address */
+ mmio_write_32((uintptr_t)&base->xtnd_slave_addr, 0);
+ mmio_write_32((uintptr_t)&base->slave_address, CONFIG_SYS_I2C_SLAVE);
+
+ /* unmask I2C interrupt */
+ mmio_write_32((uintptr_t)&base->control,
+ mmio_read_32((uintptr_t)&base->control) |
+ I2C_CONTROL_INTEN);
+
+ udelay(10);
+}
+
+/*
+ * i2c_read: - Read multiple bytes from an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip: address of the chip which is to be read
+ * @addr: i2c data address within the chip
+ * @alen: length of the i2c data address (1..2 bytes)
+ * @buffer: where to write the data
+ * @len: how much byte do we want to read
+ * @return: 0 in case of success
+ */
+int i2c_read(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
+{
+ int ret = 0;
+ uint32_t counter = 0;
+
+#ifdef DEBUG_I2C
+ marvell_i2c_probe(chip);
+#endif
+
+ do {
+ if (ret != -EAGAIN && ret) {
+ ERROR("i2c transaction failed, after %d retries\n",
+ counter);
+ marvell_i2c_stop_bit_set();
+ return ret;
+ }
+
+ /* wait for 1 us for the interrupt clear to take effect */
+ if (counter > 0)
+ udelay(1);
+ counter++;
+
+ ret = marvell_i2c_start_bit_set();
+ if (ret) {
+ ret = marvell_i2c_unstuck(ret);
+ continue;
+ }
+
+ /* if EEPROM device */
+ if (alen != 0) {
+ ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
+ if (ret)
+ continue;
+
+ ret = marvell_i2c_target_offset_set(chip, addr, alen);
+ if (ret)
+ continue;
+ ret = marvell_i2c_start_bit_set();
+ if (ret)
+ continue;
+ }
+
+ ret = marvell_i2c_address_set(chip, I2C_CMD_READ);
+ if (ret)
+ continue;
+
+ ret = marvell_i2c_data_receive(buffer, len);
+ if (ret)
+ continue;
+
+ ret = marvell_i2c_stop_bit_set();
+ } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));
+
+ if (counter == I2C_MAX_RETRY_CNT) {
+ ERROR("I2C transactions failed, got EAGAIN %d times\n",
+ I2C_MAX_RETRY_CNT);
+ ret = -EPERM;
+ }
+ mmio_write_32((uintptr_t)&base->control,
+ mmio_read_32((uintptr_t)&base->control) |
+ I2C_CONTROL_ACK);
+
+ udelay(1);
+ return ret;
+}
+
+/*
+ * i2c_write: - Write multiple bytes to an i2c device
+ *
+ * The higher level routines take into account that this function is only
+ * called with len < page length of the device (see configuration file)
+ *
+ * @chip: address of the chip which is to be written
+ * @addr: i2c data address within the chip
+ * @alen: length of the i2c data address (1..2 bytes)
+ * @buffer: where to find the data to be written
+ * @len: how much byte do we want to read
+ * @return: 0 in case of success
+ */
+int i2c_write(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
+{
+ int ret = 0;
+ uint32_t counter = 0;
+
+ do {
+ if (ret != -EAGAIN && ret) {
+ ERROR("i2c transaction failed\n");
+ marvell_i2c_stop_bit_set();
+ return ret;
+ }
+ /* wait for 1 us for the interrupt clear to take effect */
+ if (counter > 0)
+ udelay(1);
+ counter++;
+
+ ret = marvell_i2c_start_bit_set();
+ if (ret) {
+ ret = marvell_i2c_unstuck(ret);
+ continue;
+ }
+
+ ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
+ if (ret)
+ continue;
+
+ /* if EEPROM device */
+ if (alen != 0) {
+ ret = marvell_i2c_target_offset_set(chip, addr, alen);
+ if (ret)
+ continue;
+ }
+
+ ret = marvell_i2c_data_transmit(buffer, len);
+ if (ret)
+ continue;
+
+ ret = marvell_i2c_stop_bit_set();
+ } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));
+
+ if (counter == I2C_MAX_RETRY_CNT) {
+ ERROR("I2C transactions failed, got EAGAIN %d times\n",
+ I2C_MAX_RETRY_CNT);
+ ret = -EPERM;
+ }
+
+ udelay(1);
+ return ret;
+}
diff --git a/drivers/marvell/io_win.c b/drivers/marvell/io_win.c
new file mode 100644
index 000000000..40b198212
--- /dev/null
+++ b/drivers/marvell/io_win.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* IO Window unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+
+#include <a8k_common.h>
+#include <debug.h>
+#include <io_win.h>
+#include <mmio.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+#define DEBUG_ADDR_MAP
+#endif
+
+/* common defines */
+#define WIN_ENABLE_BIT (0x1)
+/* Physical address of the base of the window = {Addr[19:0],20`h0} */
+#define ADDRESS_SHIFT (20 - 4)
+#define ADDRESS_MASK (0xFFFFFFF0)
+#define IO_WIN_ALIGNMENT_1M (0x100000)
+#define IO_WIN_ALIGNMENT_64K (0x10000)
+
+/* AP registers */
+#define IO_WIN_ALR_OFFSET(ap, win) (MVEBU_IO_WIN_BASE(ap) + 0x0 + \
+ (0x10 * win))
+#define IO_WIN_AHR_OFFSET(ap, win) (MVEBU_IO_WIN_BASE(ap) + 0x8 + \
+ (0x10 * win))
+#define IO_WIN_CR_OFFSET(ap, win) (MVEBU_IO_WIN_BASE(ap) + 0xC + \
+ (0x10 * win))
+
+/* For storage of CR, ALR, AHR abd GCR */
+static uint32_t io_win_regs_save[MVEBU_IO_WIN_MAX_WINS * 3 + 1];
+
+static void io_win_check(struct addr_map_win *win)
+{
+ /* for IO The base is always 1M aligned */
+ /* check if address is aligned to 1M */
+ if (IS_NOT_ALIGN(win->base_addr, IO_WIN_ALIGNMENT_1M)) {
+ win->base_addr = ALIGN_UP(win->base_addr, IO_WIN_ALIGNMENT_1M);
+ NOTICE("%s: Align up the base address to 0x%llx\n",
+ __func__, win->base_addr);
+ }
+
+ /* size parameter validity check */
+ if (IS_NOT_ALIGN(win->win_size, IO_WIN_ALIGNMENT_1M)) {
+ win->win_size = ALIGN_UP(win->win_size, IO_WIN_ALIGNMENT_1M);
+ NOTICE("%s: Aligning size to 0x%llx\n",
+ __func__, win->win_size);
+ }
+}
+
+static void io_win_enable_window(int ap_index, struct addr_map_win *win,
+ uint32_t win_num)
+{
+ uint32_t alr, ahr;
+ uint64_t end_addr;
+
+ if (win->target_id < 0 || win->target_id >= MVEBU_IO_WIN_MAX_WINS) {
+ ERROR("target ID = %d, is invalid\n", win->target_id);
+ return;
+ }
+
+ if ((win_num == 0) || (win_num > MVEBU_IO_WIN_MAX_WINS)) {
+ ERROR("Enabling wrong IOW window %d!\n", win_num);
+ return;
+ }
+
+ /* calculate the end-address */
+ end_addr = (win->base_addr + win->win_size - 1);
+
+ alr = (uint32_t)((win->base_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+ alr |= WIN_ENABLE_BIT;
+ ahr = (uint32_t)((end_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+
+ /* write start address and end address for IO window */
+ mmio_write_32(IO_WIN_ALR_OFFSET(ap_index, win_num), alr);
+ mmio_write_32(IO_WIN_AHR_OFFSET(ap_index, win_num), ahr);
+
+ /* write window target */
+ mmio_write_32(IO_WIN_CR_OFFSET(ap_index, win_num), win->target_id);
+}
+
+static void io_win_disable_window(int ap_index, uint32_t win_num)
+{
+ uint32_t win_reg;
+
+ if ((win_num == 0) || (win_num > MVEBU_IO_WIN_MAX_WINS)) {
+ ERROR("Disabling wrong IOW window %d!\n", win_num);
+ return;
+ }
+
+ win_reg = mmio_read_32(IO_WIN_ALR_OFFSET(ap_index, win_num));
+ win_reg &= ~WIN_ENABLE_BIT;
+ mmio_write_32(IO_WIN_ALR_OFFSET(ap_index, win_num), win_reg);
+}
+
+/* Insert/Remove temporary window for using the out-of reset default
+ * CPx base address to access the CP configuration space prior to
+ * the further base address update in accordance with address mapping
+ * design.
+ *
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void iow_temp_win_insert(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ for (int i = 0; i < size; i++) {
+ win_id = MVEBU_IO_WIN_MAX_WINS - i - 1;
+ io_win_check(win);
+ io_win_enable_window(ap_index, win, win_id);
+ win++;
+ }
+}
+
+/*
+ * NOTE: Use the same window array for insertion and removal of
+ * temporary windows.
+ */
+void iow_temp_win_remove(int ap_index, struct addr_map_win *win, int size)
+{
+ uint32_t win_id;
+
+ /* Start from the last window and do not touch Win0 */
+ for (int i = 0; i < size; i++) {
+ uint64_t base;
+ uint32_t target;
+
+ win_id = MVEBU_IO_WIN_MAX_WINS - i - 1;
+
+ target = mmio_read_32(IO_WIN_CR_OFFSET(ap_index, win_id));
+ base = mmio_read_32(IO_WIN_ALR_OFFSET(ap_index, win_id));
+ base &= ~WIN_ENABLE_BIT;
+ base <<= ADDRESS_SHIFT;
+
+ if ((win->target_id != target) || (win->base_addr != base)) {
+ ERROR("%s: Trying to remove bad window-%d!\n",
+ __func__, win_id);
+ continue;
+ }
+ io_win_disable_window(ap_index, win_id);
+ win++;
+ }
+}
+
+#ifdef DEBUG_ADDR_MAP
+static void dump_io_win(int ap_index)
+{
+ uint32_t trgt_id, win_id;
+ uint32_t alr, ahr;
+ uint64_t start, end;
+
+ /* Dump all IO windows */
+ printf("\tbank target start end\n");
+ printf("\t----------------------------------------------------\n");
+ for (win_id = 0; win_id < MVEBU_IO_WIN_MAX_WINS; win_id++) {
+ alr = mmio_read_32(IO_WIN_ALR_OFFSET(ap_index, win_id));
+ if (alr & WIN_ENABLE_BIT) {
+ alr &= ~WIN_ENABLE_BIT;
+ ahr = mmio_read_32(IO_WIN_AHR_OFFSET(ap_index, win_id));
+ trgt_id = mmio_read_32(IO_WIN_CR_OFFSET(ap_index,
+ win_id));
+ start = ((uint64_t)alr << ADDRESS_SHIFT);
+ end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
+ printf("\tio-win %d 0x%016llx 0x%016llx\n",
+ trgt_id, start, end);
+ }
+ }
+ printf("\tio-win gcr is %x\n",
+ mmio_read_32(MVEBU_IO_WIN_BASE(ap_index) +
+ MVEBU_IO_WIN_GCR_OFFSET));
+}
+#endif
+
+static void iow_save_win_range(int ap_id, int win_first, int win_last,
+ uint32_t *buffer)
+{
+ int win_id, idx;
+
+ /* Save IOW */
+ for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
+ buffer[idx++] = mmio_read_32(IO_WIN_CR_OFFSET(ap_id, win_id));
+ buffer[idx++] = mmio_read_32(IO_WIN_ALR_OFFSET(ap_id, win_id));
+ buffer[idx++] = mmio_read_32(IO_WIN_AHR_OFFSET(ap_id, win_id));
+ }
+ buffer[idx] = mmio_read_32(MVEBU_IO_WIN_BASE(ap_id) +
+ MVEBU_IO_WIN_GCR_OFFSET);
+}
+
+static void iow_restore_win_range(int ap_id, int win_first, int win_last,
+ uint32_t *buffer)
+{
+ int win_id, idx;
+
+ /* Restore IOW */
+ for (idx = 0, win_id = win_first; win_id <= win_last; win_id++) {
+ mmio_write_32(IO_WIN_CR_OFFSET(ap_id, win_id), buffer[idx++]);
+ mmio_write_32(IO_WIN_ALR_OFFSET(ap_id, win_id), buffer[idx++]);
+ mmio_write_32(IO_WIN_AHR_OFFSET(ap_id, win_id), buffer[idx++]);
+ }
+ mmio_write_32(MVEBU_IO_WIN_BASE(ap_id) + MVEBU_IO_WIN_GCR_OFFSET,
+ buffer[idx++]);
+}
+
+void iow_save_win_all(int ap_id)
+{
+ iow_save_win_range(ap_id, 0, MVEBU_IO_WIN_MAX_WINS - 1,
+ io_win_regs_save);
+}
+
+void iow_restore_win_all(int ap_id)
+{
+ iow_restore_win_range(ap_id, 0, MVEBU_IO_WIN_MAX_WINS - 1,
+ io_win_regs_save);
+}
+
+int init_io_win(int ap_index)
+{
+ struct addr_map_win *win;
+ uint32_t win_id, win_reg;
+ uint32_t win_count;
+
+ INFO("Initializing IO WIN Address decoding\n");
+
+ /* Get the array of the windows and its size */
+ marvell_get_io_win_memory_map(ap_index, &win, &win_count);
+ if (win_count <= 0)
+ INFO("no windows configurations found\n");
+
+ if (win_count > MVEBU_IO_WIN_MAX_WINS) {
+ INFO("number of windows is bigger than %d\n",
+ MVEBU_IO_WIN_MAX_WINS);
+ return 0;
+ }
+
+ /* Get the default target id to set the GCR */
+ win_reg = marvell_get_io_win_gcr_target(ap_index);
+ mmio_write_32(MVEBU_IO_WIN_BASE(ap_index) + MVEBU_IO_WIN_GCR_OFFSET,
+ win_reg);
+
+ /* disable all IO windows */
+ for (win_id = 1; win_id < MVEBU_IO_WIN_MAX_WINS; win_id++)
+ io_win_disable_window(ap_index, win_id);
+
+ /* enable relevant windows, starting from win_id = 1 because
+ * index 0 dedicated for BootROM
+ */
+ for (win_id = 1; win_id <= win_count; win_id++, win++) {
+ io_win_check(win);
+ io_win_enable_window(ap_index, win, win_id);
+ }
+
+#ifdef DEBUG_ADDR_MAP
+ dump_io_win(ap_index);
+#endif
+
+ INFO("Done IO WIN Address decoding Initializing\n");
+
+ return 0;
+}
diff --git a/drivers/marvell/iob.c b/drivers/marvell/iob.c
new file mode 100644
index 000000000..acc4941f5
--- /dev/null
+++ b/drivers/marvell/iob.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2016 - 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* IOW unit device driver for Marvell CP110 and CP115 SoCs */
+
+#include <a8k_common.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <iob.h>
+#include <mmio.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+#define DEBUG_ADDR_MAP
+#endif
+
+#define MVEBU_IOB_OFFSET (0x190000)
+#define MVEBU_IOB_MAX_WINS 16
+
+/* common defines */
+#define WIN_ENABLE_BIT (0x1)
+/* Physical address of the base of the window = {AddrLow[19:0],20`h0} */
+#define ADDRESS_SHIFT (20 - 4)
+#define ADDRESS_MASK (0xFFFFFFF0)
+#define IOB_WIN_ALIGNMENT (0x100000)
+
+/* IOB registers */
+#define IOB_WIN_CR_OFFSET(win) (iob_base + 0x0 + (0x20 * win))
+#define IOB_TARGET_ID_OFFSET (8)
+#define IOB_TARGET_ID_MASK (0xF)
+
+#define IOB_WIN_SCR_OFFSET(win) (iob_base + 0x4 + (0x20 * win))
+#define IOB_WIN_ENA_CTRL_WRITE_SECURE (0x1)
+#define IOB_WIN_ENA_CTRL_READ_SECURE (0x2)
+#define IOB_WIN_ENA_WRITE_SECURE (0x4)
+#define IOB_WIN_ENA_READ_SECURE (0x8)
+
+#define IOB_WIN_ALR_OFFSET(win) (iob_base + 0x8 + (0x20 * win))
+#define IOB_WIN_AHR_OFFSET(win) (iob_base + 0xC + (0x20 * win))
+
+uintptr_t iob_base;
+
+static void iob_win_check(struct addr_map_win *win, uint32_t win_num)
+{
+ /* check if address is aligned to the size */
+ if (IS_NOT_ALIGN(win->base_addr, IOB_WIN_ALIGNMENT)) {
+ win->base_addr = ALIGN_UP(win->base_addr, IOB_WIN_ALIGNMENT);
+ ERROR("Window %d: base address unaligned to 0x%x\n",
+ win_num, IOB_WIN_ALIGNMENT);
+ printf("Align up the base address to 0x%llx\n",
+ win->base_addr);
+ }
+
+ /* size parameter validity check */
+ if (IS_NOT_ALIGN(win->win_size, IOB_WIN_ALIGNMENT)) {
+ win->win_size = ALIGN_UP(win->win_size, IOB_WIN_ALIGNMENT);
+ ERROR("Window %d: window size unaligned to 0x%x\n", win_num,
+ IOB_WIN_ALIGNMENT);
+ printf("Aligning size to 0x%llx\n", win->win_size);
+ }
+}
+
+static void iob_enable_win(struct addr_map_win *win, uint32_t win_id)
+{
+ uint32_t iob_win_reg;
+ uint32_t alr, ahr;
+ uint64_t end_addr;
+
+ end_addr = (win->base_addr + win->win_size - 1);
+ alr = (uint32_t)((win->base_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+ ahr = (uint32_t)((end_addr >> ADDRESS_SHIFT) & ADDRESS_MASK);
+
+ mmio_write_32(IOB_WIN_ALR_OFFSET(win_id), alr);
+ mmio_write_32(IOB_WIN_AHR_OFFSET(win_id), ahr);
+
+ iob_win_reg = WIN_ENABLE_BIT;
+ iob_win_reg |= (win->target_id & IOB_TARGET_ID_MASK)
+ << IOB_TARGET_ID_OFFSET;
+ mmio_write_32(IOB_WIN_CR_OFFSET(win_id), iob_win_reg);
+
+}
+
+#ifdef DEBUG_ADDR_MAP
+static void dump_iob(void)
+{
+ uint32_t win_id, win_cr, alr, ahr;
+ uint8_t target_id;
+ uint64_t start, end;
+ char *iob_target_name[IOB_MAX_TID] = {
+ "CFG ", "MCI0 ", "PEX1 ", "PEX2 ",
+ "PEX0 ", "NAND ", "RUNIT", "MCI1 " };
+
+ /* Dump all IOB windows */
+ printf("bank id target start end\n");
+ printf("----------------------------------------------------\n");
+ for (win_id = 0; win_id < MVEBU_IOB_MAX_WINS; win_id++) {
+ win_cr = mmio_read_32(IOB_WIN_CR_OFFSET(win_id));
+ if (win_cr & WIN_ENABLE_BIT) {
+ target_id = (win_cr >> IOB_TARGET_ID_OFFSET) &
+ IOB_TARGET_ID_MASK;
+ alr = mmio_read_32(IOB_WIN_ALR_OFFSET(win_id));
+ start = ((uint64_t)alr << ADDRESS_SHIFT);
+ if (win_id != 0) {
+ ahr = mmio_read_32(IOB_WIN_AHR_OFFSET(win_id));
+ end = (((uint64_t)ahr + 0x10) << ADDRESS_SHIFT);
+ } else {
+ /* Window #0 size is hardcoded to 16MB, as it's
+ * reserved for CP configuration space.
+ */
+ end = start + (16 << 20);
+ }
+ printf("iob %02d %s 0x%016llx 0x%016llx\n",
+ win_id, iob_target_name[target_id],
+ start, end);
+ }
+ }
+}
+#endif
+
+void iob_cfg_space_update(int ap_idx, int cp_idx, uintptr_t base,
+ uintptr_t new_base)
+{
+ debug_enter();
+
+ iob_base = base + MVEBU_IOB_OFFSET;
+
+ NOTICE("Change the base address of AP%d-CP%d to %lx\n",
+ ap_idx, cp_idx, new_base);
+ mmio_write_32(IOB_WIN_ALR_OFFSET(0), new_base >> ADDRESS_SHIFT);
+
+ iob_base = new_base + MVEBU_IOB_OFFSET;
+
+ /* Make sure the address was configured by the CPU before
+ * any possible access to the CP.
+ */
+ dsb();
+
+ debug_exit();
+}
+
+int init_iob(uintptr_t base)
+{
+ struct addr_map_win *win;
+ uint32_t win_id, win_reg;
+ uint32_t win_count;
+
+ INFO("Initializing IOB Address decoding\n");
+
+ /* Get the base address of the address decoding MBUS */
+ iob_base = base + MVEBU_IOB_OFFSET;
+
+ /* Get the array of the windows and fill the map data */
+ marvell_get_iob_memory_map(&win, &win_count, base);
+ if (win_count <= 0) {
+ INFO("no windows configurations found\n");
+ return 0;
+ } else if (win_count > (MVEBU_IOB_MAX_WINS - 1)) {
+ ERROR("IOB mem map array > than max available windows (%d)\n",
+ MVEBU_IOB_MAX_WINS);
+ win_count = MVEBU_IOB_MAX_WINS;
+ }
+
+ /* disable all IOB windows, start from win_id = 1
+ * because can't disable internal register window
+ */
+ for (win_id = 1; win_id < MVEBU_IOB_MAX_WINS; win_id++) {
+ win_reg = mmio_read_32(IOB_WIN_CR_OFFSET(win_id));
+ win_reg &= ~WIN_ENABLE_BIT;
+ mmio_write_32(IOB_WIN_CR_OFFSET(win_id), win_reg);
+
+ win_reg = ~IOB_WIN_ENA_CTRL_WRITE_SECURE;
+ win_reg &= ~IOB_WIN_ENA_CTRL_READ_SECURE;
+ win_reg &= ~IOB_WIN_ENA_WRITE_SECURE;
+ win_reg &= ~IOB_WIN_ENA_READ_SECURE;
+ mmio_write_32(IOB_WIN_SCR_OFFSET(win_id), win_reg);
+ }
+
+ for (win_id = 1; win_id < win_count + 1; win_id++, win++) {
+ iob_win_check(win, win_id);
+ iob_enable_win(win, win_id);
+ }
+
+#ifdef DEBUG_ADDR_MAP
+ dump_iob();
+#endif
+
+ INFO("Done IOB Address decoding Initializing\n");
+
+ return 0;
+}
diff --git a/drivers/marvell/mci.c b/drivers/marvell/mci.c
new file mode 100644
index 000000000..721504e03
--- /dev/null
+++ b/drivers/marvell/mci.c
@@ -0,0 +1,832 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* MCI bus driver for Marvell ARMADA 8K and 8K+ SoCs */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <mmio.h>
+#include <mci.h>
+#include <mvebu.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+/* /HB /Units /Direct_regs /Direct regs
+ * /Configuration Register Write/Read Data Register
+ */
+#define MCI_WRITE_READ_DATA_REG(mci_index) \
+ MVEBU_MCI_REG_BASE_REMAP(mci_index)
+/* /HB /Units /Direct_regs /Direct regs
+ * /Configuration Register Access Command Register
+ */
+#define MCI_ACCESS_CMD_REG(mci_index) \
+ (MVEBU_MCI_REG_BASE_REMAP(mci_index) + 0x4)
+
+/* Access Command fields :
+ * bit[3:0] - Sub command: 1 => Peripheral Config Register Read,
+ * 0 => Peripheral Config Register Write,
+ * 2 => Peripheral Assign ID request,
+ * 3 => Circular Config Write
+ * bit[5] - 1 => Local (same chip access) 0 => Remote
+ * bit[15:8] - Destination hop ID. Put Global ID (GID) here (see scheme below).
+ * bit[23:22] - 0x3 IHB PHY REG address space, 0x0 IHB Controller space
+ * bit[21:16] - Low 6 bits of offset. Hight 2 bits are taken from bit[28:27]
+ * of IHB_PHY_CTRL
+ * (must be set before any PHY register access occurs):
+ * /IHB_REG /IHB_REGInterchip Hopping Bus Registers
+ * /IHB Version Control Register
+ *
+ * ixi_ihb_top IHB PHY
+ * AXI ----------------------------- -------------
+ * <--| axi_hb_top | ihb_pipe_top |-->| |
+ * -->| GID=1 | GID=0 |<--| |
+ * ----------------------------- -------------
+ */
+#define MCI_INDIRECT_CTRL_READ_CMD 0x1
+#define MCI_INDIRECT_CTRL_ASSIGN_CMD 0x2
+#define MCI_INDIRECT_CTRL_CIRCULAR_CMD 0x3
+#define MCI_INDIRECT_CTRL_LOCAL_PKT (1 << 5)
+#define MCI_INDIRECT_CTRL_CMD_DONE_OFFSET 6
+#define MCI_INDIRECT_CTRL_CMD_DONE \
+ (1 << MCI_INDIRECT_CTRL_CMD_DONE_OFFSET)
+#define MCI_INDIRECT_CTRL_DATA_READY_OFFSET 7
+#define MCI_INDIRECT_CTRL_DATA_READY \
+ (1 << MCI_INDIRECT_CTRL_DATA_READY_OFFSET)
+#define MCI_INDIRECT_CTRL_HOPID_OFFSET 8
+#define MCI_INDIRECT_CTRL_HOPID(id) \
+ (((id) & 0xFF) << MCI_INDIRECT_CTRL_HOPID_OFFSET)
+#define MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET 16
+#define MCI_INDIRECT_REG_CTRL_ADDR(reg_num) \
+ (reg_num << MCI_INDIRECT_CTRL_REG_CHIPID_OFFSET)
+
+/* Hop ID values */
+#define GID_IHB_PIPE 0
+#define GID_AXI_HB 1
+#define GID_IHB_EXT 2
+
+#define MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG 0x2
+/* Target MCi Local ID (LID, which is = self DID) */
+#define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(val) (((val) & 0xFF) << 16)
+/* Bits [15:8]: Number of MCis on chip of target MCi */
+#define MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(val) (((val) & 0xFF) << 8)
+/* Bits [7:0]: Number of hops on chip of target MCi */
+#define MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(val) (((val) & 0xFF) << 0)
+
+/* IHB_REG domain registers */
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
+ * Rx Memory Configuration Register (RX_MEM_CFG)
+ */
+#define MCI_CTRL_RX_MEM_CFG_REG_NUM 0x0
+#define MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(val) (((val) & 0xFF) << 24)
+#define MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(val) (((val) & 0xFF) << 16)
+#define MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(val) (((val) & 0xFF) << 8)
+#define MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(val) (((val) & 0xF) << 4)
+#define MCI_CTRL_RX_TX_MEM_CFG_RTC(val) (((val) & 0x3) << 2)
+#define MCI_CTRL_RX_TX_MEM_CFG_WTC(val) (((val) & 0x3) << 0)
+#define MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL \
+ (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x07) | \
+ MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x3f) | \
+ MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
+ MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
+ MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
+ MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
+
+#define MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL \
+ (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x3f) | \
+ MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x03) | \
+ MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x3f) | \
+ MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(0xf) | \
+ MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
+ MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
+
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
+ * Tx Memory Configuration Register (TX_MEM_CFG)
+ */
+#define MCI_CTRL_TX_MEM_CFG_REG_NUM 0x1
+/* field mapping for TX mem config register
+ * are the same as for RX register - see register above
+ */
+#define MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL \
+ (MCI_CTRL_RX_TX_MEM_CFG_RQ_THRESH(0x20) | \
+ MCI_CTRL_RX_TX_MEM_CFG_PQ_THRESH(0x20) | \
+ MCI_CTRL_RX_TX_MEM_CFG_NQ_THRESH(0x20) | \
+ MCI_CTRL_RX_TX_MEM_CFG_DELTA_THRESH(2) | \
+ MCI_CTRL_RX_TX_MEM_CFG_RTC(1) | \
+ MCI_CTRL_RX_TX_MEM_CFG_WTC(1))
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
+ * /IHB Link CRC Control
+ */
+/* MCi Link CRC Control Register (MCi_CRC_CTRL) */
+#define MCI_LINK_CRC_CTRL_REG_NUM 0x4
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
+ * /IHB Status Register
+ */
+/* MCi Status Register (MCi_STS) */
+#define MCI_CTRL_STATUS_REG_NUM 0x5
+#define MCI_CTRL_STATUS_REG_PHY_READY (1 << 12)
+#define MCI_CTRL_STATUS_REG_LINK_PRESENT (1 << 15)
+#define MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET 24
+#define MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK \
+ (0xF << MCI_CTRL_STATUS_REG_PHY_CID_VIO_OFFSET)
+/* Expected successful Link result, including reserved bit */
+#define MCI_CTRL_PHY_READY (MCI_CTRL_STATUS_REG_PHY_READY | \
+ MCI_CTRL_STATUS_REG_LINK_PRESENT | \
+ MCI_CTRL_STATUS_REG_PHY_CID_VIO_MASK)
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers/
+ * MCi PHY Speed Settings Register (MCi_PHY_SETTING)
+ */
+#define MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM 0x8
+#define MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(val) (((val) & 0xF) << 28)
+#define MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(val) (((val) & 0xF) << 12)
+#define MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(val) (((val) & 0xF) << 8)
+#define MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(val) (((val) & 0xF) << 4)
+#define MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(val) (((val) & 0x1) << 1)
+#define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL \
+ (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
+ MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
+ MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x2) | \
+ MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
+#define MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 \
+ (MCI_CTRL_MCI_PHY_SET_DLO_FIFO_FULL_TRESH(0x3) | \
+ MCI_CTRL_MCI_PHY_SET_PHY_MAX_SPEED(0x3) | \
+ MCI_CTRL_MCI_PHY_SET_PHYCLK_SEL(0x5) | \
+ MCI_CTRL_MCI_PHY_SET_REFCLK_FREQ_SEL(0x1))
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
+ * /IHB Mode Config
+ */
+#define MCI_CTRL_IHB_MODE_CFG_REG_NUM 0x25
+#define MCI_CTRL_IHB_MODE_HBCLK_DIV(val) ((val) & 0xFF)
+#define MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET 8
+#define MCI_CTRL_IHB_MODE_CHUNK_MOD \
+ (1 << MCI_CTRL_IHB_MODE_CHUNK_MOD_OFFSET)
+#define MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET 9
+#define MCI_CTRL_IHB_MODE_FWD_MOD \
+ (1 << MCI_CTRL_IHB_MODE_FWD_MOD_OFFSET)
+#define MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(val) (((val) & 0xF) << 12)
+#define MCI_CTRL_IHB_MODE_RX_COMB_THRESH(val) (((val) & 0xFF) << 16)
+#define MCI_CTRL_IHB_MODE_TX_COMB_THRESH(val) (((val) & 0xFF) << 24)
+
+#define MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL \
+ (MCI_CTRL_IHB_MODE_HBCLK_DIV(6) | \
+ MCI_CTRL_IHB_MODE_FWD_MOD | \
+ MCI_CTRL_IHB_MODE_SEQFF_FINE_MOD(0xF) | \
+ MCI_CTRL_IHB_MODE_RX_COMB_THRESH(0x3f) | \
+ MCI_CTRL_IHB_MODE_TX_COMB_THRESH(0x40))
+/* AXI_HB registers */
+#define MCI_AXI_ACCESS_DATA_REG_NUM 0x0
+#define MCI_AXI_ACCESS_PCIE_MODE 1
+#define MCI_AXI_ACCESS_CACHE_CHECK_OFFSET 5
+#define MCI_AXI_ACCESS_CACHE_CHECK \
+ (1 << MCI_AXI_ACCESS_CACHE_CHECK_OFFSET)
+#define MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET 6
+#define MCI_AXI_ACCESS_FORCE_POST_WR \
+ (1 << MCI_AXI_ACCESS_FORCE_POST_WR_OFFSET)
+#define MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET 9
+#define MCI_AXI_ACCESS_DISABLE_CLK_GATING \
+ (1 << MCI_AXI_ACCESS_DISABLE_CLK_GATING_OFFSET)
+
+/* /HB /Units /HB_REG /HB_REGHopping Bus Registers
+ * /Window 0 Address Mask Register
+ */
+#define MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM 0x2
+
+/* /HB /Units /HB_REG /HB_REGHopping Bus Registers
+ * /Window 0 Destination Register
+ */
+#define MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM 0x3
+#define MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(val) (((val) & 0x1) << 16)
+#define MCI_HB_CTRL_WIN0_DEST_ID(val) (((val) & 0xFF) << 0)
+
+/* /HB /Units /HB_REG /HB_REGHopping Bus Registers /Tx Control Register */
+#define MCI_HB_CTRL_TX_CTRL_REG_NUM 0xD
+#define MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET 24
+#define MCI_HB_CTRL_TX_CTRL_PCIE_MODE \
+ (1 << MCI_HB_CTRL_TX_CTRL_PCIE_MODE_OFFSET)
+#define MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(val) (((val) & 0xF) << 12)
+#define MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(val) (((val) & 0x1F) << 6)
+#define MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(val) (((val) & 0x1F) << 0)
+
+/* /HB /Units /IHB_REG /IHB_REGInterchip Hopping Bus Registers
+ * /IHB Version Control Register
+ */
+#define MCI_PHY_CTRL_REG_NUM 0x7
+#define MCI_PHY_CTRL_MCI_MINOR 0x8 /* BITS [3:0] */
+#define MCI_PHY_CTRL_MCI_MAJOR_OFFSET 4
+#define MCI_PHY_CTRL_MCI_MAJOR \
+ (1 << MCI_PHY_CTRL_MCI_MAJOR_OFFSET)
+#define MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET 11
+#define MCI_PHY_CTRL_MCI_SLEEP_REQ \
+ (1 << MCI_PHY_CTRL_MCI_SLEEP_REQ_OFFSET)
+/* Host=1 / Device=0 PHY mode */
+#define MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET 24
+#define MCI_PHY_CTRL_MCI_PHY_MODE_HOST \
+ (1 << MCI_PHY_CTRL_MCI_PHY_MODE_OFFSET)
+/* Register=1 / PWM=0 interface */
+#define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET 25
+#define MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE \
+ (1 << MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE_OFFSET)
+ /* PHY code InReset=1 */
+#define MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET 26
+#define MCI_PHY_CTRL_MCI_PHY_RESET_CORE \
+ (1 << MCI_PHY_CTRL_MCI_PHY_RESET_CORE_OFFSET)
+#define MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET 27
+#define MCI_PHY_CTRL_PHY_ADDR_MSB(addr) \
+ (((addr) & 0x3) << \
+ MCI_PHY_CTRL_PHY_ADDR_MSB_OFFSET)
+#define MCI_PHY_CTRL_PIDI_MODE_OFFSET 31
+#define MCI_PHY_CTRL_PIDI_MODE \
+ (1 << MCI_PHY_CTRL_PIDI_MODE_OFFSET)
+
+/* Number of times to wait for the MCI link ready after MCI configurations
+ * Normally takes 34-35 successive reads
+ */
+#define LINK_READY_TIMEOUT 100
+
+enum mci_register_type {
+ MCI_REG_TYPE_PHY = 0,
+ MCI_REG_TYPE_CTRL,
+};
+
+enum {
+ MCI_CMD_WRITE,
+ MCI_CMD_READ
+};
+
+/* Write wrapper callback for debug:
+ * will print written data in case LOG_LEVEL >= 40
+ */
+static void mci_mmio_write_32(uintptr_t addr, uint32_t value)
+{
+ VERBOSE("Write:\t0x%x = 0x%x\n", (uint32_t)addr, value);
+ mmio_write_32(addr, value);
+}
+/* Read wrapper callback for debug:
+ * will print read data in case LOG_LEVEL >= 40
+ */
+static uint32_t mci_mmio_read_32(uintptr_t addr)
+{
+ uint32_t value;
+
+ value = mmio_read_32(addr);
+ VERBOSE("Read:\t0x%x = 0x%x\n", (uint32_t)addr, value);
+ return value;
+}
+
+/* MCI indirect access command completion polling:
+ * Each write/read command done via MCI indirect registers must be polled
+ * for command completions status.
+ *
+ * Returns 1 in case of error
+ * Returns 0 in case of command completed successfully.
+ */
+static int mci_poll_command_completion(int mci_index, int command_type)
+{
+ uint32_t mci_cmd_value = 0, retry_count = 100, ret = 0;
+ uint32_t completion_flags = MCI_INDIRECT_CTRL_CMD_DONE;
+
+ debug_enter();
+ /* Read commands require validating that requested data is ready */
+ if (command_type == MCI_CMD_READ)
+ completion_flags |= MCI_INDIRECT_CTRL_DATA_READY;
+
+ do {
+ /* wait 1 ms before each polling */
+ mdelay(1);
+ mci_cmd_value = mci_mmio_read_32(MCI_ACCESS_CMD_REG(mci_index));
+ } while (((mci_cmd_value & completion_flags) != completion_flags) &&
+ (retry_count-- > 0));
+
+ if (retry_count == 0) {
+ ERROR("%s: MCI command timeout (command status = 0x%x)\n",
+ __func__, mci_cmd_value);
+ ret = 1;
+ }
+
+ debug_exit();
+ return ret;
+}
+
+int mci_read(int mci_idx, uint32_t cmd, uint32_t *value)
+{
+ int rval;
+
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd);
+
+ rval = mci_poll_command_completion(mci_idx, MCI_CMD_READ);
+
+ *value = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_idx));
+
+ return rval;
+}
+
+int mci_write(int mci_idx, uint32_t cmd, uint32_t data)
+{
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_idx), data);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_idx), cmd);
+
+ return mci_poll_command_completion(mci_idx, MCI_CMD_WRITE);
+}
+
+/* Perform 3 configurations in one command: PCI mode,
+ * queues separation and cache bit
+ */
+static int mci_axi_set_pcie_mode(int mci_index)
+{
+ uint32_t reg_data, ret = 1;
+
+ debug_enter();
+ /* This configuration makes MCI IP behave consistently with AXI protocol
+ * It should be configured at one side only (for example locally at AP).
+ * The IP takes care of performing the same configurations at MCI on
+ * another side (for example remotely at CP).
+ */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_AXI_ACCESS_PCIE_MODE |
+ MCI_AXI_ACCESS_CACHE_CHECK |
+ MCI_AXI_ACCESS_FORCE_POST_WR |
+ MCI_AXI_ACCESS_DISABLE_CLK_GATING);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_AXI_ACCESS_DATA_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT |
+ MCI_INDIRECT_CTRL_CIRCULAR_CMD);
+
+ /* if Write command was successful, verify PCIe mode */
+ if (mci_poll_command_completion(mci_index, MCI_CMD_WRITE) == 0) {
+ /* Verify the PCIe mode selected */
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_TX_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT |
+ MCI_INDIRECT_CTRL_READ_CMD);
+ /* if read was completed, verify PCIe mode */
+ if (mci_poll_command_completion(mci_index, MCI_CMD_READ) == 0) {
+ reg_data = mci_mmio_read_32(
+ MCI_WRITE_READ_DATA_REG(mci_index));
+ if (reg_data & MCI_HB_CTRL_TX_CTRL_PCIE_MODE)
+ ret = 0;
+ }
+ }
+
+ debug_exit();
+ return ret;
+}
+
+/* Reduce sequence FIFO timer expiration threshold */
+static int mci_axi_set_fifo_thresh(int mci_index)
+{
+ uint32_t reg_data, ret = 0;
+
+ debug_enter();
+ /* This configuration reduces sequence FIFO timer expiration threshold
+ * (to 0x7 instead of 0xA).
+ * In MCI 1.6 version this configuration prevents possible functional
+ * issues.
+ * In version 1.82 the configuration prevents performance degradation
+ */
+
+ /* Configure local AP side */
+ reg_data = MCI_PHY_CTRL_PIDI_MODE |
+ MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE |
+ MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
+ MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_MINOR;
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Reduce the threshold */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL);
+
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_IHB_MODE_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Exit PIDI mode */
+ reg_data = MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE |
+ MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
+ MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_MINOR;
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Configure remote CP side */
+ reg_data = MCI_PHY_CTRL_PIDI_MODE |
+ MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_MINOR |
+ MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE;
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_CTRL_IHB_MODE_FWD_MOD);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Reduce the threshold */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_IHB_MODE_CFG_REG_DEF_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_IHB_MODE_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Exit PIDI mode */
+ reg_data = MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_MINOR |
+ MCI_PHY_CTRL_MCI_PHY_REG_IF_MODE;
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index), reg_data);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_CTRL_IHB_MODE_FWD_MOD);
+
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ debug_exit();
+ return ret;
+}
+
+/* Configure:
+ * 1. AP & CP TX thresholds and delta configurations
+ * 2. DLO & DLI FIFO full threshold
+ * 3. RX thresholds and delta configurations
+ * 4. CP AR and AW outstanding
+ * 5. AP AR and AW outstanding
+ */
+static int mci_axi_set_fifo_rx_tx_thresh(int mci_index)
+{
+ uint32_t ret = 0;
+
+ debug_enter();
+ /* AP TX thresholds and delta configurations (IHB_reg 0x1) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_TX_MEM_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* CP TX thresholds and delta configurations (IHB_reg 0x1) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_TX_MEM_CFG_REG_DEF_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_TX_MEM_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* AP DLO & DLI FIFO full threshold & Auto-Link enable (IHB_reg 0x8) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL |
+ MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* CP DLO & DLI FIFO full threshold (IHB_reg 0x8) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* AP RX thresholds and delta configurations (IHB_reg 0x0) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_RX_MEM_CFG_REG_DEF_AP_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_RX_MEM_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* CP RX thresholds and delta configurations (IHB_reg 0x0) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_CTRL_RX_MEM_CFG_REG_DEF_CP_VAL);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_CTRL_RX_MEM_CFG_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* AP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
+ MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(3) |
+ MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(3));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_TX_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* CP AR & AW maximum AXI outstanding request cfg (HB_reg 0xd) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(mci_index),
+ MCI_HB_CTRL_TX_CTRL_PRI_TH_QOS(8) |
+ MCI_HB_CTRL_TX_CTRL_MAX_RD_CNT(0xB) |
+ MCI_HB_CTRL_TX_CTRL_MAX_WR_CNT(0x11));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(mci_index),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_TX_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ debug_exit();
+ return ret;
+}
+
+/* configure MCI to allow read & write transactions to arrive at the same time.
+ * Without the below configuration, MCI won't sent response to CPU for
+ * transactions which arrived simultaneously and will lead to CPU hang.
+ * The below will configure MCI to be able to pass transactions from/to CP/AP.
+ */
+static int mci_enable_simultaneous_transactions(int mci_index)
+{
+ uint32_t ret = 0;
+
+ debug_enter();
+ /* ID assignment (assigning global ID offset to CP) */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
+ MCI_DID_GLOBAL_ASSIGN_REQ_MCI_LOCAL_ID(2) |
+ MCI_DID_GLOBAL_ASSIGN_REQ_MCI_COUNT(2) |
+ MCI_DID_GLOBAL_ASSIGN_REQ_HOPS_NUM(2));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_DID_GLOBAL_ASSIGNMENT_REQUEST_REG) |
+ MCI_INDIRECT_CTRL_ASSIGN_CMD);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Assigning dest. ID=3 to all transactions entering from AXI at AP */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
+ MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
+ MCI_HB_CTRL_WIN0_DEST_ID(3));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* Assigning dest. ID=1 to all transactions entering from AXI at CP */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0),
+ MCI_HB_CTRL_WIN0_DEST_VALID_FLAG(1) |
+ MCI_HB_CTRL_WIN0_DEST_ID(1));
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* End address to all transactions entering from AXI at AP.
+ * This will lead to get match for any AXI address
+ * and receive destination ID=3
+ */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ /* End address to all transactions entering from AXI at CP.
+ * This will lead to get match for any AXI address
+ * and receive destination ID=1
+ */
+ mci_mmio_write_32(MCI_WRITE_READ_DATA_REG(0), 0xffffffff);
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_WIN0_ADDRESS_MASK_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_IHB_EXT) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB));
+ ret |= mci_poll_command_completion(mci_index, MCI_CMD_WRITE);
+
+ debug_exit();
+ return ret;
+}
+
+/* Check if MCI simultaneous transaction was already enabled.
+ * Currently bootrom does this mci configuration only when the boot source is
+ * SAR_MCIX4, in other cases it should be done at this stage.
+ * It is worth noticing that in case of booting from uart, the bootrom
+ * flow is different and this mci initialization is skipped even if boot
+ * source is SAR_MCIX4. Therefore new verification bases on appropriate mci's
+ * register content: if the appropriate reg contains 0x0 it means that the
+ * bootrom didn't perform required mci configuration.
+ *
+ * Returns:
+ * 0 - configuration already done
+ * 1 - configuration missing
+ */
+static _Bool mci_simulatenous_trans_missing(int mci_index)
+{
+ uint32_t reg, ret;
+
+ /* read 'Window 0 Destination ID assignment' from HB register 0x3
+ * (TX_CFG_W0_DST_ID) to check whether ID assignment was already
+ * performed by BootROM.
+ */
+ debug_enter();
+ mci_mmio_write_32(MCI_ACCESS_CMD_REG(0),
+ MCI_INDIRECT_REG_CTRL_ADDR(
+ MCI_HB_CTRL_WIN0_DESTINATION_REG_NUM) |
+ MCI_INDIRECT_CTRL_HOPID(GID_AXI_HB) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT |
+ MCI_INDIRECT_CTRL_READ_CMD);
+ ret = mci_poll_command_completion(mci_index, MCI_CMD_READ);
+
+ reg = mci_mmio_read_32(MCI_WRITE_READ_DATA_REG(mci_index));
+
+ if (ret)
+ ERROR("Failed to verify MCI simultaneous read/write status\n");
+
+ debug_exit();
+ /* default ID assignment is 0, so if register doesn't contain zeros
+ * it means that bootrom already performed required configuration.
+ */
+ if (reg != 0)
+ return 0;
+
+ return 1;
+}
+
+/* For A1 revision, configure the MCI link for performance improvement:
+ * - set MCI to support read/write transactions to arrive at the same time
+ * - Switch AXI to PCIe mode
+ * - Reduce sequence FIFO threshold
+ * - Configure RX/TX FIFO thresholds
+ *
+ * Note:
+ * We don't exit on error code from any sub routine, to try (best effort) to
+ * complete the MCI configuration.
+ * (If we exit - Bootloader will surely fail to boot)
+ */
+int mci_configure(int mci_index)
+{
+ int rval;
+
+ debug_enter();
+ /* According to design guidelines the MCI simultaneous transaction
+ * shouldn't be enabled more then once - therefore make sure that it
+ * wasn't already enabled in bootrom.
+ */
+ if (mci_simulatenous_trans_missing(mci_index)) {
+ VERBOSE("Enabling MCI simultaneous transaction\n");
+ /* set MCI to support read/write transactions
+ * to arrive at the same time
+ */
+ rval = mci_enable_simultaneous_transactions(mci_index);
+ if (rval)
+ ERROR("Failed to set MCI simultaneous read/write\n");
+ } else
+ VERBOSE("Skip MCI ID assignment - already done by bootrom\n");
+
+ /* Configure MCI for more consistent behavior with AXI protocol */
+ rval = mci_axi_set_pcie_mode(mci_index);
+ if (rval)
+ ERROR("Failed to set MCI to AXI PCIe mode\n");
+
+ /* reduce FIFO global threshold */
+ rval = mci_axi_set_fifo_thresh(mci_index);
+ if (rval)
+ ERROR("Failed to set MCI FIFO global threshold\n");
+
+ /* configure RX/TX FIFO thresholds */
+ rval = mci_axi_set_fifo_rx_tx_thresh(mci_index);
+ if (rval)
+ ERROR("Failed to set MCI RX/TX FIFO threshold\n");
+
+ debug_exit();
+ return 1;
+}
+
+int mci_get_link_status(void)
+{
+ uint32_t cmd, data;
+
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT | MCI_INDIRECT_CTRL_READ_CMD);
+ if (mci_read(0, cmd, &data)) {
+ ERROR("Failed to read status register\n");
+ return -1;
+ }
+
+ /* Check if the link is ready */
+ if (data != MCI_CTRL_PHY_READY) {
+ ERROR("Bad link status %x\n", data);
+ return -1;
+ }
+
+ return 0;
+}
+
+void mci_turn_link_down(void)
+{
+ uint32_t cmd, data;
+ int rval = 0;
+
+ debug_enter();
+
+ /* Turn off auto-link */
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 |
+ MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(0));
+ rval = mci_write(0, cmd, data);
+ if (rval)
+ ERROR("Failed to turn off auto-link\n");
+
+ /* Reset AP PHY */
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = (MCI_PHY_CTRL_MCI_MINOR |
+ MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_PHY_MODE_HOST |
+ MCI_PHY_CTRL_MCI_PHY_RESET_CORE);
+ rval = mci_write(0, cmd, data);
+ if (rval)
+ ERROR("Failed to reset AP PHY\n");
+
+ /* Clear all status & CRC values */
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_LINK_CRC_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = 0x0;
+ mci_write(0, cmd, data);
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_STATUS_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = 0x0;
+ rval = mci_write(0, cmd, data);
+ if (rval)
+ ERROR("Failed to reset AP PHY\n");
+
+ /* Wait 5ms before un-reset the PHY */
+ mdelay(5);
+
+ /* Un-reset AP PHY */
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_PHY_CTRL_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = (MCI_PHY_CTRL_MCI_MINOR | MCI_PHY_CTRL_MCI_MAJOR |
+ MCI_PHY_CTRL_MCI_PHY_MODE_HOST);
+ rval = mci_write(0, cmd, data);
+ if (rval)
+ ERROR("Failed to un-reset AP PHY\n");
+
+ debug_exit();
+}
+
+void mci_turn_link_on(void)
+{
+ uint32_t cmd, data;
+ int rval = 0;
+
+ debug_enter();
+ /* Turn on auto-link */
+ cmd = (MCI_INDIRECT_REG_CTRL_ADDR(MCI_CTRL_MCI_PHY_SETTINGS_REG_NUM) |
+ MCI_INDIRECT_CTRL_LOCAL_PKT);
+ data = (MCI_CTRL_MCI_PHY_SET_REG_DEF_VAL2 |
+ MCI_CTRL_MCI_PHY_SET_AUTO_LINK_EN(1));
+ rval = mci_write(0, cmd, data);
+ if (rval)
+ ERROR("Failed to turn on auto-link\n");
+
+ debug_exit();
+}
+
+/* Initialize MCI for performance improvements */
+int mci_initialize(int mci_index)
+{
+ int ret;
+
+ debug_enter();
+ INFO("MCI%d initialization:\n", mci_index);
+
+ ret = mci_configure(mci_index);
+
+ debug_exit();
+ return ret;
+}
diff --git a/drivers/marvell/mochi/ap807_setup.c b/drivers/marvell/mochi/ap807_setup.c
new file mode 100644
index 000000000..075ca31f8
--- /dev/null
+++ b/drivers/marvell/mochi/ap807_setup.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* AP807 Marvell SoC driver */
+
+#include <ap_setup.h>
+#include <cache_llc.h>
+#include <ccu.h>
+#include <debug.h>
+#include <io_win.h>
+#include <mci.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#define SMMU_sACR (MVEBU_SMMU_BASE + 0x10)
+#define SMMU_sACR_PG_64K (1 << 16)
+
+#define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) \
+ + 0x3F0)
+#define GSPMU_CPU_CONTROL (0x1 << 0)
+
+#define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) \
+ + 0x200)
+#define CCU_SET_POC_OFFSET 5
+
+#define DSS_CR0 (MVEBU_RFU_BASE + 0x100)
+#define DVM_48BIT_VA_ENABLE (1 << 21)
+
+/* Secure MoChi incoming access */
+#define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738)
+#define SEC_MOCHI_IN_ACC_IHB0_EN (1)
+#define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3)
+#define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6)
+#define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9)
+#define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \
+ SEC_MOCHI_IN_ACC_IHB1_EN | \
+ SEC_MOCHI_IN_ACC_IHB2_EN | \
+ SEC_MOCHI_IN_ACC_PIDI_EN)
+
+/* SYSRST_OUTn Config definitions */
+#define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4)
+#define WD_MASK_SYS_RST_OUT (1 << 2)
+
+/* DSS PHY for DRAM */
+#define DSS_SCR_REG (MVEBU_RFU_BASE + 0x208)
+#define DSS_PPROT_OFFS 4
+#define DSS_PPROT_MASK 0x7
+#define DSS_PPROT_PRIV_SECURE_DATA 0x1
+
+/* Used for Units of AP-807 (e.g. SDIO and etc) */
+#define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580)
+#define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \
+ 0x4 * index)
+
+enum axi_attr {
+ AXI_SDIO_ATTR = 0,
+ AXI_DFX_ATTR,
+ AXI_MAX_ATTR,
+};
+
+static void ap_sec_masters_access_en(uint32_t enable)
+{
+ uint32_t reg;
+
+ /* Open/Close incoming access for all masters.
+ * The access is disabled in trusted boot mode
+ * Could only be done in EL3
+ */
+ reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG);
+ if (enable)
+ mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg |
+ SEC_IN_ACCESS_ENA_ALL_MASTERS);
+ else
+ mmio_write_32(SEC_MOCHI_IN_ACC_REG,
+ reg & ~SEC_IN_ACCESS_ENA_ALL_MASTERS);
+}
+
+static void setup_smmu(void)
+{
+ uint32_t reg;
+
+ /* Set the SMMU page size to 64 KB */
+ reg = mmio_read_32(SMMU_sACR);
+ reg |= SMMU_sACR_PG_64K;
+ mmio_write_32(SMMU_sACR, reg);
+}
+
+static void init_aurora2(void)
+{
+ uint32_t reg;
+
+ /* Enable GSPMU control by CPU */
+ reg = mmio_read_32(CCU_GSPMU_CR);
+ reg |= GSPMU_CPU_CONTROL;
+ mmio_write_32(CCU_GSPMU_CR, reg);
+
+#if LLC_ENABLE
+ /* Enable LLC for AP807 in exclusive mode */
+ llc_enable(0, 1);
+
+ /* Set point of coherency to DDR.
+ * This is required by units which have
+ * SW cache coherency
+ */
+ reg = mmio_read_32(CCU_HTC_CR);
+ reg |= (0x1 << CCU_SET_POC_OFFSET);
+ mmio_write_32(CCU_HTC_CR, reg);
+#endif /* LLC_ENABLE */
+}
+
+
+/* MCIx indirect access register are based by default at 0xf4000000/0xf6000000
+ * to avoid conflict of internal registers of units connected via MCIx, which
+ * can be based on the same address (i.e CP1 base is also 0xf4000000),
+ * the following routines remaps the MCIx indirect bases to another domain
+ */
+static void mci_remap_indirect_access_base(void)
+{
+ uint32_t mci;
+
+ for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++)
+ mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci),
+ MVEBU_MCI_REG_BASE_REMAP(mci) >>
+ MCI_REMAP_OFF_SHIFT);
+}
+
+static void ap807_axi_attr_init(void)
+{
+ uint32_t index, data;
+
+ /* Initialize AXI attributes for AP807 */
+ /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
+ for (index = 0; index < AXI_MAX_ATTR; index++) {
+ switch (index) {
+ /* DFX works with no coherent only -
+ * there's no option to configure the Ax-Cache and Ax-Domain
+ */
+ case AXI_DFX_ATTR:
+ continue;
+ default:
+ /* Set Ax-Cache as cacheable, no allocate, modifiable,
+ * bufferable.
+ * The values are different because Read & Write
+ * definition is different in Ax-Cache
+ */
+ data = mmio_read_32(MVEBU_AXI_ATTR_REG(index));
+ data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
+ data |= (CACHE_ATTR_WRITE_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_ARCACHE_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
+ data |= (CACHE_ATTR_READ_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_AWCACHE_OFFSET;
+ /* Set Ax-Domain as Outer domain */
+ data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
+ mmio_write_32(MVEBU_AXI_ATTR_REG(index), data);
+ }
+ }
+}
+
+static void misc_soc_configurations(void)
+{
+ uint32_t reg;
+
+ /* Enable 48-bit VA */
+ mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE);
+
+ /* Un-mask Watchdog reset from influencing the SYSRST_OUTn.
+ * Otherwise, upon WD timeout, the WD reset signal won't trigger reset
+ */
+ reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG);
+ reg &= ~(WD_MASK_SYS_RST_OUT);
+ mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg);
+}
+
+void ap_init(void)
+{
+ /* Setup Aurora2. */
+ init_aurora2();
+
+ /* configure MCI mapping */
+ mci_remap_indirect_access_base();
+
+ /* configure IO_WIN windows */
+ init_io_win(MVEBU_AP0);
+
+ /* configure CCU windows */
+ init_ccu(MVEBU_AP0);
+
+ /* configure the SMMU */
+ setup_smmu();
+
+ /* Open AP incoming access for all masters */
+ ap_sec_masters_access_en(1);
+
+ /* configure axi for AP */
+ ap807_axi_attr_init();
+
+ /* misc configuration of the SoC */
+ misc_soc_configurations();
+}
+
+static void ap807_dram_phy_access_config(void)
+{
+ uint32_t reg_val;
+ /* Update DSS port access permission to DSS_PHY */
+ reg_val = mmio_read_32(DSS_SCR_REG);
+ reg_val &= ~(DSS_PPROT_MASK << DSS_PPROT_OFFS);
+ reg_val |= ((DSS_PPROT_PRIV_SECURE_DATA & DSS_PPROT_MASK) <<
+ DSS_PPROT_OFFS);
+ mmio_write_32(DSS_SCR_REG, reg_val);
+}
+
+void ap_ble_init(void)
+{
+ /* Enable DSS port */
+ ap807_dram_phy_access_config();
+}
+
+int ap_get_count(void)
+{
+ return 1;
+}
+
+
diff --git a/drivers/marvell/mochi/apn806_setup.c b/drivers/marvell/mochi/apn806_setup.c
new file mode 100644
index 000000000..1d33be93a
--- /dev/null
+++ b/drivers/marvell/mochi/apn806_setup.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* AP806 Marvell SoC driver */
+
+#include <ap_setup.h>
+#include <ccu.h>
+#include <cache_llc.h>
+#include <debug.h>
+#include <io_win.h>
+#include <mci.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#define SMMU_sACR (MVEBU_SMMU_BASE + 0x10)
+#define SMMU_sACR_PG_64K (1 << 16)
+
+#define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
+ 0x3F0)
+#define GSPMU_CPU_CONTROL (0x1 << 0)
+
+#define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
+ 0x200)
+#define CCU_SET_POC_OFFSET 5
+
+#define CCU_RGF(win) (MVEBU_CCU_BASE(MVEBU_AP0) + \
+ 0x90 + 4 * (win))
+
+#define DSS_CR0 (MVEBU_RFU_BASE + 0x100)
+#define DVM_48BIT_VA_ENABLE (1 << 21)
+
+/* Secure MoChi incoming access */
+#define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738)
+#define SEC_MOCHI_IN_ACC_IHB0_EN (1)
+#define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3)
+#define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6)
+#define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9)
+#define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \
+ SEC_MOCHI_IN_ACC_IHB1_EN | \
+ SEC_MOCHI_IN_ACC_IHB2_EN | \
+ SEC_MOCHI_IN_ACC_PIDI_EN)
+
+/* SYSRST_OUTn Config definitions */
+#define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4)
+#define WD_MASK_SYS_RST_OUT (1 << 2)
+
+/* Generic Timer System Controller */
+#define MVEBU_MSS_GTCR_REG (MVEBU_REGS_BASE + 0x581000)
+#define MVEBU_MSS_GTCR_ENABLE_BIT 0x1
+
+/*
+ * AXI Configuration.
+ */
+
+/* Used for Units of AP-806 (e.g. SDIO and etc) */
+#define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580)
+#define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \
+ 0x4 * index)
+
+enum axi_attr {
+ AXI_SDIO_ATTR = 0,
+ AXI_DFX_ATTR,
+ AXI_MAX_ATTR,
+};
+
+static void apn_sec_masters_access_en(uint32_t enable)
+{
+ uint32_t reg;
+
+ /* Open/Close incoming access for all masters.
+ * The access is disabled in trusted boot mode
+ * Could only be done in EL3
+ */
+ reg = mmio_read_32(SEC_MOCHI_IN_ACC_REG);
+ if (enable)
+ mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg |
+ SEC_IN_ACCESS_ENA_ALL_MASTERS);
+ else
+ mmio_write_32(SEC_MOCHI_IN_ACC_REG, reg &
+ ~SEC_IN_ACCESS_ENA_ALL_MASTERS);
+}
+
+static void setup_smmu(void)
+{
+ uint32_t reg;
+
+ /* Set the SMMU page size to 64 KB */
+ reg = mmio_read_32(SMMU_sACR);
+ reg |= SMMU_sACR_PG_64K;
+ mmio_write_32(SMMU_sACR, reg);
+}
+
+static void apn806_errata_wa_init(void)
+{
+ /*
+ * ERRATA ID: RES-3033912 - Internal Address Space Init state causes
+ * a hang upon accesses to [0xf070_0000, 0xf07f_ffff]
+ * Workaround: Boot Firmware (ATF) should configure CCU_RGF_WIN(4) to
+ * split [0x6e_0000, 0xff_ffff] to values [0x6e_0000, 0x6f_ffff] and
+ * [0x80_0000, 0xff_ffff] that cause accesses to the
+ * segment of [0xf070_0000, 0xf07f_ffff] to act as RAZWI.
+ */
+ mmio_write_32(CCU_RGF(4), 0x37f9b809);
+ mmio_write_32(CCU_RGF(5), 0x7ffa0009);
+}
+
+static void init_aurora2(void)
+{
+ uint32_t reg;
+
+ /* Enable GSPMU control by CPU */
+ reg = mmio_read_32(CCU_GSPMU_CR);
+ reg |= GSPMU_CPU_CONTROL;
+ mmio_write_32(CCU_GSPMU_CR, reg);
+
+#if LLC_ENABLE
+ /* Enable LLC for AP806 in exclusive mode */
+ llc_enable(0, 1);
+
+ /* Set point of coherency to DDR.
+ * This is required by units which have
+ * SW cache coherency
+ */
+ reg = mmio_read_32(CCU_HTC_CR);
+ reg |= (0x1 << CCU_SET_POC_OFFSET);
+ mmio_write_32(CCU_HTC_CR, reg);
+#endif /* LLC_ENABLE */
+
+ apn806_errata_wa_init();
+}
+
+
+/* MCIx indirect access register are based by default at 0xf4000000/0xf6000000
+ * to avoid conflict of internal registers of units connected via MCIx, which
+ * can be based on the same address (i.e CP1 base is also 0xf4000000),
+ * the following routines remaps the MCIx indirect bases to another domain
+ */
+static void mci_remap_indirect_access_base(void)
+{
+ uint32_t mci;
+
+ for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++)
+ mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci),
+ MVEBU_MCI_REG_BASE_REMAP(mci) >>
+ MCI_REMAP_OFF_SHIFT);
+}
+
+static void apn806_axi_attr_init(void)
+{
+ uint32_t index, data;
+
+ /* Initialize AXI attributes for APN806 */
+
+ /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
+ for (index = 0; index < AXI_MAX_ATTR; index++) {
+ switch (index) {
+ /* DFX works with no coherent only -
+ * there's no option to configure the Ax-Cache and Ax-Domain
+ */
+ case AXI_DFX_ATTR:
+ continue;
+ default:
+ /* Set Ax-Cache as cacheable, no allocate, modifiable,
+ * bufferable
+ * The values are different because Read & Write
+ * definition is different in Ax-Cache
+ */
+ data = mmio_read_32(MVEBU_AXI_ATTR_REG(index));
+ data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
+ data |= (CACHE_ATTR_WRITE_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_ARCACHE_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
+ data |= (CACHE_ATTR_READ_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_AWCACHE_OFFSET;
+ /* Set Ax-Domain as Outer domain */
+ data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
+ mmio_write_32(MVEBU_AXI_ATTR_REG(index), data);
+ }
+ }
+}
+
+static void dss_setup(void)
+{
+ /* Enable 48-bit VA */
+ mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE);
+}
+
+void misc_soc_configurations(void)
+{
+ uint32_t reg;
+
+ /* Un-mask Watchdog reset from influencing the SYSRST_OUTn.
+ * Otherwise, upon WD timeout, the WD reset signal won't trigger reset
+ */
+ reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG);
+ reg &= ~(WD_MASK_SYS_RST_OUT);
+ mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg);
+}
+
+void ap_init(void)
+{
+ /* Setup Aurora2. */
+ init_aurora2();
+
+ /* configure MCI mapping */
+ mci_remap_indirect_access_base();
+
+ /* configure IO_WIN windows */
+ init_io_win(MVEBU_AP0);
+
+ /* configure CCU windows */
+ init_ccu(MVEBU_AP0);
+
+ /* configure DSS */
+ dss_setup();
+
+ /* configure the SMMU */
+ setup_smmu();
+
+ /* Open APN incoming access for all masters */
+ apn_sec_masters_access_en(1);
+
+ /* configure axi for APN*/
+ apn806_axi_attr_init();
+
+ /* misc configuration of the SoC */
+ misc_soc_configurations();
+}
+
+void ap_ble_init(void)
+{
+}
+
+int ap_get_count(void)
+{
+ return 1;
+}
+
diff --git a/drivers/marvell/mochi/cp110_setup.c b/drivers/marvell/mochi/cp110_setup.c
new file mode 100644
index 000000000..c4cb307f9
--- /dev/null
+++ b/drivers/marvell/mochi/cp110_setup.c
@@ -0,0 +1,429 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* CP110 Marvell SoC driver */
+
+#include <amb_adec.h>
+#include <cp110_setup.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <iob.h>
+#include <plat_marvell.h>
+
+/*
+ * AXI Configuration.
+ */
+
+ /* Used for Units of CP-110 (e.g. USB device, USB Host, and etc) */
+#define MVEBU_AXI_ATTR_OFFSET (0x441300)
+#define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_OFFSET + \
+ 0x4 * index)
+
+/* AXI Protection bits */
+#define MVEBU_AXI_PROT_OFFSET (0x441200)
+
+/* AXI Protection regs */
+#define MVEBU_AXI_PROT_REG(index) ((index <= 4) ? \
+ (MVEBU_AXI_PROT_OFFSET + \
+ 0x4 * index) : \
+ (MVEBU_AXI_PROT_OFFSET + 0x18))
+#define MVEBU_AXI_PROT_REGS_NUM (6)
+
+#define MVEBU_SOC_CFGS_OFFSET (0x441900)
+#define MVEBU_SOC_CFG_REG(index) (MVEBU_SOC_CFGS_OFFSET + \
+ 0x4 * index)
+#define MVEBU_SOC_CFG_REG_NUM (0)
+#define MVEBU_SOC_CFG_GLOG_SECURE_EN_MASK (0xE)
+
+/* SATA3 MBUS to AXI regs */
+#define MVEBU_BRIDGE_WIN_DIS_REG (MVEBU_SOC_CFGS_OFFSET + 0x10)
+#define MVEBU_BRIDGE_WIN_DIS_OFF (0x0)
+
+/* SATA3 MBUS to AXI regs */
+#define MVEBU_SATA_M2A_AXI_PORT_CTRL_REG (0x54ff04)
+
+/* AXI to MBUS bridge registers */
+#define MVEBU_AMB_IP_OFFSET (0x13ff00)
+#define MVEBU_AMB_IP_BRIDGE_WIN_REG(win) (MVEBU_AMB_IP_OFFSET + \
+ (win * 0x8))
+#define MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET 0
+#define MVEBU_AMB_IP_BRIDGE_WIN_EN_MASK \
+ (0x1 << MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET)
+#define MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET 16
+#define MVEBU_AMB_IP_BRIDGE_WIN_SIZE_MASK \
+ (0xffff << MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET)
+
+#define MVEBU_SAMPLE_AT_RESET_REG (0x440600)
+#define SAR_PCIE1_CLK_CFG_OFFSET 31
+#define SAR_PCIE1_CLK_CFG_MASK (0x1 << SAR_PCIE1_CLK_CFG_OFFSET)
+#define SAR_PCIE0_CLK_CFG_OFFSET 30
+#define SAR_PCIE0_CLK_CFG_MASK (0x1 << SAR_PCIE0_CLK_CFG_OFFSET)
+#define SAR_I2C_INIT_EN_OFFSET 24
+#define SAR_I2C_INIT_EN_MASK (1 << SAR_I2C_INIT_EN_OFFSET)
+
+/*******************************************************************************
+ * PCIE clock buffer control
+ ******************************************************************************/
+#define MVEBU_PCIE_REF_CLK_BUF_CTRL (0x4404F0)
+#define PCIE1_REFCLK_BUFF_SOURCE 0x800
+#define PCIE0_REFCLK_BUFF_SOURCE 0x400
+
+/*******************************************************************************
+ * MSS Device Push Set Register
+ ******************************************************************************/
+#define MVEBU_CP_MSS_DPSHSR_REG (0x280040)
+#define MSS_DPSHSR_REG_PCIE_CLK_SEL 0x8
+
+/*******************************************************************************
+ * RTC Configuration
+ ******************************************************************************/
+#define MVEBU_RTC_BASE (0x284000)
+#define MVEBU_RTC_STATUS_REG (MVEBU_RTC_BASE + 0x0)
+#define MVEBU_RTC_STATUS_ALARM1_MASK 0x1
+#define MVEBU_RTC_STATUS_ALARM2_MASK 0x2
+#define MVEBU_RTC_IRQ_1_CONFIG_REG (MVEBU_RTC_BASE + 0x4)
+#define MVEBU_RTC_IRQ_2_CONFIG_REG (MVEBU_RTC_BASE + 0x8)
+#define MVEBU_RTC_TIME_REG (MVEBU_RTC_BASE + 0xC)
+#define MVEBU_RTC_ALARM_1_REG (MVEBU_RTC_BASE + 0x10)
+#define MVEBU_RTC_ALARM_2_REG (MVEBU_RTC_BASE + 0x14)
+#define MVEBU_RTC_CCR_REG (MVEBU_RTC_BASE + 0x18)
+#define MVEBU_RTC_NOMINAL_TIMING 0x2000
+#define MVEBU_RTC_NOMINAL_TIMING_MASK 0x7FFF
+#define MVEBU_RTC_TEST_CONFIG_REG (MVEBU_RTC_BASE + 0x1C)
+#define MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG (MVEBU_RTC_BASE + 0x80)
+#define MVEBU_RTC_WRCLK_PERIOD_MASK 0xFFFF
+#define MVEBU_RTC_WRCLK_PERIOD_DEFAULT 0x3FF
+#define MVEBU_RTC_WRCLK_SETUP_OFFS 16
+#define MVEBU_RTC_WRCLK_SETUP_MASK 0xFFFF0000
+#define MVEBU_RTC_WRCLK_SETUP_DEFAULT 0x29
+#define MVEBU_RTC_BRIDGE_TIMING_CTRL1_REG (MVEBU_RTC_BASE + 0x84)
+#define MVEBU_RTC_READ_OUTPUT_DELAY_MASK 0xFFFF
+#define MVEBU_RTC_READ_OUTPUT_DELAY_DEFAULT 0x1F
+
+enum axi_attr {
+ AXI_ADUNIT_ATTR = 0,
+ AXI_COMUNIT_ATTR,
+ AXI_EIP197_ATTR,
+ AXI_USB3D_ATTR,
+ AXI_USB3H0_ATTR,
+ AXI_USB3H1_ATTR,
+ AXI_SATA0_ATTR,
+ AXI_SATA1_ATTR,
+ AXI_DAP_ATTR,
+ AXI_DFX_ATTR,
+ AXI_DBG_TRC_ATTR = 12,
+ AXI_SDIO_ATTR,
+ AXI_MSS_ATTR,
+ AXI_MAX_ATTR,
+};
+
+/* Most stream IDS are configured centrally in the CP-110 RFU
+ * but some are configured inside the unit registers
+ */
+#define RFU_STREAM_ID_BASE (0x450000)
+#define USB3H_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0xC)
+#define USB3H_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x10)
+#define SATA_0_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x14)
+#define SATA_1_STREAM_ID_REG (RFU_STREAM_ID_BASE + 0x18)
+
+#define CP_DMA_0_STREAM_ID_REG (0x6B0010)
+#define CP_DMA_1_STREAM_ID_REG (0x6D0010)
+
+/* We allocate IDs 128-255 for PCIe */
+#define MAX_STREAM_ID (0x80)
+
+uintptr_t stream_id_reg[] = {
+ USB3H_0_STREAM_ID_REG,
+ USB3H_1_STREAM_ID_REG,
+ CP_DMA_0_STREAM_ID_REG,
+ CP_DMA_1_STREAM_ID_REG,
+ SATA_0_STREAM_ID_REG,
+ SATA_1_STREAM_ID_REG,
+ 0
+};
+
+static void cp110_errata_wa_init(uintptr_t base)
+{
+ uint32_t data;
+
+ /* ERRATA GL-4076863:
+ * Reset value for global_secure_enable inputs must be changed
+ * from '1' to '0'.
+ * When asserted, only "secured" transactions can enter IHB
+ * configuration space.
+ * However, blocking AXI transactions is performed by IOB.
+ * Performing it also at IHB/HB complicates programming model.
+ *
+ * Enable non-secure access in SOC configuration register
+ */
+ data = mmio_read_32(base + MVEBU_SOC_CFG_REG(MVEBU_SOC_CFG_REG_NUM));
+ data &= ~MVEBU_SOC_CFG_GLOG_SECURE_EN_MASK;
+ mmio_write_32(base + MVEBU_SOC_CFG_REG(MVEBU_SOC_CFG_REG_NUM), data);
+}
+
+static void cp110_pcie_clk_cfg(uintptr_t base)
+{
+ uint32_t pcie0_clk, pcie1_clk, reg;
+
+ /*
+ * Determine the pcie0/1 clock direction (input/output) from the
+ * sample at reset.
+ */
+ reg = mmio_read_32(base + MVEBU_SAMPLE_AT_RESET_REG);
+ pcie0_clk = (reg & SAR_PCIE0_CLK_CFG_MASK) >> SAR_PCIE0_CLK_CFG_OFFSET;
+ pcie1_clk = (reg & SAR_PCIE1_CLK_CFG_MASK) >> SAR_PCIE1_CLK_CFG_OFFSET;
+
+ /* CP110 revision A2 */
+ if (cp110_rev_id_get(base) == MVEBU_CP110_REF_ID_A2) {
+ /*
+ * PCIe Reference Clock Buffer Control register must be
+ * set according to the clock direction (input/output)
+ */
+ reg = mmio_read_32(base + MVEBU_PCIE_REF_CLK_BUF_CTRL);
+ reg &= ~(PCIE0_REFCLK_BUFF_SOURCE | PCIE1_REFCLK_BUFF_SOURCE);
+ if (!pcie0_clk)
+ reg |= PCIE0_REFCLK_BUFF_SOURCE;
+ if (!pcie1_clk)
+ reg |= PCIE1_REFCLK_BUFF_SOURCE;
+
+ mmio_write_32(base + MVEBU_PCIE_REF_CLK_BUF_CTRL, reg);
+ }
+
+ /* CP110 revision A1 */
+ if (cp110_rev_id_get(base) == MVEBU_CP110_REF_ID_A1) {
+ if (!pcie0_clk || !pcie1_clk) {
+ /*
+ * if one of the pcie clocks is set to input,
+ * we need to set mss_push[131] field, otherwise,
+ * the pcie clock might not work.
+ */
+ reg = mmio_read_32(base + MVEBU_CP_MSS_DPSHSR_REG);
+ reg |= MSS_DPSHSR_REG_PCIE_CLK_SEL;
+ mmio_write_32(base + MVEBU_CP_MSS_DPSHSR_REG, reg);
+ }
+ }
+}
+
+/* Set a unique stream id for all DMA capable devices */
+static void cp110_stream_id_init(uintptr_t base, uint32_t stream_id)
+{
+ int i = 0;
+
+ while (stream_id_reg[i]) {
+ if (i > MAX_STREAM_ID_PER_CP) {
+ NOTICE("Only first %d (maximum) Stream IDs allocated\n",
+ MAX_STREAM_ID_PER_CP);
+ return;
+ }
+
+ if ((stream_id_reg[i] == CP_DMA_0_STREAM_ID_REG) ||
+ (stream_id_reg[i] == CP_DMA_1_STREAM_ID_REG))
+ mmio_write_32(base + stream_id_reg[i],
+ stream_id << 16 | stream_id);
+ else
+ mmio_write_32(base + stream_id_reg[i], stream_id);
+
+ /* SATA port 0/1 are in the same SATA unit, and they should use
+ * the same STREAM ID number
+ */
+ if (stream_id_reg[i] != SATA_0_STREAM_ID_REG)
+ stream_id++;
+
+ i++;
+ }
+}
+
+static void cp110_axi_attr_init(uintptr_t base)
+{
+ uint32_t index, data;
+
+ /* Initialize AXI attributes for Armada-7K/8K SoC */
+
+ /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
+ for (index = 0; index < AXI_MAX_ATTR; index++) {
+ switch (index) {
+ /* DFX and MSS unit works with no coherent only -
+ * there's no option to configure the Ax-Cache and Ax-Domain
+ */
+ case AXI_DFX_ATTR:
+ case AXI_MSS_ATTR:
+ continue;
+ default:
+ /* Set Ax-Cache as cacheable, no allocate, modifiable,
+ * bufferable
+ * The values are different because Read & Write
+ * definition is different in Ax-Cache
+ */
+ data = mmio_read_32(base + MVEBU_AXI_ATTR_REG(index));
+ data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
+ data |= (CACHE_ATTR_WRITE_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_ARCACHE_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
+ data |= (CACHE_ATTR_READ_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_AXI_ATTR_AWCACHE_OFFSET;
+ /* Set Ax-Domain as Outer domain */
+ data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
+ data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
+ data |= DOMAIN_OUTER_SHAREABLE <<
+ MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
+ mmio_write_32(base + MVEBU_AXI_ATTR_REG(index), data);
+ }
+ }
+
+ /* SATA IOCC supported, cache attributes
+ * for SATA MBUS to AXI configuration.
+ */
+ data = mmio_read_32(base + MVEBU_SATA_M2A_AXI_PORT_CTRL_REG);
+ data &= ~MVEBU_SATA_M2A_AXI_AWCACHE_MASK;
+ data |= (CACHE_ATTR_WRITE_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET;
+ data &= ~MVEBU_SATA_M2A_AXI_ARCACHE_MASK;
+ data |= (CACHE_ATTR_READ_ALLOC |
+ CACHE_ATTR_CACHEABLE |
+ CACHE_ATTR_BUFFERABLE) <<
+ MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET;
+ mmio_write_32(base + MVEBU_SATA_M2A_AXI_PORT_CTRL_REG, data);
+
+ /* Set all IO's AXI attribute to non-secure access. */
+ for (index = 0; index < MVEBU_AXI_PROT_REGS_NUM; index++)
+ mmio_write_32(base + MVEBU_AXI_PROT_REG(index),
+ DOMAIN_SYSTEM_SHAREABLE);
+}
+
+static void amb_bridge_init(uintptr_t base)
+{
+ uint32_t reg;
+
+ /* Open AMB bridge Window to Access COMPHY/MDIO registers */
+ reg = mmio_read_32(base + MVEBU_AMB_IP_BRIDGE_WIN_REG(0));
+ reg &= ~(MVEBU_AMB_IP_BRIDGE_WIN_SIZE_MASK |
+ MVEBU_AMB_IP_BRIDGE_WIN_EN_MASK);
+ reg |= (0x7ff << MVEBU_AMB_IP_BRIDGE_WIN_SIZE_OFFSET) |
+ (0x1 << MVEBU_AMB_IP_BRIDGE_WIN_EN_OFFSET);
+ mmio_write_32(base + MVEBU_AMB_IP_BRIDGE_WIN_REG(0), reg);
+}
+
+static void cp110_rtc_init(uintptr_t base)
+{
+ /* Update MBus timing parameters before accessing RTC registers */
+ mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG,
+ MVEBU_RTC_WRCLK_PERIOD_MASK,
+ MVEBU_RTC_WRCLK_PERIOD_DEFAULT);
+
+ mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL0_REG,
+ MVEBU_RTC_WRCLK_SETUP_MASK,
+ MVEBU_RTC_WRCLK_SETUP_DEFAULT <<
+ MVEBU_RTC_WRCLK_SETUP_OFFS);
+
+ mmio_clrsetbits_32(base + MVEBU_RTC_BRIDGE_TIMING_CTRL1_REG,
+ MVEBU_RTC_READ_OUTPUT_DELAY_MASK,
+ MVEBU_RTC_READ_OUTPUT_DELAY_DEFAULT);
+
+ /*
+ * Issue reset to the RTC if Clock Correction register
+ * contents did not sustain the reboot/power-on.
+ */
+ if ((mmio_read_32(base + MVEBU_RTC_CCR_REG) &
+ MVEBU_RTC_NOMINAL_TIMING_MASK) != MVEBU_RTC_NOMINAL_TIMING) {
+ /* Reset Test register */
+ mmio_write_32(base + MVEBU_RTC_TEST_CONFIG_REG, 0);
+ mdelay(500);
+
+ /* Reset Time register */
+ mmio_write_32(base + MVEBU_RTC_TIME_REG, 0);
+ udelay(62);
+
+ /* Reset Status register */
+ mmio_write_32(base + MVEBU_RTC_STATUS_REG,
+ (MVEBU_RTC_STATUS_ALARM1_MASK |
+ MVEBU_RTC_STATUS_ALARM2_MASK));
+ udelay(62);
+
+ /* Turn off Int1 and Int2 sources & clear the Alarm count */
+ mmio_write_32(base + MVEBU_RTC_IRQ_1_CONFIG_REG, 0);
+ mmio_write_32(base + MVEBU_RTC_IRQ_2_CONFIG_REG, 0);
+ mmio_write_32(base + MVEBU_RTC_ALARM_1_REG, 0);
+ mmio_write_32(base + MVEBU_RTC_ALARM_2_REG, 0);
+
+ /* Setup nominal register access timing */
+ mmio_write_32(base + MVEBU_RTC_CCR_REG,
+ MVEBU_RTC_NOMINAL_TIMING);
+
+ /* Reset Time register */
+ mmio_write_32(base + MVEBU_RTC_TIME_REG, 0);
+ udelay(10);
+
+ /* Reset Status register */
+ mmio_write_32(base + MVEBU_RTC_STATUS_REG,
+ (MVEBU_RTC_STATUS_ALARM1_MASK |
+ MVEBU_RTC_STATUS_ALARM2_MASK));
+ udelay(50);
+ }
+}
+
+static void cp110_amb_adec_init(uintptr_t base)
+{
+ /* enable AXI-MBUS by clearing "Bridge Windows Disable" */
+ mmio_clrbits_32(base + MVEBU_BRIDGE_WIN_DIS_REG,
+ (1 << MVEBU_BRIDGE_WIN_DIS_OFF));
+
+ /* configure AXI-MBUS windows for CP */
+ init_amb_adec(base);
+}
+
+void cp110_init(uintptr_t cp110_base, uint32_t stream_id)
+{
+ INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base);
+
+ /* configure IOB windows for CP0*/
+ init_iob(cp110_base);
+
+ /* configure AXI-MBUS windows for CP0*/
+ cp110_amb_adec_init(cp110_base);
+
+ /* configure axi for CP0*/
+ cp110_axi_attr_init(cp110_base);
+
+ /* Execute SW WA for erratas */
+ cp110_errata_wa_init(cp110_base);
+
+ /* Confiure pcie clock according to clock direction */
+ cp110_pcie_clk_cfg(cp110_base);
+
+ /* configure stream id for CP0 */
+ cp110_stream_id_init(cp110_base, stream_id);
+
+ /* Open AMB bridge for comphy for CP0 & CP1*/
+ amb_bridge_init(cp110_base);
+
+ /* Reset RTC if needed */
+ cp110_rtc_init(cp110_base);
+}
+
+/* Do the minimal setup required to configure the CP in BLE */
+void cp110_ble_init(uintptr_t cp110_base)
+{
+#if PCI_EP_SUPPORT
+ INFO("%s: Initialize CPx - base = %lx\n", __func__, cp110_base);
+
+ amb_bridge_init(cp110_base);
+
+ /* Configure PCIe clock */
+ cp110_pcie_clk_cfg(cp110_base);
+
+ /* Configure PCIe endpoint */
+ ble_plat_pcie_ep_setup();
+#endif
+}
diff --git a/drivers/marvell/thermal.c b/drivers/marvell/thermal.c
new file mode 100644
index 000000000..c7ceb9291
--- /dev/null
+++ b/drivers/marvell/thermal.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Driver for thermal unit located in Marvell ARMADA 8K and compatible SoCs */
+
+#include <debug.h>
+#include <thermal.h>
+
+int marvell_thermal_init(struct tsen_config *tsen_cfg)
+{
+ if (tsen_cfg->tsen_ready == 1) {
+ INFO("thermal sensor is already initialized\n");
+ return 0;
+ }
+
+ if (tsen_cfg->ptr_tsen_probe == NULL) {
+ ERROR("initial thermal sensor configuration is missing\n");
+ return -1;
+ }
+
+ if (tsen_cfg->ptr_tsen_probe(tsen_cfg)) {
+ ERROR("thermal sensor initialization failed\n");
+ return -1;
+ }
+
+ VERBOSE("thermal sensor was initialized\n");
+
+ return 0;
+}
+
+int marvell_thermal_read(struct tsen_config *tsen_cfg, int *temp)
+{
+ if (temp == NULL) {
+ ERROR("NULL pointer for temperature read\n");
+ return -1;
+ }
+
+ if (tsen_cfg->ptr_tsen_read == NULL ||
+ tsen_cfg->tsen_ready == 0) {
+ ERROR("thermal sensor was not initialized\n");
+ return -1;
+ }
+
+ if (tsen_cfg->ptr_tsen_read(tsen_cfg, temp)) {
+ ERROR("temperature read failed\n");
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 8fe3239e5..bf87612d5 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -9,6 +9,7 @@
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
+#include <delay_timer.h>
#include <errno.h>
#include <mmc.h>
#include <stdbool.h>
@@ -23,7 +24,7 @@
static const struct mmc_ops *ops;
static unsigned int mmc_ocr_value;
static struct mmc_csd_emmc mmc_csd;
-static unsigned char mmc_ext_csd[512] __aligned(4);
+static unsigned char mmc_ext_csd[512] __aligned(16);
static unsigned int mmc_flags;
static struct mmc_device_info *mmc_dev_info;
static unsigned int rca;
@@ -220,7 +221,7 @@ static int mmc_fill_device_info(void)
unsigned int speed_idx;
unsigned int nb_blocks;
unsigned int freq_unit;
- int ret;
+ int ret = 0;
struct mmc_csd_sd_v2 *csd_sd_v2;
switch (mmc_dev_info->mmc_dev_type) {
@@ -319,18 +320,12 @@ static int mmc_fill_device_info(void)
static int sd_send_op_cond(void)
{
- int retries = SEND_OP_COND_MAX_RETRIES;
+ int n;
unsigned int resp_data[4];
- do {
+ for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
int ret;
- if (retries == 0) {
- ERROR("ACMD41 failed after %d retries\n",
- SEND_OP_COND_MAX_RETRIES);
- return -EIO;
- }
-
/* CMD55: Application Specific Command */
ret = mmc_send_cmd(MMC_CMD(55), 0, MMC_RESPONSE_R(1), NULL);
if (ret != 0) {
@@ -344,25 +339,29 @@ static int sd_send_op_cond(void)
return ret;
}
- retries--;
- } while ((resp_data[0] & OCR_POWERUP) == 0U);
+ if ((resp_data[0] & OCR_POWERUP) != 0U) {
+ mmc_ocr_value = resp_data[0];
- mmc_ocr_value = resp_data[0];
+ if ((mmc_ocr_value & OCR_HCS) != 0U) {
+ mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
+ } else {
+ mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+ }
- if ((mmc_ocr_value & OCR_HCS) != 0U) {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD_HC;
- } else {
- mmc_dev_info->mmc_dev_type = MMC_IS_SD;
+ return 0;
+ }
+
+ mdelay(1);
}
- return 0;
+ ERROR("ACMD41 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
+
+ return -EIO;
}
-static int mmc_send_op_cond(void)
+static int mmc_reset_to_idle(void)
{
int ret;
- int retries = SEND_OP_COND_MAX_RETRIES;
- unsigned int resp_data[4];
/* CMD0: reset to IDLE */
ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
@@ -370,14 +369,19 @@ static int mmc_send_op_cond(void)
return ret;
}
- do {
- if (retries == 0) {
- ERROR("CMD1 failed after %d retries\n",
- SEND_OP_COND_MAX_RETRIES);
- return -EIO;
- }
+ mdelay(2);
+
+ return 0;
+}
- /* CMD1: get OCR register (SEND_OP_COND) */
+static int mmc_send_op_cond(void)
+{
+ int ret, n;
+ unsigned int resp_data[4];
+
+ mmc_reset_to_idle();
+
+ for (n = 0; n < SEND_OP_COND_MAX_RETRIES; n++) {
ret = mmc_send_cmd(MMC_CMD(1), OCR_SECTOR_MODE |
OCR_VDD_MIN_2V7 | OCR_VDD_MIN_1V7,
MMC_RESPONSE_R(3), &resp_data[0]);
@@ -385,12 +389,17 @@ static int mmc_send_op_cond(void)
return ret;
}
- retries--;
- } while ((resp_data[0] & OCR_POWERUP) == 0U);
+ if ((resp_data[0] & OCR_POWERUP) != 0U) {
+ mmc_ocr_value = resp_data[0];
+ return 0;
+ }
- mmc_ocr_value = resp_data[0];
+ mdelay(1);
+ }
- return 0;
+ ERROR("CMD1 failed after %d retries\n", SEND_OP_COND_MAX_RETRIES);
+
+ return -EIO;
}
static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
@@ -400,20 +409,18 @@ static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
ops->init();
- /* CMD0: reset to IDLE */
- ret = mmc_send_cmd(MMC_CMD(0), 0, 0, NULL);
- if (ret != 0) {
- return ret;
- }
-
- /* CMD8: Send Interface Condition Command */
- ret = mmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
- MMC_RESPONSE_R(7), &resp_data[0]);
+ mmc_reset_to_idle();
- if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
- ret = sd_send_op_cond();
- } else {
+ if (mmc_dev_info->mmc_dev_type == MMC_IS_EMMC) {
ret = mmc_send_op_cond();
+ } else {
+ /* CMD8: Send Interface Condition Command */
+ ret = mmc_send_cmd(MMC_CMD(8), VHS_2_7_3_6_V | CMD8_CHECK_PATTERN,
+ MMC_RESPONSE_R(7), &resp_data[0]);
+
+ if ((ret == 0) && ((resp_data[0] & 0xffU) == CMD8_CHECK_PATTERN)) {
+ ret = sd_send_op_cond();
+ }
}
if (ret != 0) {
return ret;
@@ -466,15 +473,15 @@ static int mmc_enumerate(unsigned int clk, unsigned int bus_width)
}
} while (ret != MMC_STATE_TRAN);
- ret = mmc_fill_device_info();
+ ret = mmc_set_ios(clk, bus_width);
if (ret != 0) {
return ret;
}
- return mmc_set_ios(clk, bus_width);
+ return mmc_fill_device_info();
}
-size_t mmc_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
+size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size)
{
int ret;
unsigned int cmd_idx, cmd_arg;
@@ -541,7 +548,7 @@ size_t mmc_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
return size;
}
-size_t mmc_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
+size_t mmc_write_blocks(int lba, const uintptr_t buf, size_t size)
{
int ret;
unsigned int cmd_idx, cmd_arg;
@@ -608,7 +615,7 @@ size_t mmc_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
return size;
}
-size_t mmc_erase_blocks(unsigned int lba, size_t size)
+size_t mmc_erase_blocks(int lba, size_t size)
{
int ret;
@@ -654,7 +661,7 @@ static inline void mmc_rpmb_disable(void)
PART_CFG_BOOT_PARTITION1_ENABLE);
}
-size_t mmc_rpmb_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
+size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size)
{
size_t size_read;
@@ -665,7 +672,7 @@ size_t mmc_rpmb_read_blocks(unsigned int lba, uintptr_t buf, size_t size)
return size_read;
}
-size_t mmc_rpmb_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
+size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size)
{
size_t size_written;
@@ -676,7 +683,7 @@ size_t mmc_rpmb_write_blocks(unsigned int lba, const uintptr_t buf, size_t size)
return size_written;
}
-size_t mmc_rpmb_erase_blocks(unsigned int lba, size_t size)
+size_t mmc_rpmb_erase_blocks(int lba, size_t size)
{
size_t size_erased;
diff --git a/drivers/partition/partition.c b/drivers/partition/partition.c
index e2b468363..d6fb4b8e4 100644
--- a/drivers/partition/partition.c
+++ b/drivers/partition/partition.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <mbr.h>
#include <partition.h>
#include <platform.h>
+#include <stdio.h>
#include <string.h>
static uint8_t mbr_sector[PARTITION_BLOCK_SIZE];
diff --git a/drivers/st/clk/stm32mp1_clk.c b/drivers/st/clk/stm32mp1_clk.c
new file mode 100644
index 000000000..f0bf363e2
--- /dev/null
+++ b/drivers/st/clk/stm32mp1_clk.c
@@ -0,0 +1,1612 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include <errno.h>
+#include <generic_delay_timer.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <utils_def.h>
+
+#define MAX_HSI_HZ 64000000
+
+#define TIMEOUT_200MS (plat_get_syscnt_freq2() / 5U)
+#define TIMEOUT_1S plat_get_syscnt_freq2()
+
+#define PLLRDY_TIMEOUT TIMEOUT_200MS
+#define CLKSRC_TIMEOUT TIMEOUT_200MS
+#define CLKDIV_TIMEOUT TIMEOUT_200MS
+#define HSIDIV_TIMEOUT TIMEOUT_200MS
+#define OSCRDY_TIMEOUT TIMEOUT_1S
+
+enum stm32mp1_parent_id {
+/* Oscillators are defined in enum stm32mp_osc_id */
+
+/* Other parent source */
+ _HSI_KER = NB_OSC,
+ _HSE_KER,
+ _HSE_KER_DIV2,
+ _CSI_KER,
+ _PLL1_P,
+ _PLL1_Q,
+ _PLL1_R,
+ _PLL2_P,
+ _PLL2_Q,
+ _PLL2_R,
+ _PLL3_P,
+ _PLL3_Q,
+ _PLL3_R,
+ _PLL4_P,
+ _PLL4_Q,
+ _PLL4_R,
+ _ACLK,
+ _PCLK1,
+ _PCLK2,
+ _PCLK3,
+ _PCLK4,
+ _PCLK5,
+ _HCLK6,
+ _HCLK2,
+ _CK_PER,
+ _CK_MPU,
+ _PARENT_NB,
+ _UNKNOWN_ID = 0xff,
+};
+
+enum stm32mp1_parent_sel {
+ _I2C46_SEL,
+ _UART6_SEL,
+ _UART24_SEL,
+ _UART35_SEL,
+ _UART78_SEL,
+ _SDMMC12_SEL,
+ _SDMMC3_SEL,
+ _QSPI_SEL,
+ _FMC_SEL,
+ _USBPHY_SEL,
+ _USBO_SEL,
+ _STGEN_SEL,
+ _PARENT_SEL_NB,
+ _UNKNOWN_SEL = 0xff,
+};
+
+enum stm32mp1_pll_id {
+ _PLL1,
+ _PLL2,
+ _PLL3,
+ _PLL4,
+ _PLL_NB
+};
+
+enum stm32mp1_div_id {
+ _DIV_P,
+ _DIV_Q,
+ _DIV_R,
+ _DIV_NB,
+};
+
+enum stm32mp1_clksrc_id {
+ CLKSRC_MPU,
+ CLKSRC_AXI,
+ CLKSRC_PLL12,
+ CLKSRC_PLL3,
+ CLKSRC_PLL4,
+ CLKSRC_RTC,
+ CLKSRC_MCO1,
+ CLKSRC_MCO2,
+ CLKSRC_NB
+};
+
+enum stm32mp1_clkdiv_id {
+ CLKDIV_MPU,
+ CLKDIV_AXI,
+ CLKDIV_APB1,
+ CLKDIV_APB2,
+ CLKDIV_APB3,
+ CLKDIV_APB4,
+ CLKDIV_APB5,
+ CLKDIV_RTC,
+ CLKDIV_MCO1,
+ CLKDIV_MCO2,
+ CLKDIV_NB
+};
+
+enum stm32mp1_pllcfg {
+ PLLCFG_M,
+ PLLCFG_N,
+ PLLCFG_P,
+ PLLCFG_Q,
+ PLLCFG_R,
+ PLLCFG_O,
+ PLLCFG_NB
+};
+
+enum stm32mp1_pllcsg {
+ PLLCSG_MOD_PER,
+ PLLCSG_INC_STEP,
+ PLLCSG_SSCG_MODE,
+ PLLCSG_NB
+};
+
+enum stm32mp1_plltype {
+ PLL_800,
+ PLL_1600,
+ PLL_TYPE_NB
+};
+
+struct stm32mp1_pll {
+ uint8_t refclk_min;
+ uint8_t refclk_max;
+ uint8_t divn_max;
+};
+
+struct stm32mp1_clk_gate {
+ uint16_t offset;
+ uint8_t bit;
+ uint8_t index;
+ uint8_t set_clr;
+ enum stm32mp1_parent_sel sel;
+ enum stm32mp1_parent_id fixed;
+ bool secure;
+};
+
+struct stm32mp1_clk_sel {
+ uint16_t offset;
+ uint8_t src;
+ uint8_t msk;
+ uint8_t nb_parent;
+ const uint8_t *parent;
+};
+
+#define REFCLK_SIZE 4
+struct stm32mp1_clk_pll {
+ enum stm32mp1_plltype plltype;
+ uint16_t rckxselr;
+ uint16_t pllxcfgr1;
+ uint16_t pllxcfgr2;
+ uint16_t pllxfracr;
+ uint16_t pllxcr;
+ uint16_t pllxcsgr;
+ enum stm32mp_osc_id refclk[REFCLK_SIZE];
+};
+
+struct stm32mp1_clk_data {
+ const struct stm32mp1_clk_gate *gate;
+ const struct stm32mp1_clk_sel *sel;
+ const struct stm32mp1_clk_pll *pll;
+ const int nb_gate;
+};
+
+struct stm32mp1_clk_priv {
+ uint32_t base;
+ const struct stm32mp1_clk_data *data;
+ unsigned long osc[NB_OSC];
+ uint32_t pkcs_usb_value;
+};
+
+#define STM32MP1_CLK(off, b, idx, s) \
+ { \
+ .offset = (off), \
+ .bit = (b), \
+ .index = (idx), \
+ .set_clr = 0, \
+ .sel = (s), \
+ .fixed = _UNKNOWN_ID, \
+ .secure = 0, \
+ }
+
+#define STM32MP1_CLK_F(off, b, idx, f) \
+ { \
+ .offset = (off), \
+ .bit = (b), \
+ .index = (idx), \
+ .set_clr = 0, \
+ .sel = _UNKNOWN_SEL, \
+ .fixed = (f), \
+ .secure = 0, \
+ }
+
+#define STM32MP1_CLK_SET_CLR(off, b, idx, s) \
+ { \
+ .offset = (off), \
+ .bit = (b), \
+ .index = (idx), \
+ .set_clr = 1, \
+ .sel = (s), \
+ .fixed = _UNKNOWN_ID, \
+ .secure = 0, \
+ }
+
+#define STM32MP1_CLK_SET_CLR_F(off, b, idx, f) \
+ { \
+ .offset = (off), \
+ .bit = (b), \
+ .index = (idx), \
+ .set_clr = 1, \
+ .sel = _UNKNOWN_SEL, \
+ .fixed = (f), \
+ .secure = 0, \
+ }
+
+#define STM32MP1_CLK_SEC_SET_CLR(off, b, idx, s) \
+ { \
+ .offset = (off), \
+ .bit = (b), \
+ .index = (idx), \
+ .set_clr = 1, \
+ .sel = (s), \
+ .fixed = _UNKNOWN_ID, \
+ .secure = 1, \
+ }
+
+#define STM32MP1_CLK_PARENT(idx, off, s, m, p) \
+ [(idx)] = { \
+ .offset = (off), \
+ .src = (s), \
+ .msk = (m), \
+ .parent = (p), \
+ .nb_parent = ARRAY_SIZE((p)) \
+ }
+
+#define STM32MP1_CLK_PLL(idx, type, off1, off2, off3, \
+ off4, off5, off6, \
+ p1, p2, p3, p4) \
+ [(idx)] = { \
+ .plltype = (type), \
+ .rckxselr = (off1), \
+ .pllxcfgr1 = (off2), \
+ .pllxcfgr2 = (off3), \
+ .pllxfracr = (off4), \
+ .pllxcr = (off5), \
+ .pllxcsgr = (off6), \
+ .refclk[0] = (p1), \
+ .refclk[1] = (p2), \
+ .refclk[2] = (p3), \
+ .refclk[3] = (p4), \
+ }
+
+static const uint8_t stm32mp1_clks[][2] = {
+ {CK_PER, _CK_PER},
+ {CK_MPU, _CK_MPU},
+ {CK_AXI, _ACLK},
+ {CK_HSE, _HSE},
+ {CK_CSI, _CSI},
+ {CK_LSI, _LSI},
+ {CK_LSE, _LSE},
+ {CK_HSI, _HSI},
+ {CK_HSE_DIV2, _HSE_KER_DIV2},
+};
+
+static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
+ STM32MP1_CLK(RCC_DDRITFCR, 0, DDRC1, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 1, DDRC1LP, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 2, DDRC2, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 3, DDRC2LP, _UNKNOWN_SEL),
+ STM32MP1_CLK_F(RCC_DDRITFCR, 4, DDRPHYC, _PLL2_R),
+ STM32MP1_CLK(RCC_DDRITFCR, 5, DDRPHYCLP, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 6, DDRCAPB, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 7, DDRCAPBLP, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 8, AXIDCG, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 9, DDRPHYCAPB, _UNKNOWN_SEL),
+ STM32MP1_CLK(RCC_DDRITFCR, 10, DDRPHYCAPBLP, _UNKNOWN_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 14, USART2_K, _UART24_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 15, USART3_K, _UART35_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 16, UART4_K, _UART24_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 17, UART5_K, _UART35_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 18, UART7_K, _UART78_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB1ENSETR, 19, UART8_K, _UART78_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB2ENSETR, 13, USART6_K, _UART6_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL),
+
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 2, I2C4_K, _I2C46_SEL),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 8, RTCAPB, _PCLK5),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 11, TZC1, _UNKNOWN_SEL),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 12, TZC2, _UNKNOWN_SEL),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_APB5ENSETR, 20, STGEN_K, _STGEN_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 8, USBO_K, _USBO_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB2ENSETR, 16, SDMMC3_K, _SDMMC3_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 0, GPIOA, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 1, GPIOB, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 2, GPIOC, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 3, GPIOD, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 4, GPIOE, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 5, GPIOF, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 6, GPIOG, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 7, GPIOH, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 8, GPIOI, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 9, GPIOJ, _UNKNOWN_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB4ENSETR, 10, GPIOK, _UNKNOWN_SEL),
+
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 5, HASH1, _UNKNOWN_SEL),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 6, RNG1_K, _CSI_KER),
+ STM32MP1_CLK_SEC_SET_CLR(RCC_MP_AHB5ENSETR, 8, BKPSRAM, _UNKNOWN_SEL),
+
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 12, FMC_K, _FMC_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 14, QSPI_K, _QSPI_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 16, SDMMC1_K, _SDMMC12_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 17, SDMMC2_K, _SDMMC12_SEL),
+ STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 24, USBH, _UNKNOWN_SEL),
+
+ STM32MP1_CLK(RCC_DBGCFGR, 8, CK_DBG, _UNKNOWN_SEL),
+};
+
+static const uint8_t i2c46_parents[] = {_PCLK5, _PLL3_Q, _HSI_KER, _CSI_KER};
+static const uint8_t uart6_parents[] = {_PCLK2, _PLL4_Q, _HSI_KER, _CSI_KER,
+ _HSE_KER};
+static const uint8_t uart24_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+ _HSE_KER};
+static const uint8_t uart35_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+ _HSE_KER};
+static const uint8_t uart78_parents[] = {_PCLK1, _PLL4_Q, _HSI_KER, _CSI_KER,
+ _HSE_KER};
+static const uint8_t sdmmc12_parents[] = {_HCLK6, _PLL3_R, _PLL4_P, _HSI_KER};
+static const uint8_t sdmmc3_parents[] = {_HCLK2, _PLL3_R, _PLL4_P, _HSI_KER};
+static const uint8_t qspi_parents[] = {_ACLK, _PLL3_R, _PLL4_P, _CK_PER};
+static const uint8_t fmc_parents[] = {_ACLK, _PLL3_R, _PLL4_P, _CK_PER};
+static const uint8_t usbphy_parents[] = {_HSE_KER, _PLL4_R, _HSE_KER_DIV2};
+static const uint8_t usbo_parents[] = {_PLL4_R, _USB_PHY_48};
+static const uint8_t stgen_parents[] = {_HSI_KER, _HSE_KER};
+
+static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = {
+ STM32MP1_CLK_PARENT(_I2C46_SEL, RCC_I2C46CKSELR, 0, 0x7, i2c46_parents),
+ STM32MP1_CLK_PARENT(_UART6_SEL, RCC_UART6CKSELR, 0, 0x7, uart6_parents),
+ STM32MP1_CLK_PARENT(_UART24_SEL, RCC_UART24CKSELR, 0, 0x7,
+ uart24_parents),
+ STM32MP1_CLK_PARENT(_UART35_SEL, RCC_UART35CKSELR, 0, 0x7,
+ uart35_parents),
+ STM32MP1_CLK_PARENT(_UART78_SEL, RCC_UART78CKSELR, 0, 0x7,
+ uart78_parents),
+ STM32MP1_CLK_PARENT(_SDMMC12_SEL, RCC_SDMMC12CKSELR, 0, 0x7,
+ sdmmc12_parents),
+ STM32MP1_CLK_PARENT(_SDMMC3_SEL, RCC_SDMMC3CKSELR, 0, 0x7,
+ sdmmc3_parents),
+ STM32MP1_CLK_PARENT(_QSPI_SEL, RCC_QSPICKSELR, 0, 0xf, qspi_parents),
+ STM32MP1_CLK_PARENT(_FMC_SEL, RCC_FMCCKSELR, 0, 0xf, fmc_parents),
+ STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents),
+ STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents),
+ STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents),
+};
+
+/* Define characteristic of PLL according type */
+#define DIVN_MIN 24
+static const struct stm32mp1_pll stm32mp1_pll[PLL_TYPE_NB] = {
+ [PLL_800] = {
+ .refclk_min = 4,
+ .refclk_max = 16,
+ .divn_max = 99,
+ },
+ [PLL_1600] = {
+ .refclk_min = 8,
+ .refclk_max = 16,
+ .divn_max = 199,
+ },
+};
+
+/* PLLNCFGR2 register divider by output */
+static const uint8_t pllncfgr2[_DIV_NB] = {
+ [_DIV_P] = RCC_PLLNCFGR2_DIVP_SHIFT,
+ [_DIV_Q] = RCC_PLLNCFGR2_DIVQ_SHIFT,
+ [_DIV_R] = RCC_PLLNCFGR2_DIVR_SHIFT
+};
+
+static const struct stm32mp1_clk_pll stm32mp1_clk_pll[_PLL_NB] = {
+ STM32MP1_CLK_PLL(_PLL1, PLL_1600,
+ RCC_RCK12SELR, RCC_PLL1CFGR1, RCC_PLL1CFGR2,
+ RCC_PLL1FRACR, RCC_PLL1CR, RCC_PLL1CSGR,
+ _HSI, _HSE, _UNKNOWN_OSC_ID, _UNKNOWN_OSC_ID),
+ STM32MP1_CLK_PLL(_PLL2, PLL_1600,
+ RCC_RCK12SELR, RCC_PLL2CFGR1, RCC_PLL2CFGR2,
+ RCC_PLL2FRACR, RCC_PLL2CR, RCC_PLL2CSGR,
+ _HSI, _HSE, _UNKNOWN_OSC_ID, _UNKNOWN_OSC_ID),
+ STM32MP1_CLK_PLL(_PLL3, PLL_800,
+ RCC_RCK3SELR, RCC_PLL3CFGR1, RCC_PLL3CFGR2,
+ RCC_PLL3FRACR, RCC_PLL3CR, RCC_PLL3CSGR,
+ _HSI, _HSE, _CSI, _UNKNOWN_OSC_ID),
+ STM32MP1_CLK_PLL(_PLL4, PLL_800,
+ RCC_RCK4SELR, RCC_PLL4CFGR1, RCC_PLL4CFGR2,
+ RCC_PLL4FRACR, RCC_PLL4CR, RCC_PLL4CSGR,
+ _HSI, _HSE, _CSI, _I2S_CKIN),
+};
+
+/* Prescaler table lookups for clock computation */
+
+/* div = /1 /2 /4 /8 /16 : same divider for PMU and APBX */
+#define stm32mp1_mpu_div stm32mp1_mpu_apbx_div
+#define stm32mp1_apbx_div stm32mp1_mpu_apbx_div
+static const uint8_t stm32mp1_mpu_apbx_div[8] = {
+ 0, 1, 2, 3, 4, 4, 4, 4
+};
+
+/* div = /1 /2 /3 /4 */
+static const uint8_t stm32mp1_axi_div[8] = {
+ 1, 2, 3, 4, 4, 4, 4, 4
+};
+
+static const struct stm32mp1_clk_data stm32mp1_data = {
+ .gate = stm32mp1_clk_gate,
+ .sel = stm32mp1_clk_sel,
+ .pll = stm32mp1_clk_pll,
+ .nb_gate = ARRAY_SIZE(stm32mp1_clk_gate),
+};
+
+static struct stm32mp1_clk_priv stm32mp1_clk_priv_data;
+
+static unsigned long stm32mp1_clk_get_fixed(struct stm32mp1_clk_priv *priv,
+ enum stm32mp_osc_id idx)
+{
+ if (idx >= NB_OSC) {
+ return 0;
+ }
+
+ return priv->osc[idx];
+}
+
+static int stm32mp1_clk_get_id(struct stm32mp1_clk_priv *priv, unsigned long id)
+{
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+ int i;
+ int nb_clks = priv->data->nb_gate;
+
+ for (i = 0; i < nb_clks; i++) {
+ if (gate[i].index == id) {
+ return i;
+ }
+ }
+
+ ERROR("%s: clk id %d not found\n", __func__, (uint32_t)id);
+
+ return -EINVAL;
+}
+
+static enum stm32mp1_parent_sel
+stm32mp1_clk_get_sel(struct stm32mp1_clk_priv *priv, int i)
+{
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+
+ return gate[i].sel;
+}
+
+static enum stm32mp1_parent_id
+stm32mp1_clk_get_fixed_parent(struct stm32mp1_clk_priv *priv, int i)
+{
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+
+ return gate[i].fixed;
+}
+
+static int stm32mp1_clk_get_parent(struct stm32mp1_clk_priv *priv,
+ unsigned long id)
+{
+ const struct stm32mp1_clk_sel *sel = priv->data->sel;
+ uint32_t j, p_sel;
+ int i;
+ enum stm32mp1_parent_id p;
+ enum stm32mp1_parent_sel s;
+
+ for (j = 0; j < ARRAY_SIZE(stm32mp1_clks); j++) {
+ if (stm32mp1_clks[j][0] == id) {
+ return (int)stm32mp1_clks[j][1];
+ }
+ }
+
+ i = stm32mp1_clk_get_id(priv, id);
+ if (i < 0) {
+ return i;
+ }
+
+ p = stm32mp1_clk_get_fixed_parent(priv, i);
+ if (p < _PARENT_NB) {
+ return (int)p;
+ }
+
+ s = stm32mp1_clk_get_sel(priv, i);
+ if (s >= _PARENT_SEL_NB) {
+ return -EINVAL;
+ }
+
+ p_sel = (mmio_read_32(priv->base + sel[s].offset) >> sel[s].src) &
+ sel[s].msk;
+
+ if (p_sel < sel[s].nb_parent) {
+ return (int)sel[s].parent[p_sel];
+ }
+
+ ERROR("%s: no parents defined for clk id %ld\n", __func__, id);
+
+ return -EINVAL;
+}
+
+static unsigned long stm32mp1_pll_get_fref_ck(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t selr, src;
+ unsigned long refclk;
+
+ selr = mmio_read_32(priv->base + pll[pll_id].rckxselr);
+ src = selr & RCC_SELR_REFCLK_SRC_MASK;
+
+ refclk = stm32mp1_clk_get_fixed(priv, pll[pll_id].refclk[src]);
+
+ return refclk;
+}
+
+/*
+ * pll_get_fvco() : return the VCO or (VCO / 2) frequency for the requested PLL
+ * - PLL1 & PLL2 => return VCO / 2 with Fpll_y_ck = FVCO / 2 * (DIVy + 1)
+ * - PLL3 & PLL4 => return VCO with Fpll_y_ck = FVCO / (DIVy + 1)
+ * => in all cases Fpll_y_ck = pll_get_fvco() / (DIVy + 1)
+ */
+static unsigned long stm32mp1_pll_get_fvco(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ unsigned long refclk, fvco;
+ uint32_t cfgr1, fracr, divm, divn;
+
+ cfgr1 = mmio_read_32(priv->base + pll[pll_id].pllxcfgr1);
+ fracr = mmio_read_32(priv->base + pll[pll_id].pllxfracr);
+
+ divm = (cfgr1 & (RCC_PLLNCFGR1_DIVM_MASK)) >> RCC_PLLNCFGR1_DIVM_SHIFT;
+ divn = cfgr1 & RCC_PLLNCFGR1_DIVN_MASK;
+
+ refclk = stm32mp1_pll_get_fref_ck(priv, pll_id);
+
+ /*
+ * With FRACV :
+ * Fvco = Fck_ref * ((DIVN + 1) + FRACV / 2^13) / (DIVM + 1)
+ * Without FRACV
+ * Fvco = Fck_ref * ((DIVN + 1) / (DIVM + 1)
+ */
+ if ((fracr & RCC_PLLNFRACR_FRACLE) != 0U) {
+ uint32_t fracv = (fracr & RCC_PLLNFRACR_FRACV_MASK)
+ >> RCC_PLLNFRACR_FRACV_SHIFT;
+ unsigned long long numerator, denominator;
+
+ numerator = ((unsigned long long)divn + 1U) << 13;
+ numerator = (refclk * numerator) + fracv;
+ denominator = ((unsigned long long)divm + 1U) << 13;
+ fvco = (unsigned long)(numerator / denominator);
+ } else {
+ fvco = (unsigned long)(refclk * (divn + 1U) / (divm + 1U));
+ }
+
+ return fvco;
+}
+
+static unsigned long stm32mp1_read_pll_freq(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id,
+ enum stm32mp1_div_id div_id)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ unsigned long dfout;
+ uint32_t cfgr2, divy;
+
+ if (div_id >= _DIV_NB) {
+ return 0;
+ }
+
+ cfgr2 = mmio_read_32(priv->base + pll[pll_id].pllxcfgr2);
+ divy = (cfgr2 >> pllncfgr2[div_id]) & RCC_PLLNCFGR2_DIVX_MASK;
+
+ dfout = stm32mp1_pll_get_fvco(priv, pll_id) / (divy + 1U);
+
+ return dfout;
+}
+
+static unsigned long stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p)
+{
+ uint32_t reg, clkdiv;
+ unsigned long clock = 0;
+
+ switch (p) {
+ case _CK_MPU:
+ /* MPU sub system */
+ reg = mmio_read_32(priv->base + RCC_MPCKSELR);
+ switch (reg & RCC_SELR_SRC_MASK) {
+ case RCC_MPCKSELR_HSI:
+ clock = stm32mp1_clk_get_fixed(priv, _HSI);
+ break;
+ case RCC_MPCKSELR_HSE:
+ clock = stm32mp1_clk_get_fixed(priv, _HSE);
+ break;
+ case RCC_MPCKSELR_PLL:
+ clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+ break;
+ case RCC_MPCKSELR_PLL_MPUDIV:
+ clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+
+ reg = mmio_read_32(priv->base + RCC_MPCKDIVR);
+ clkdiv = reg & RCC_MPUDIV_MASK;
+ if (clkdiv != 0U) {
+ clock /= stm32mp1_mpu_div[clkdiv];
+ }
+
+ break;
+ default:
+ break;
+ }
+ break;
+ /* AXI sub system */
+ case _ACLK:
+ case _HCLK2:
+ case _HCLK6:
+ case _PCLK4:
+ case _PCLK5:
+ reg = mmio_read_32(priv->base + RCC_ASSCKSELR);
+ switch (reg & RCC_SELR_SRC_MASK) {
+ case RCC_ASSCKSELR_HSI:
+ clock = stm32mp1_clk_get_fixed(priv, _HSI);
+ break;
+ case RCC_ASSCKSELR_HSE:
+ clock = stm32mp1_clk_get_fixed(priv, _HSE);
+ break;
+ case RCC_ASSCKSELR_PLL:
+ clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_P);
+ break;
+ default:
+ break;
+ }
+
+ /* System clock divider */
+ reg = mmio_read_32(priv->base + RCC_AXIDIVR);
+ clock /= stm32mp1_axi_div[reg & RCC_AXIDIV_MASK];
+
+ switch (p) {
+ case _PCLK4:
+ reg = mmio_read_32(priv->base + RCC_APB4DIVR);
+ clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
+ break;
+ case _PCLK5:
+ reg = mmio_read_32(priv->base + RCC_APB5DIVR);
+ clock >>= stm32mp1_apbx_div[reg & RCC_APBXDIV_MASK];
+ break;
+ default:
+ break;
+ }
+ break;
+ case _CK_PER:
+ reg = mmio_read_32(priv->base + RCC_CPERCKSELR);
+ switch (reg & RCC_SELR_SRC_MASK) {
+ case RCC_CPERCKSELR_HSI:
+ clock = stm32mp1_clk_get_fixed(priv, _HSI);
+ break;
+ case RCC_CPERCKSELR_HSE:
+ clock = stm32mp1_clk_get_fixed(priv, _HSE);
+ break;
+ case RCC_CPERCKSELR_CSI:
+ clock = stm32mp1_clk_get_fixed(priv, _CSI);
+ break;
+ default:
+ break;
+ }
+ break;
+ case _HSI:
+ case _HSI_KER:
+ clock = stm32mp1_clk_get_fixed(priv, _HSI);
+ break;
+ case _CSI:
+ case _CSI_KER:
+ clock = stm32mp1_clk_get_fixed(priv, _CSI);
+ break;
+ case _HSE:
+ case _HSE_KER:
+ clock = stm32mp1_clk_get_fixed(priv, _HSE);
+ break;
+ case _HSE_KER_DIV2:
+ clock = stm32mp1_clk_get_fixed(priv, _HSE) >> 1;
+ break;
+ case _LSI:
+ clock = stm32mp1_clk_get_fixed(priv, _LSI);
+ break;
+ case _LSE:
+ clock = stm32mp1_clk_get_fixed(priv, _LSE);
+ break;
+ /* PLL */
+ case _PLL1_P:
+ clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_P);
+ break;
+ case _PLL1_Q:
+ clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_Q);
+ break;
+ case _PLL1_R:
+ clock = stm32mp1_read_pll_freq(priv, _PLL1, _DIV_R);
+ break;
+ case _PLL2_P:
+ clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_P);
+ break;
+ case _PLL2_Q:
+ clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_Q);
+ break;
+ case _PLL2_R:
+ clock = stm32mp1_read_pll_freq(priv, _PLL2, _DIV_R);
+ break;
+ case _PLL3_P:
+ clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_P);
+ break;
+ case _PLL3_Q:
+ clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_Q);
+ break;
+ case _PLL3_R:
+ clock = stm32mp1_read_pll_freq(priv, _PLL3, _DIV_R);
+ break;
+ case _PLL4_P:
+ clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_P);
+ break;
+ case _PLL4_Q:
+ clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_Q);
+ break;
+ case _PLL4_R:
+ clock = stm32mp1_read_pll_freq(priv, _PLL4, _DIV_R);
+ break;
+ /* Other */
+ case _USB_PHY_48:
+ clock = stm32mp1_clk_get_fixed(priv, _USB_PHY_48);
+ break;
+ default:
+ break;
+ }
+
+ return clock;
+}
+
+bool stm32mp1_clk_is_enabled(unsigned long id)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+ int i = stm32mp1_clk_get_id(priv, id);
+
+ if (i < 0) {
+ return false;
+ }
+
+ return ((mmio_read_32(priv->base + gate[i].offset) &
+ BIT(gate[i].bit)) != 0U);
+}
+
+int stm32mp1_clk_enable(unsigned long id)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+ int i = stm32mp1_clk_get_id(priv, id);
+
+ if (i < 0) {
+ return i;
+ }
+
+ if (gate[i].set_clr != 0U) {
+ mmio_write_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+ } else {
+ mmio_setbits_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+ }
+
+ return 0;
+}
+
+int stm32mp1_clk_disable(unsigned long id)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ const struct stm32mp1_clk_gate *gate = priv->data->gate;
+ int i = stm32mp1_clk_get_id(priv, id);
+
+ if (i < 0) {
+ return i;
+ }
+
+ if (gate[i].set_clr != 0U) {
+ mmio_write_32(priv->base + gate[i].offset
+ + RCC_MP_ENCLRR_OFFSET,
+ BIT(gate[i].bit));
+ } else {
+ mmio_clrbits_32(priv->base + gate[i].offset, BIT(gate[i].bit));
+ }
+
+ return 0;
+}
+
+unsigned long stm32mp1_clk_get_rate(unsigned long id)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ int p = stm32mp1_clk_get_parent(priv, id);
+ unsigned long rate;
+
+ if (p < 0) {
+ return 0;
+ }
+
+ rate = stm32mp1_clk_get(priv, p);
+
+ return rate;
+}
+
+static void stm32mp1_ls_osc_set(int enable, uint32_t rcc, uint32_t offset,
+ uint32_t mask_on)
+{
+ uint32_t address = rcc + offset;
+
+ if (enable != 0) {
+ mmio_setbits_32(address, mask_on);
+ } else {
+ mmio_clrbits_32(address, mask_on);
+ }
+}
+
+static void stm32mp1_hs_ocs_set(int enable, uint32_t rcc, uint32_t mask_on)
+{
+ if (enable != 0) {
+ mmio_setbits_32(rcc + RCC_OCENSETR, mask_on);
+ } else {
+ mmio_setbits_32(rcc + RCC_OCENCLRR, mask_on);
+ }
+}
+
+static int stm32mp1_osc_wait(int enable, uint32_t rcc, uint32_t offset,
+ uint32_t mask_rdy)
+{
+ unsigned long start;
+ uint32_t mask_test;
+ uint32_t address = rcc + offset;
+
+ if (enable != 0) {
+ mask_test = mask_rdy;
+ } else {
+ mask_test = 0;
+ }
+
+ start = get_timer(0);
+ while ((mmio_read_32(address) & mask_rdy) != mask_test) {
+ if (get_timer(start) > OSCRDY_TIMEOUT) {
+ ERROR("OSC %x @ %x timeout for enable=%d : 0x%x\n",
+ mask_rdy, address, enable, mmio_read_32(address));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static void stm32mp1_lse_enable(uint32_t rcc, bool bypass, uint32_t lsedrv)
+{
+ uint32_t value;
+
+ if (bypass) {
+ mmio_setbits_32(rcc + RCC_BDCR, RCC_BDCR_LSEBYP);
+ }
+
+ /*
+ * Warning: not recommended to switch directly from "high drive"
+ * to "medium low drive", and vice-versa.
+ */
+ value = (mmio_read_32(rcc + RCC_BDCR) & RCC_BDCR_LSEDRV_MASK) >>
+ RCC_BDCR_LSEDRV_SHIFT;
+
+ while (value != lsedrv) {
+ if (value > lsedrv) {
+ value--;
+ } else {
+ value++;
+ }
+
+ mmio_clrsetbits_32(rcc + RCC_BDCR,
+ RCC_BDCR_LSEDRV_MASK,
+ value << RCC_BDCR_LSEDRV_SHIFT);
+ }
+
+ stm32mp1_ls_osc_set(1, rcc, RCC_BDCR, RCC_BDCR_LSEON);
+}
+
+static void stm32mp1_lse_wait(uint32_t rcc)
+{
+ if (stm32mp1_osc_wait(1, rcc, RCC_BDCR, RCC_BDCR_LSERDY) != 0) {
+ VERBOSE("%s: failed\n", __func__);
+ }
+}
+
+static void stm32mp1_lsi_set(uint32_t rcc, int enable)
+{
+ stm32mp1_ls_osc_set(enable, rcc, RCC_RDLSICR, RCC_RDLSICR_LSION);
+ if (stm32mp1_osc_wait(enable, rcc, RCC_RDLSICR, RCC_RDLSICR_LSIRDY) !=
+ 0) {
+ VERBOSE("%s: failed\n", __func__);
+ }
+}
+
+static void stm32mp1_hse_enable(uint32_t rcc, bool bypass, bool css)
+{
+ if (bypass) {
+ mmio_setbits_32(rcc + RCC_OCENSETR, RCC_OCENR_HSEBYP);
+ }
+
+ stm32mp1_hs_ocs_set(1, rcc, RCC_OCENR_HSEON);
+ if (stm32mp1_osc_wait(1, rcc, RCC_OCRDYR, RCC_OCRDYR_HSERDY) !=
+ 0) {
+ VERBOSE("%s: failed\n", __func__);
+ }
+
+ if (css) {
+ mmio_setbits_32(rcc + RCC_OCENSETR, RCC_OCENR_HSECSSON);
+ }
+}
+
+static void stm32mp1_csi_set(uint32_t rcc, int enable)
+{
+ stm32mp1_ls_osc_set(enable, rcc, RCC_OCENSETR, RCC_OCENR_CSION);
+ if (stm32mp1_osc_wait(enable, rcc, RCC_OCRDYR, RCC_OCRDYR_CSIRDY) !=
+ 0) {
+ VERBOSE("%s: failed\n", __func__);
+ }
+}
+
+static void stm32mp1_hsi_set(uint32_t rcc, int enable)
+{
+ stm32mp1_hs_ocs_set(enable, rcc, RCC_OCENR_HSION);
+ if (stm32mp1_osc_wait(enable, rcc, RCC_OCRDYR, RCC_OCRDYR_HSIRDY) !=
+ 0) {
+ VERBOSE("%s: failed\n", __func__);
+ }
+}
+
+static int stm32mp1_set_hsidiv(uint32_t rcc, uint8_t hsidiv)
+{
+ unsigned long start;
+ uint32_t address = rcc + RCC_OCRDYR;
+
+ mmio_clrsetbits_32(rcc + RCC_HSICFGR,
+ RCC_HSICFGR_HSIDIV_MASK,
+ RCC_HSICFGR_HSIDIV_MASK & (uint32_t)hsidiv);
+
+ start = get_timer(0);
+ while ((mmio_read_32(address) & RCC_OCRDYR_HSIDIVRDY) == 0U) {
+ if (get_timer(start) > HSIDIV_TIMEOUT) {
+ ERROR("HSIDIV failed @ 0x%x: 0x%x\n",
+ address, mmio_read_32(address));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32mp1_hsidiv(uint32_t rcc, unsigned long hsifreq)
+{
+ uint8_t hsidiv;
+ uint32_t hsidivfreq = MAX_HSI_HZ;
+
+ for (hsidiv = 0; hsidiv < 4U; hsidiv++) {
+ if (hsidivfreq == hsifreq) {
+ break;
+ }
+
+ hsidivfreq /= 2U;
+ }
+
+ if (hsidiv == 4U) {
+ ERROR("Invalid clk-hsi frequency\n");
+ return -1;
+ }
+
+ if (hsidiv != 0U) {
+ return stm32mp1_set_hsidiv(rcc, hsidiv);
+ }
+
+ return 0;
+}
+
+static void stm32mp1_pll_start(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+
+ mmio_write_32(priv->base + pll[pll_id].pllxcr, RCC_PLLNCR_PLLON);
+}
+
+static int stm32mp1_pll_output(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id, uint32_t output)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t pllxcr = priv->base + pll[pll_id].pllxcr;
+ unsigned long start;
+
+ start = get_timer(0);
+ /* Wait PLL lock */
+ while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) == 0U) {
+ if (get_timer(start) > PLLRDY_TIMEOUT) {
+ ERROR("PLL%d start failed @ 0x%x: 0x%x\n",
+ pll_id, pllxcr, mmio_read_32(pllxcr));
+ return -ETIMEDOUT;
+ }
+ }
+
+ /* Start the requested output */
+ mmio_setbits_32(pllxcr, output << RCC_PLLNCR_DIVEN_SHIFT);
+
+ return 0;
+}
+
+static int stm32mp1_pll_stop(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t pllxcr = priv->base + pll[pll_id].pllxcr;
+ unsigned long start;
+
+ /* Stop all output */
+ mmio_clrbits_32(pllxcr, RCC_PLLNCR_DIVPEN | RCC_PLLNCR_DIVQEN |
+ RCC_PLLNCR_DIVREN);
+
+ /* Stop PLL */
+ mmio_clrbits_32(pllxcr, RCC_PLLNCR_PLLON);
+
+ start = get_timer(0);
+ /* Wait PLL stopped */
+ while ((mmio_read_32(pllxcr) & RCC_PLLNCR_PLLRDY) != 0U) {
+ if (get_timer(start) > PLLRDY_TIMEOUT) {
+ ERROR("PLL%d stop failed @ 0x%x: 0x%x\n",
+ pll_id, pllxcr, mmio_read_32(pllxcr));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static void stm32mp1_pll_config_output(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id,
+ uint32_t *pllcfg)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t rcc = priv->base;
+ uint32_t value;
+
+ value = (pllcfg[PLLCFG_P] << RCC_PLLNCFGR2_DIVP_SHIFT) &
+ RCC_PLLNCFGR2_DIVP_MASK;
+ value |= (pllcfg[PLLCFG_Q] << RCC_PLLNCFGR2_DIVQ_SHIFT) &
+ RCC_PLLNCFGR2_DIVQ_MASK;
+ value |= (pllcfg[PLLCFG_R] << RCC_PLLNCFGR2_DIVR_SHIFT) &
+ RCC_PLLNCFGR2_DIVR_MASK;
+ mmio_write_32(rcc + pll[pll_id].pllxcfgr2, value);
+}
+
+static int stm32mp1_pll_config(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id,
+ uint32_t *pllcfg, uint32_t fracv)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t rcc = priv->base;
+ enum stm32mp1_plltype type = pll[pll_id].plltype;
+ unsigned long refclk;
+ uint32_t ifrge = 0;
+ uint32_t src, value;
+
+ src = mmio_read_32(priv->base + pll[pll_id].rckxselr) &
+ RCC_SELR_REFCLK_SRC_MASK;
+
+ refclk = stm32mp1_clk_get_fixed(priv, pll[pll_id].refclk[src]) /
+ (pllcfg[PLLCFG_M] + 1U);
+
+ if ((refclk < (stm32mp1_pll[type].refclk_min * 1000000U)) ||
+ (refclk > (stm32mp1_pll[type].refclk_max * 1000000U))) {
+ return -EINVAL;
+ }
+
+ if ((type == PLL_800) && (refclk >= 8000000U)) {
+ ifrge = 1U;
+ }
+
+ value = (pllcfg[PLLCFG_N] << RCC_PLLNCFGR1_DIVN_SHIFT) &
+ RCC_PLLNCFGR1_DIVN_MASK;
+ value |= (pllcfg[PLLCFG_M] << RCC_PLLNCFGR1_DIVM_SHIFT) &
+ RCC_PLLNCFGR1_DIVM_MASK;
+ value |= (ifrge << RCC_PLLNCFGR1_IFRGE_SHIFT) &
+ RCC_PLLNCFGR1_IFRGE_MASK;
+ mmio_write_32(rcc + pll[pll_id].pllxcfgr1, value);
+
+ /* Fractional configuration */
+ value = 0;
+ mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+ value = fracv << RCC_PLLNFRACR_FRACV_SHIFT;
+ mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+ value |= RCC_PLLNFRACR_FRACLE;
+ mmio_write_32(rcc + pll[pll_id].pllxfracr, value);
+
+ stm32mp1_pll_config_output(priv, pll_id, pllcfg);
+
+ return 0;
+}
+
+static void stm32mp1_pll_csg(struct stm32mp1_clk_priv *priv,
+ enum stm32mp1_pll_id pll_id,
+ uint32_t *csg)
+{
+ const struct stm32mp1_clk_pll *pll = priv->data->pll;
+ uint32_t pllxcsg = 0;
+
+ pllxcsg |= (csg[PLLCSG_MOD_PER] << RCC_PLLNCSGR_MOD_PER_SHIFT) &
+ RCC_PLLNCSGR_MOD_PER_MASK;
+
+ pllxcsg |= (csg[PLLCSG_INC_STEP] << RCC_PLLNCSGR_INC_STEP_SHIFT) &
+ RCC_PLLNCSGR_INC_STEP_MASK;
+
+ pllxcsg |= (csg[PLLCSG_SSCG_MODE] << RCC_PLLNCSGR_SSCG_MODE_SHIFT) &
+ RCC_PLLNCSGR_SSCG_MODE_MASK;
+
+ mmio_write_32(priv->base + pll[pll_id].pllxcsgr, pllxcsg);
+}
+
+static int stm32mp1_set_clksrc(struct stm32mp1_clk_priv *priv,
+ unsigned int clksrc)
+{
+ uint32_t address = priv->base + (clksrc >> 4);
+ unsigned long start;
+
+ mmio_clrsetbits_32(address, RCC_SELR_SRC_MASK,
+ clksrc & RCC_SELR_SRC_MASK);
+
+ start = get_timer(0);
+ while ((mmio_read_32(address) & RCC_SELR_SRCRDY) == 0U) {
+ if (get_timer(start) > CLKSRC_TIMEOUT) {
+ ERROR("CLKSRC %x start failed @ 0x%x: 0x%x\n",
+ clksrc, address, mmio_read_32(address));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32mp1_set_clkdiv(unsigned int clkdiv, uint32_t address)
+{
+ unsigned long start;
+
+ mmio_clrsetbits_32(address, RCC_DIVR_DIV_MASK,
+ clkdiv & RCC_DIVR_DIV_MASK);
+
+ start = get_timer(0);
+ while ((mmio_read_32(address) & RCC_DIVR_DIVRDY) == 0U) {
+ if (get_timer(start) > CLKDIV_TIMEOUT) {
+ ERROR("CLKDIV %x start failed @ 0x%x: 0x%x\n",
+ clkdiv, address, mmio_read_32(address));
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static void stm32mp1_mco_csg(struct stm32mp1_clk_priv *priv,
+ uint32_t clksrc, uint32_t clkdiv)
+{
+ uint32_t address = priv->base + (clksrc >> 4);
+
+ /*
+ * Binding clksrc :
+ * bit15-4 offset
+ * bit3: disable
+ * bit2-0: MCOSEL[2:0]
+ */
+ if ((clksrc & 0x8U) != 0U) {
+ mmio_clrbits_32(address, RCC_MCOCFG_MCOON);
+ } else {
+ mmio_clrsetbits_32(address,
+ RCC_MCOCFG_MCOSRC_MASK,
+ clksrc & RCC_MCOCFG_MCOSRC_MASK);
+ mmio_clrsetbits_32(address,
+ RCC_MCOCFG_MCODIV_MASK,
+ clkdiv << RCC_MCOCFG_MCODIV_SHIFT);
+ mmio_setbits_32(address, RCC_MCOCFG_MCOON);
+ }
+}
+
+static void stm32mp1_set_rtcsrc(struct stm32mp1_clk_priv *priv,
+ unsigned int clksrc, bool lse_css)
+{
+ uint32_t address = priv->base + RCC_BDCR;
+
+ if (((mmio_read_32(address) & RCC_BDCR_RTCCKEN) == 0U) ||
+ (clksrc != (uint32_t)CLK_RTC_DISABLED)) {
+ mmio_clrsetbits_32(address,
+ RCC_BDCR_RTCSRC_MASK,
+ clksrc << RCC_BDCR_RTCSRC_SHIFT);
+
+ mmio_setbits_32(address, RCC_BDCR_RTCCKEN);
+ }
+
+ if (lse_css) {
+ mmio_setbits_32(address, RCC_BDCR_LSECSSON);
+ }
+}
+
+#define CNTCVL_OFF 0x008
+#define CNTCVU_OFF 0x00C
+
+static void stm32mp1_stgen_config(struct stm32mp1_clk_priv *priv)
+{
+ uintptr_t stgen;
+ int p;
+ uint32_t cntfid0;
+ unsigned long rate;
+
+ stgen = fdt_get_stgen_base();
+
+ cntfid0 = mmio_read_32(stgen + CNTFID_OFF);
+ p = stm32mp1_clk_get_parent(priv, STGEN_K);
+ rate = stm32mp1_clk_get(priv, p);
+
+ if (cntfid0 != rate) {
+ unsigned long long counter;
+
+ mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+ counter = (unsigned long long)
+ mmio_read_32(stgen + CNTCVL_OFF);
+ counter |= ((unsigned long long)
+ (mmio_read_32(stgen + CNTCVU_OFF))) << 32;
+ counter = (counter * rate / cntfid0);
+ mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)counter);
+ mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(counter >> 32));
+ mmio_write_32(stgen + CNTFID_OFF, rate);
+ mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+
+ write_cntfrq((u_register_t)rate);
+
+ /* Need to update timer with new frequency */
+ generic_delay_timer_init();
+ }
+}
+
+void stm32mp1_stgen_increment(unsigned long long offset_in_ms)
+{
+ uintptr_t stgen;
+ unsigned long long cnt;
+
+ stgen = fdt_get_stgen_base();
+
+ cnt = ((unsigned long long)mmio_read_32(stgen + CNTCVU_OFF) << 32) |
+ mmio_read_32(stgen + CNTCVL_OFF);
+
+ cnt += (offset_in_ms * mmio_read_32(stgen + CNTFID_OFF)) / 1000U;
+
+ mmio_clrbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+ mmio_write_32(stgen + CNTCVL_OFF, (uint32_t)cnt);
+ mmio_write_32(stgen + CNTCVU_OFF, (uint32_t)(cnt >> 32));
+ mmio_setbits_32(stgen + CNTCR_OFF, CNTCR_EN);
+}
+
+static void stm32mp1_pkcs_config(struct stm32mp1_clk_priv *priv, uint32_t pkcs)
+{
+ uint32_t address = priv->base + ((pkcs >> 4) & 0xFFFU);
+ uint32_t value = pkcs & 0xFU;
+ uint32_t mask = 0xFU;
+
+ if ((pkcs & BIT(31)) != 0U) {
+ mask <<= 4;
+ value <<= 4;
+ }
+
+ mmio_clrsetbits_32(address, mask, value);
+}
+
+int stm32mp1_clk_init(void)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ uint32_t rcc = priv->base;
+ unsigned int clksrc[CLKSRC_NB];
+ unsigned int clkdiv[CLKDIV_NB];
+ unsigned int pllcfg[_PLL_NB][PLLCFG_NB];
+ int plloff[_PLL_NB];
+ int ret, len;
+ enum stm32mp1_pll_id i;
+ bool lse_css = false;
+ const uint32_t *pkcs_cell;
+
+ /* Check status field to disable security */
+ if (!fdt_get_rcc_secure_status()) {
+ mmio_write_32(rcc + RCC_TZCR, 0);
+ }
+
+ ret = fdt_rcc_read_uint32_array("st,clksrc", clksrc,
+ (uint32_t)CLKSRC_NB);
+ if (ret < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ ret = fdt_rcc_read_uint32_array("st,clkdiv", clkdiv,
+ (uint32_t)CLKDIV_NB);
+ if (ret < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+ char name[12];
+
+ snprintf(name, sizeof(name), "st,pll@%d", i);
+ plloff[i] = fdt_rcc_subnode_offset(name);
+
+ if (!fdt_check_node(plloff[i])) {
+ continue;
+ }
+
+ ret = fdt_read_uint32_array(plloff[i], "cfg",
+ pllcfg[i], (int)PLLCFG_NB);
+ if (ret < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+ }
+
+ stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO1], clkdiv[CLKDIV_MCO1]);
+ stm32mp1_mco_csg(priv, clksrc[CLKSRC_MCO2], clkdiv[CLKDIV_MCO2]);
+
+ /*
+ * Switch ON oscillator found in device-tree.
+ * Note: HSI already ON after BootROM stage.
+ */
+ if (priv->osc[_LSI] != 0U) {
+ stm32mp1_lsi_set(rcc, 1);
+ }
+ if (priv->osc[_LSE] != 0U) {
+ bool bypass;
+ uint32_t lsedrv;
+
+ bypass = fdt_osc_read_bool(_LSE, "st,bypass");
+ lse_css = fdt_osc_read_bool(_LSE, "st,css");
+ lsedrv = fdt_osc_read_uint32_default(_LSE, "st,drive",
+ LSEDRV_MEDIUM_HIGH);
+ stm32mp1_lse_enable(rcc, bypass, lsedrv);
+ }
+ if (priv->osc[_HSE] != 0U) {
+ bool bypass, css;
+
+ bypass = fdt_osc_read_bool(_LSE, "st,bypass");
+ css = fdt_osc_read_bool(_LSE, "st,css");
+ stm32mp1_hse_enable(rcc, bypass, css);
+ }
+ /*
+ * CSI is mandatory for automatic I/O compensation (SYSCFG_CMPCR)
+ * => switch on CSI even if node is not present in device tree
+ */
+ stm32mp1_csi_set(rcc, 1);
+
+ /* Come back to HSI */
+ ret = stm32mp1_set_clksrc(priv, CLK_MPU_HSI);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clksrc(priv, CLK_AXI_HSI);
+ if (ret != 0) {
+ return ret;
+ }
+
+ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+ if (i == _PLL4)
+ continue;
+ ret = stm32mp1_pll_stop(priv, i);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ /* Configure HSIDIV */
+ if (priv->osc[_HSI] != 0U) {
+ ret = stm32mp1_hsidiv(rcc, priv->osc[_HSI]);
+ if (ret != 0) {
+ return ret;
+ }
+ stm32mp1_stgen_config(priv);
+ }
+
+ /* Select DIV */
+ /* No ready bit when MPUSRC != CLK_MPU_PLL1P_DIV, MPUDIV is disabled */
+ mmio_write_32(rcc + RCC_MPCKDIVR,
+ clkdiv[CLKDIV_MPU] & RCC_DIVR_DIV_MASK);
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_AXI], rcc + RCC_AXIDIVR);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB4], rcc + RCC_APB4DIVR);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB5], rcc + RCC_APB5DIVR);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB1], rcc + RCC_APB1DIVR);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB2], rcc + RCC_APB2DIVR);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clkdiv(clkdiv[CLKDIV_APB3], rcc + RCC_APB3DIVR);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* No ready bit for RTC */
+ mmio_write_32(rcc + RCC_RTCDIVR,
+ clkdiv[CLKDIV_RTC] & RCC_DIVR_DIV_MASK);
+
+ /* Configure PLLs source */
+ ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL12]);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL3]);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_PLL4]);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Configure and start PLLs */
+ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+ uint32_t fracv;
+ uint32_t csg[PLLCSG_NB];
+
+ if (!fdt_check_node(plloff[i])) {
+ continue;
+ }
+
+ fracv = fdt_read_uint32_default(plloff[i], "frac", 0);
+
+ ret = stm32mp1_pll_config(priv, i, pllcfg[i], fracv);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = fdt_read_uint32_array(plloff[i], "csg", csg,
+ (uint32_t)PLLCSG_NB);
+ if (ret == 0) {
+ stm32mp1_pll_csg(priv, i, csg);
+ } else if (ret != -FDT_ERR_NOTFOUND) {
+ return ret;
+ }
+
+ stm32mp1_pll_start(priv, i);
+ }
+ /* Wait and start PLLs ouptut when ready */
+ for (i = (enum stm32mp1_pll_id)0; i < _PLL_NB; i++) {
+ if (!fdt_check_node(plloff[i])) {
+ continue;
+ }
+
+ ret = stm32mp1_pll_output(priv, i, pllcfg[i][PLLCFG_O]);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+ /* Wait LSE ready before to use it */
+ if (priv->osc[_LSE] != 0U) {
+ stm32mp1_lse_wait(rcc);
+ }
+
+ /* Configure with expected clock source */
+ ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_MPU]);
+ if (ret != 0) {
+ return ret;
+ }
+ ret = stm32mp1_set_clksrc(priv, clksrc[CLKSRC_AXI]);
+ if (ret != 0) {
+ return ret;
+ }
+ stm32mp1_set_rtcsrc(priv, clksrc[CLKSRC_RTC], lse_css);
+
+ /* Configure PKCK */
+ pkcs_cell = fdt_rcc_read_prop("st,pkcs", &len);
+ if (pkcs_cell != NULL) {
+ bool ckper_disabled = false;
+ uint32_t j;
+
+ priv->pkcs_usb_value = 0;
+
+ for (j = 0; j < ((uint32_t)len / sizeof(uint32_t)); j++) {
+ uint32_t pkcs = (uint32_t)fdt32_to_cpu(pkcs_cell[j]);
+
+ if (pkcs == (uint32_t)CLK_CKPER_DISABLED) {
+ ckper_disabled = true;
+ continue;
+ }
+ stm32mp1_pkcs_config(priv, pkcs);
+ }
+
+ /*
+ * CKPER is source for some peripheral clocks
+ * (FMC-NAND / QPSI-NOR) and switching source is allowed
+ * only if previous clock is still ON
+ * => deactivated CKPER only after switching clock
+ */
+ if (ckper_disabled) {
+ stm32mp1_pkcs_config(priv, CLK_CKPER_DISABLED);
+ }
+ }
+
+ /* Switch OFF HSI if not found in device-tree */
+ if (priv->osc[_HSI] == 0U) {
+ stm32mp1_hsi_set(rcc, 0);
+ }
+ stm32mp1_stgen_config(priv);
+
+ /* Software Self-Refresh mode (SSR) during DDR initilialization */
+ mmio_clrsetbits_32(priv->base + RCC_DDRITFCR,
+ RCC_DDRITFCR_DDRCKMOD_MASK,
+ RCC_DDRITFCR_DDRCKMOD_SSR <<
+ RCC_DDRITFCR_DDRCKMOD_SHIFT);
+
+ return 0;
+}
+
+static void stm32mp1_osc_clk_init(const char *name,
+ struct stm32mp1_clk_priv *priv,
+ enum stm32mp_osc_id index)
+{
+ uint32_t frequency;
+
+ priv->osc[index] = 0;
+
+ if (fdt_osc_read_freq(name, &frequency) != 0) {
+ ERROR("%s frequency request failed\n", name);
+ panic();
+ } else {
+ priv->osc[index] = frequency;
+ }
+}
+
+static void stm32mp1_osc_init(void)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+ enum stm32mp_osc_id i;
+
+ for (i = (enum stm32mp_osc_id)0 ; i < NB_OSC; i++) {
+ stm32mp1_osc_clk_init(stm32mp_osc_node_label[i], priv, i);
+ }
+}
+
+int stm32mp1_clk_probe(void)
+{
+ struct stm32mp1_clk_priv *priv = &stm32mp1_clk_priv_data;
+
+ priv->base = fdt_rcc_read_addr();
+ if (priv->base == 0U) {
+ return -EINVAL;
+ }
+
+ priv->data = &stm32mp1_data;
+
+ if ((priv->data->gate == NULL) || (priv->data->sel == NULL) ||
+ (priv->data->pll == NULL)) {
+ return -EINVAL;
+ }
+
+ stm32mp1_osc_init();
+
+ return 0;
+}
diff --git a/drivers/st/clk/stm32mp1_clkfunc.c b/drivers/st/clk/stm32mp1_clkfunc.c
new file mode 100644
index 000000000..d4c69cb4e
--- /dev/null
+++ b/drivers/st/clk/stm32mp1_clkfunc.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_dt.h>
+
+#define DT_RCC_NODE_NAME "rcc@50000000"
+#define DT_RCC_CLK_COMPAT "st,stm32mp1-rcc"
+#define DT_RCC_COMPAT "syscon"
+#define DT_STGEN_COMPAT "st,stm32-stgen"
+#define DT_UART_COMPAT "st,stm32h7-uart"
+#define DT_USART_COMPAT "st,stm32h7-usart"
+
+const char *stm32mp_osc_node_label[NB_OSC] = {
+ [_LSI] = "clk-lsi",
+ [_LSE] = "clk-lse",
+ [_HSI] = "clk-hsi",
+ [_HSE] = "clk-hse",
+ [_CSI] = "clk-csi",
+ [_I2S_CKIN] = "i2s_ckin",
+ [_USB_PHY_48] = "ck_usbo_48m"
+};
+
+/*******************************************************************************
+ * This function reads the frequency of an oscillator from its name.
+ * It reads the value indicated inside the device tree.
+ * Returns 0 if success, and a negative value else.
+ * If success, value is stored in the second parameter.
+ ******************************************************************************/
+int fdt_osc_read_freq(const char *name, uint32_t *freq)
+{
+ int node, subnode;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ node = fdt_path_offset(fdt, "/clocks");
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar;
+ int ret;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ return ret;
+ }
+
+ if (strncmp(cchar, name, (size_t)ret) == 0) {
+ const fdt32_t *cuint;
+
+ cuint = fdt_getprop(fdt, subnode, "clock-frequency",
+ &ret);
+ if (cuint == NULL) {
+ return ret;
+ }
+
+ *freq = fdt32_to_cpu(*cuint);
+
+ return 0;
+ }
+ }
+
+ /* Oscillator not found, freq=0 */
+ *freq = 0;
+ return 0;
+}
+
+/*******************************************************************************
+ * This function checks the presence of an oscillator property from its id.
+ * The search is done inside the device tree.
+ * Returns true/false regarding search result.
+ ******************************************************************************/
+bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name)
+{
+ int node, subnode;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return false;
+ }
+
+ if (osc_id >= NB_OSC) {
+ return false;
+ }
+
+ node = fdt_path_offset(fdt, "/clocks");
+ if (node < 0) {
+ return false;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar;
+ int ret;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ return false;
+ }
+
+ if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
+ (size_t)ret) != 0) {
+ continue;
+ }
+
+ if (fdt_getprop(fdt, subnode, prop_name, NULL) != NULL) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/*******************************************************************************
+ * This function reads a value of a oscillator property from its id.
+ * Returns value if success, and a default value if property not found.
+ * Default value is passed as parameter.
+ ******************************************************************************/
+uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
+ const char *prop_name, uint32_t dflt_value)
+{
+ int node, subnode;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return dflt_value;
+ }
+
+ if (osc_id >= NB_OSC) {
+ return dflt_value;
+ }
+
+ node = fdt_path_offset(fdt, "/clocks");
+ if (node < 0) {
+ return dflt_value;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar;
+ int ret;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ return dflt_value;
+ }
+
+ if (strncmp(cchar, stm32mp_osc_node_label[osc_id],
+ (size_t)ret) != 0) {
+ continue;
+ }
+
+ return fdt_read_uint32_default(subnode, prop_name, dflt_value);
+ }
+
+ return dflt_value;
+}
+
+/*******************************************************************************
+ * This function reads the rcc base address.
+ * It reads the value indicated inside the device tree.
+ * Returns address if success, and 0 value else.
+ ******************************************************************************/
+uint32_t fdt_rcc_read_addr(void)
+{
+ int node, subnode;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return 0;
+ }
+
+ node = fdt_path_offset(fdt, "/soc");
+ if (node < 0) {
+ return 0;
+ }
+
+ fdt_for_each_subnode(subnode, fdt, node) {
+ const char *cchar;
+ int ret;
+
+ cchar = fdt_get_name(fdt, subnode, &ret);
+ if (cchar == NULL) {
+ return 0;
+ }
+
+ if (strncmp(cchar, DT_RCC_NODE_NAME, (size_t)ret) == 0) {
+ const fdt32_t *cuint;
+
+ cuint = fdt_getprop(fdt, subnode, "reg", NULL);
+ if (cuint == NULL) {
+ return 0;
+ }
+
+ return fdt32_to_cpu(*cuint);
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function reads a series of parameters in rcc-clk section.
+ * It reads the values indicated inside the device tree, from property name.
+ * The number of parameters is also indicated as entry parameter.
+ * Returns 0 if success, and a negative value else.
+ * If success, values are stored at the second parameter address.
+ ******************************************************************************/
+int fdt_rcc_read_uint32_array(const char *prop_name,
+ uint32_t *array, uint32_t count)
+{
+ int node;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return fdt_read_uint32_array(node, prop_name, array, count);
+}
+
+/*******************************************************************************
+ * This function gets the subnode offset in rcc-clk section from its name.
+ * It reads the values indicated inside the device tree.
+ * Returns offset if success, and a negative value else.
+ ******************************************************************************/
+int fdt_rcc_subnode_offset(const char *name)
+{
+ int node, subnode;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ subnode = fdt_subnode_offset(fdt, node, name);
+ if (subnode <= 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return subnode;
+}
+
+/*******************************************************************************
+ * This function gets the pointer to a rcc-clk property from its name.
+ * It reads the values indicated inside the device tree.
+ * Length of the property is stored in the second parameter.
+ * Returns pointer if success, and NULL value else.
+ ******************************************************************************/
+const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp)
+{
+ const uint32_t *cuint;
+ int node, len;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return NULL;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_CLK_COMPAT);
+ if (node < 0) {
+ return NULL;
+ }
+
+ cuint = fdt_getprop(fdt, node, prop_name, &len);
+ if (cuint == NULL) {
+ return NULL;
+ }
+
+ *lenp = len;
+ return cuint;
+}
+
+/*******************************************************************************
+ * This function gets the secure status for rcc node.
+ * It reads secure-status in device tree.
+ * Returns 1 if rcc is available from secure world, 0 else.
+ ******************************************************************************/
+bool fdt_get_rcc_secure_status(void)
+{
+ int node;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return false;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_RCC_COMPAT);
+ if (node < 0) {
+ return false;
+ }
+
+ return fdt_check_secure_status(node);
+}
+
+/*******************************************************************************
+ * This function reads the stgen base address.
+ * It reads the value indicated inside the device tree.
+ * Returns address if success, and NULL value else.
+ ******************************************************************************/
+uintptr_t fdt_get_stgen_base(void)
+{
+ int node;
+ const fdt32_t *cuint;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return 0;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_STGEN_COMPAT);
+ if (node < 0) {
+ return 0;
+ }
+
+ cuint = fdt_getprop(fdt, node, "reg", NULL);
+ if (cuint == NULL) {
+ return 0;
+ }
+
+ return fdt32_to_cpu(*cuint);
+}
+
+/*******************************************************************************
+ * This function gets the clock ID of the given node.
+ * It reads the value indicated inside the device tree.
+ * Returns ID if success, and a negative value else.
+ ******************************************************************************/
+int fdt_get_clock_id(int node)
+{
+ const fdt32_t *cuint;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ cuint = fdt_getprop(fdt, node, "clocks", NULL);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint++;
+ return (int)fdt32_to_cpu(*cuint);
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr.c b/drivers/st/ddr/stm32mp1_ddr.c
new file mode 100644
index 000000000..eed1d7613
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ddr.c
@@ -0,0 +1,895 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <mmio.h>
+#include <platform.h>
+#include <stddef.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_ddr_regs.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stm32mp1_pwr.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+
+struct reg_desc {
+ const char *name;
+ uint16_t offset; /* Offset for base address */
+ uint8_t par_offset; /* Offset for parameter array */
+};
+
+#define INVALID_OFFSET 0xFFU
+
+#define TIMESLOT_1US (plat_get_syscnt_freq2() / 1000000U)
+
+#define DDRCTL_REG(x, y) \
+ { \
+ .name = #x, \
+ .offset = offsetof(struct stm32mp1_ddrctl, x), \
+ .par_offset = offsetof(struct y, x) \
+ }
+
+#define DDRPHY_REG(x, y) \
+ { \
+ .name = #x, \
+ .offset = offsetof(struct stm32mp1_ddrphy, x), \
+ .par_offset = offsetof(struct y, x) \
+ }
+
+#define DDRCTL_REG_REG(x) DDRCTL_REG(x, stm32mp1_ddrctrl_reg)
+static const struct reg_desc ddr_reg[] = {
+ DDRCTL_REG_REG(mstr),
+ DDRCTL_REG_REG(mrctrl0),
+ DDRCTL_REG_REG(mrctrl1),
+ DDRCTL_REG_REG(derateen),
+ DDRCTL_REG_REG(derateint),
+ DDRCTL_REG_REG(pwrctl),
+ DDRCTL_REG_REG(pwrtmg),
+ DDRCTL_REG_REG(hwlpctl),
+ DDRCTL_REG_REG(rfshctl0),
+ DDRCTL_REG_REG(rfshctl3),
+ DDRCTL_REG_REG(crcparctl0),
+ DDRCTL_REG_REG(zqctl0),
+ DDRCTL_REG_REG(dfitmg0),
+ DDRCTL_REG_REG(dfitmg1),
+ DDRCTL_REG_REG(dfilpcfg0),
+ DDRCTL_REG_REG(dfiupd0),
+ DDRCTL_REG_REG(dfiupd1),
+ DDRCTL_REG_REG(dfiupd2),
+ DDRCTL_REG_REG(dfiphymstr),
+ DDRCTL_REG_REG(odtmap),
+ DDRCTL_REG_REG(dbg0),
+ DDRCTL_REG_REG(dbg1),
+ DDRCTL_REG_REG(dbgcmd),
+ DDRCTL_REG_REG(poisoncfg),
+ DDRCTL_REG_REG(pccfg),
+};
+
+#define DDRCTL_REG_TIMING(x) DDRCTL_REG(x, stm32mp1_ddrctrl_timing)
+static const struct reg_desc ddr_timing[] = {
+ DDRCTL_REG_TIMING(rfshtmg),
+ DDRCTL_REG_TIMING(dramtmg0),
+ DDRCTL_REG_TIMING(dramtmg1),
+ DDRCTL_REG_TIMING(dramtmg2),
+ DDRCTL_REG_TIMING(dramtmg3),
+ DDRCTL_REG_TIMING(dramtmg4),
+ DDRCTL_REG_TIMING(dramtmg5),
+ DDRCTL_REG_TIMING(dramtmg6),
+ DDRCTL_REG_TIMING(dramtmg7),
+ DDRCTL_REG_TIMING(dramtmg8),
+ DDRCTL_REG_TIMING(dramtmg14),
+ DDRCTL_REG_TIMING(odtcfg),
+};
+
+#define DDRCTL_REG_MAP(x) DDRCTL_REG(x, stm32mp1_ddrctrl_map)
+static const struct reg_desc ddr_map[] = {
+ DDRCTL_REG_MAP(addrmap1),
+ DDRCTL_REG_MAP(addrmap2),
+ DDRCTL_REG_MAP(addrmap3),
+ DDRCTL_REG_MAP(addrmap4),
+ DDRCTL_REG_MAP(addrmap5),
+ DDRCTL_REG_MAP(addrmap6),
+ DDRCTL_REG_MAP(addrmap9),
+ DDRCTL_REG_MAP(addrmap10),
+ DDRCTL_REG_MAP(addrmap11),
+};
+
+#define DDRCTL_REG_PERF(x) DDRCTL_REG(x, stm32mp1_ddrctrl_perf)
+static const struct reg_desc ddr_perf[] = {
+ DDRCTL_REG_PERF(sched),
+ DDRCTL_REG_PERF(sched1),
+ DDRCTL_REG_PERF(perfhpr1),
+ DDRCTL_REG_PERF(perflpr1),
+ DDRCTL_REG_PERF(perfwr1),
+ DDRCTL_REG_PERF(pcfgr_0),
+ DDRCTL_REG_PERF(pcfgw_0),
+ DDRCTL_REG_PERF(pcfgqos0_0),
+ DDRCTL_REG_PERF(pcfgqos1_0),
+ DDRCTL_REG_PERF(pcfgwqos0_0),
+ DDRCTL_REG_PERF(pcfgwqos1_0),
+ DDRCTL_REG_PERF(pcfgr_1),
+ DDRCTL_REG_PERF(pcfgw_1),
+ DDRCTL_REG_PERF(pcfgqos0_1),
+ DDRCTL_REG_PERF(pcfgqos1_1),
+ DDRCTL_REG_PERF(pcfgwqos0_1),
+ DDRCTL_REG_PERF(pcfgwqos1_1),
+};
+
+#define DDRPHY_REG_REG(x) DDRPHY_REG(x, stm32mp1_ddrphy_reg)
+static const struct reg_desc ddrphy_reg[] = {
+ DDRPHY_REG_REG(pgcr),
+ DDRPHY_REG_REG(aciocr),
+ DDRPHY_REG_REG(dxccr),
+ DDRPHY_REG_REG(dsgcr),
+ DDRPHY_REG_REG(dcr),
+ DDRPHY_REG_REG(odtcr),
+ DDRPHY_REG_REG(zq0cr1),
+ DDRPHY_REG_REG(dx0gcr),
+ DDRPHY_REG_REG(dx1gcr),
+ DDRPHY_REG_REG(dx2gcr),
+ DDRPHY_REG_REG(dx3gcr),
+};
+
+#define DDRPHY_REG_TIMING(x) DDRPHY_REG(x, stm32mp1_ddrphy_timing)
+static const struct reg_desc ddrphy_timing[] = {
+ DDRPHY_REG_TIMING(ptr0),
+ DDRPHY_REG_TIMING(ptr1),
+ DDRPHY_REG_TIMING(ptr2),
+ DDRPHY_REG_TIMING(dtpr0),
+ DDRPHY_REG_TIMING(dtpr1),
+ DDRPHY_REG_TIMING(dtpr2),
+ DDRPHY_REG_TIMING(mr0),
+ DDRPHY_REG_TIMING(mr1),
+ DDRPHY_REG_TIMING(mr2),
+ DDRPHY_REG_TIMING(mr3),
+};
+
+#define DDRPHY_REG_CAL(x) DDRPHY_REG(x, stm32mp1_ddrphy_cal)
+static const struct reg_desc ddrphy_cal[] = {
+ DDRPHY_REG_CAL(dx0dllcr),
+ DDRPHY_REG_CAL(dx0dqtr),
+ DDRPHY_REG_CAL(dx0dqstr),
+ DDRPHY_REG_CAL(dx1dllcr),
+ DDRPHY_REG_CAL(dx1dqtr),
+ DDRPHY_REG_CAL(dx1dqstr),
+ DDRPHY_REG_CAL(dx2dllcr),
+ DDRPHY_REG_CAL(dx2dqtr),
+ DDRPHY_REG_CAL(dx2dqstr),
+ DDRPHY_REG_CAL(dx3dllcr),
+ DDRPHY_REG_CAL(dx3dqtr),
+ DDRPHY_REG_CAL(dx3dqstr),
+};
+
+#define DDR_REG_DYN(x) \
+ { \
+ .name = #x, \
+ .offset = offsetof(struct stm32mp1_ddrctl, x), \
+ .par_offset = INVALID_OFFSET \
+ }
+
+static const struct reg_desc ddr_dyn[] = {
+ DDR_REG_DYN(stat),
+ DDR_REG_DYN(init0),
+ DDR_REG_DYN(dfimisc),
+ DDR_REG_DYN(dfistat),
+ DDR_REG_DYN(swctl),
+ DDR_REG_DYN(swstat),
+ DDR_REG_DYN(pctrl_0),
+ DDR_REG_DYN(pctrl_1),
+};
+
+#define DDRPHY_REG_DYN(x) \
+ { \
+ .name = #x, \
+ .offset = offsetof(struct stm32mp1_ddrphy, x), \
+ .par_offset = INVALID_OFFSET \
+ }
+
+static const struct reg_desc ddrphy_dyn[] = {
+ DDRPHY_REG_DYN(pir),
+ DDRPHY_REG_DYN(pgsr),
+};
+
+enum reg_type {
+ REG_REG,
+ REG_TIMING,
+ REG_PERF,
+ REG_MAP,
+ REGPHY_REG,
+ REGPHY_TIMING,
+ REGPHY_CAL,
+/*
+ * Dynamic registers => managed in driver or not changed,
+ * can be dumped in interactive mode.
+ */
+ REG_DYN,
+ REGPHY_DYN,
+ REG_TYPE_NB
+};
+
+enum base_type {
+ DDR_BASE,
+ DDRPHY_BASE,
+ NONE_BASE
+};
+
+struct ddr_reg_info {
+ const char *name;
+ const struct reg_desc *desc;
+ uint8_t size;
+ enum base_type base;
+};
+
+static const struct ddr_reg_info ddr_registers[REG_TYPE_NB] = {
+ [REG_REG] = {
+ "static", ddr_reg, ARRAY_SIZE(ddr_reg), DDR_BASE
+ },
+ [REG_TIMING] = {
+ "timing", ddr_timing, ARRAY_SIZE(ddr_timing), DDR_BASE
+ },
+ [REG_PERF] = {
+ "perf", ddr_perf, ARRAY_SIZE(ddr_perf), DDR_BASE
+ },
+ [REG_MAP] = {
+ "map", ddr_map, ARRAY_SIZE(ddr_map), DDR_BASE
+ },
+ [REGPHY_REG] = {
+ "static", ddrphy_reg, ARRAY_SIZE(ddrphy_reg), DDRPHY_BASE
+ },
+ [REGPHY_TIMING] = {
+ "timing", ddrphy_timing, ARRAY_SIZE(ddrphy_timing), DDRPHY_BASE
+ },
+ [REGPHY_CAL] = {
+ "cal", ddrphy_cal, ARRAY_SIZE(ddrphy_cal), DDRPHY_BASE
+ },
+ [REG_DYN] = {
+ "dyn", ddr_dyn, ARRAY_SIZE(ddr_dyn), DDR_BASE
+ },
+ [REGPHY_DYN] = {
+ "dyn", ddrphy_dyn, ARRAY_SIZE(ddrphy_dyn), DDRPHY_BASE
+ },
+};
+
+static uint32_t get_base_addr(const struct ddr_info *priv, enum base_type base)
+{
+ if (base == DDRPHY_BASE) {
+ return (uint32_t)priv->phy;
+ } else {
+ return (uint32_t)priv->ctl;
+ }
+}
+
+static void set_reg(const struct ddr_info *priv,
+ enum reg_type type,
+ const void *param)
+{
+ unsigned int i;
+ unsigned int *ptr, value;
+ enum base_type base = ddr_registers[type].base;
+ uint32_t base_addr = get_base_addr(priv, base);
+ const struct reg_desc *desc = ddr_registers[type].desc;
+
+ VERBOSE("init %s\n", ddr_registers[type].name);
+ for (i = 0; i < ddr_registers[type].size; i++) {
+ ptr = (unsigned int *)(base_addr + desc[i].offset);
+ if (desc[i].par_offset == INVALID_OFFSET) {
+ ERROR("invalid parameter offset for %s", desc[i].name);
+ panic();
+ } else {
+ value = *((uint32_t *)((uint32_t)param +
+ desc[i].par_offset));
+ mmio_write_32((uint32_t)ptr, value);
+ }
+ }
+}
+
+static void stm32mp1_ddrphy_idone_wait(struct stm32mp1_ddrphy *phy)
+{
+ uint32_t pgsr;
+ int error = 0;
+ unsigned long start;
+ unsigned long time0, time;
+
+ start = get_timer(0);
+ time0 = start;
+
+ do {
+ pgsr = mmio_read_32((uint32_t)&phy->pgsr);
+ time = get_timer(start);
+ if (time != time0) {
+ VERBOSE(" > [0x%x] pgsr = 0x%x &\n",
+ (uint32_t)&phy->pgsr, pgsr);
+ VERBOSE(" [0x%x] pir = 0x%x (time=%x)\n",
+ (uint32_t)&phy->pir,
+ mmio_read_32((uint32_t)&phy->pir),
+ (uint32_t)time);
+ }
+
+ time0 = time;
+ if (time > plat_get_syscnt_freq2()) {
+ panic();
+ }
+ if ((pgsr & DDRPHYC_PGSR_DTERR) != 0U) {
+ VERBOSE("DQS Gate Trainig Error\n");
+ error++;
+ }
+ if ((pgsr & DDRPHYC_PGSR_DTIERR) != 0U) {
+ VERBOSE("DQS Gate Trainig Intermittent Error\n");
+ error++;
+ }
+ if ((pgsr & DDRPHYC_PGSR_DFTERR) != 0U) {
+ VERBOSE("DQS Drift Error\n");
+ error++;
+ }
+ if ((pgsr & DDRPHYC_PGSR_RVERR) != 0U) {
+ VERBOSE("Read Valid Training Error\n");
+ error++;
+ }
+ if ((pgsr & DDRPHYC_PGSR_RVEIRR) != 0U) {
+ VERBOSE("Read Valid Training Intermittent Error\n");
+ error++;
+ }
+ } while ((pgsr & DDRPHYC_PGSR_IDONE) == 0U && error == 0);
+ VERBOSE("\n[0x%x] pgsr = 0x%x\n",
+ (uint32_t)&phy->pgsr, pgsr);
+}
+
+static void stm32mp1_ddrphy_init(struct stm32mp1_ddrphy *phy, uint32_t pir)
+{
+ uint32_t pir_init = pir | DDRPHYC_PIR_INIT;
+
+ mmio_write_32((uint32_t)&phy->pir, pir_init);
+ VERBOSE("[0x%x] pir = 0x%x -> 0x%x\n",
+ (uint32_t)&phy->pir, pir_init,
+ mmio_read_32((uint32_t)&phy->pir));
+
+ /* Need to wait 10 configuration clock before start polling */
+ udelay(10);
+
+ /* Wait DRAM initialization and Gate Training Evaluation complete */
+ stm32mp1_ddrphy_idone_wait(phy);
+}
+
+/* Start quasi dynamic register update */
+static void stm32mp1_start_sw_done(struct stm32mp1_ddrctl *ctl)
+{
+ mmio_clrbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+ VERBOSE("[0x%x] swctl = 0x%x\n",
+ (uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+}
+
+/* Wait quasi dynamic register update */
+static void stm32mp1_wait_sw_done_ack(struct stm32mp1_ddrctl *ctl)
+{
+ unsigned long start;
+ uint32_t swstat;
+
+ mmio_setbits_32((uint32_t)&ctl->swctl, DDRCTRL_SWCTL_SW_DONE);
+ VERBOSE("[0x%x] swctl = 0x%x\n",
+ (uint32_t)&ctl->swctl, mmio_read_32((uint32_t)&ctl->swctl));
+
+ start = get_timer(0);
+ do {
+ swstat = mmio_read_32((uint32_t)&ctl->swstat);
+ VERBOSE("[0x%x] swstat = 0x%x ",
+ (uint32_t)&ctl->swstat, swstat);
+ VERBOSE("timer in ms 0x%x = start 0x%lx\r",
+ get_timer(0), start);
+ if (get_timer(start) > plat_get_syscnt_freq2()) {
+ panic();
+ }
+ } while ((swstat & DDRCTRL_SWSTAT_SW_DONE_ACK) == 0U);
+
+ VERBOSE("[0x%x] swstat = 0x%x\n",
+ (uint32_t)&ctl->swstat, swstat);
+}
+
+/* Wait quasi dynamic register update */
+static void stm32mp1_wait_operating_mode(struct ddr_info *priv, uint32_t mode)
+{
+ unsigned long start;
+ uint32_t stat;
+ uint32_t operating_mode;
+ uint32_t selref_type;
+ int break_loop = 0;
+
+ start = get_timer(0);
+ for ( ; ; ) {
+ stat = mmio_read_32((uint32_t)&priv->ctl->stat);
+ operating_mode = stat & DDRCTRL_STAT_OPERATING_MODE_MASK;
+ selref_type = stat & DDRCTRL_STAT_SELFREF_TYPE_MASK;
+ VERBOSE("[0x%x] stat = 0x%x\n",
+ (uint32_t)&priv->ctl->stat, stat);
+ VERBOSE("timer in ms 0x%x = start 0x%lx\r",
+ get_timer(0), start);
+ if (get_timer(start) > plat_get_syscnt_freq2()) {
+ panic();
+ }
+
+ if (mode == DDRCTRL_STAT_OPERATING_MODE_SR) {
+ /*
+ * Self-refresh due to software
+ * => checking also STAT.selfref_type.
+ */
+ if ((operating_mode ==
+ DDRCTRL_STAT_OPERATING_MODE_SR) &&
+ (selref_type == DDRCTRL_STAT_SELFREF_TYPE_SR)) {
+ break_loop = 1;
+ }
+ } else if (operating_mode == mode) {
+ break_loop = 1;
+ } else if ((mode == DDRCTRL_STAT_OPERATING_MODE_NORMAL) &&
+ (operating_mode == DDRCTRL_STAT_OPERATING_MODE_SR) &&
+ (selref_type == DDRCTRL_STAT_SELFREF_TYPE_ASR)) {
+ /* Normal mode: handle also automatic self refresh */
+ break_loop = 1;
+ }
+
+ if (break_loop == 1) {
+ break;
+ }
+ }
+
+ VERBOSE("[0x%x] stat = 0x%x\n",
+ (uint32_t)&priv->ctl->stat, stat);
+}
+
+/* Mode Register Writes (MRW or MRS) */
+static void stm32mp1_mode_register_write(struct ddr_info *priv, uint8_t addr,
+ uint32_t data)
+{
+ uint32_t mrctrl0;
+
+ VERBOSE("MRS: %d = %x\n", addr, data);
+
+ /*
+ * 1. Poll MRSTAT.mr_wr_busy until it is '0'.
+ * This checks that there is no outstanding MR transaction.
+ * No write should be performed to MRCTRL0 and MRCTRL1
+ * if MRSTAT.mr_wr_busy = 1.
+ */
+ while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+ DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
+ ;
+ }
+
+ /*
+ * 2. Write the MRCTRL0.mr_type, MRCTRL0.mr_addr, MRCTRL0.mr_rank
+ * and (for MRWs) MRCTRL1.mr_data to define the MR transaction.
+ */
+ mrctrl0 = DDRCTRL_MRCTRL0_MR_TYPE_WRITE |
+ DDRCTRL_MRCTRL0_MR_RANK_ALL |
+ (((uint32_t)addr << DDRCTRL_MRCTRL0_MR_ADDR_SHIFT) &
+ DDRCTRL_MRCTRL0_MR_ADDR_MASK);
+ mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+ VERBOSE("[0x%x] mrctrl0 = 0x%x (0x%x)\n",
+ (uint32_t)&priv->ctl->mrctrl0,
+ mmio_read_32((uint32_t)&priv->ctl->mrctrl0), mrctrl0);
+ mmio_write_32((uint32_t)&priv->ctl->mrctrl1, data);
+ VERBOSE("[0x%x] mrctrl1 = 0x%x\n",
+ (uint32_t)&priv->ctl->mrctrl1,
+ mmio_read_32((uint32_t)&priv->ctl->mrctrl1));
+
+ /*
+ * 3. In a separate APB transaction, write the MRCTRL0.mr_wr to 1. This
+ * bit is self-clearing, and triggers the MR transaction.
+ * The uMCTL2 then asserts the MRSTAT.mr_wr_busy while it performs
+ * the MR transaction to SDRAM, and no further access can be
+ * initiated until it is deasserted.
+ */
+ mrctrl0 |= DDRCTRL_MRCTRL0_MR_WR;
+ mmio_write_32((uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+
+ while ((mmio_read_32((uint32_t)&priv->ctl->mrstat) &
+ DDRCTRL_MRSTAT_MR_WR_BUSY) != 0U) {
+ ;
+ }
+
+ VERBOSE("[0x%x] mrctrl0 = 0x%x\n",
+ (uint32_t)&priv->ctl->mrctrl0, mrctrl0);
+}
+
+/* Switch DDR3 from DLL-on to DLL-off */
+static void stm32mp1_ddr3_dll_off(struct ddr_info *priv)
+{
+ uint32_t mr1 = mmio_read_32((uint32_t)&priv->phy->mr1);
+ uint32_t mr2 = mmio_read_32((uint32_t)&priv->phy->mr2);
+ uint32_t dbgcam;
+
+ VERBOSE("mr1: 0x%x\n", mr1);
+ VERBOSE("mr2: 0x%x\n", mr2);
+
+ /*
+ * 1. Set the DBG1.dis_hif = 1.
+ * This prevents further reads/writes being received on the HIF.
+ */
+ mmio_setbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+ VERBOSE("[0x%x] dbg1 = 0x%x\n",
+ (uint32_t)&priv->ctl->dbg1,
+ mmio_read_32((uint32_t)&priv->ctl->dbg1));
+
+ /*
+ * 2. Ensure all commands have been flushed from the uMCTL2 by polling
+ * DBGCAM.wr_data_pipeline_empty = 1,
+ * DBGCAM.rd_data_pipeline_empty = 1,
+ * DBGCAM.dbg_wr_q_depth = 0 ,
+ * DBGCAM.dbg_lpr_q_depth = 0, and
+ * DBGCAM.dbg_hpr_q_depth = 0.
+ */
+ do {
+ dbgcam = mmio_read_32((uint32_t)&priv->ctl->dbgcam);
+ VERBOSE("[0x%x] dbgcam = 0x%x\n",
+ (uint32_t)&priv->ctl->dbgcam, dbgcam);
+ } while ((((dbgcam & DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY) ==
+ DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY)) &&
+ ((dbgcam & DDRCTRL_DBGCAM_DBG_Q_DEPTH) == 0U));
+
+ /*
+ * 3. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+ * to disable RTT_NOM:
+ * a. DDR3: Write to MR1[9], MR1[6] and MR1[2]
+ * b. DDR4: Write to MR1[10:8]
+ */
+ mr1 &= ~(BIT(9) | BIT(6) | BIT(2));
+ stm32mp1_mode_register_write(priv, 1, mr1);
+
+ /*
+ * 4. For DDR4 only: Perform an MRS command
+ * (using MRCTRL0 and MRCTRL1 registers) to write to MR5[8:6]
+ * to disable RTT_PARK
+ */
+
+ /*
+ * 5. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+ * to write to MR2[10:9], to disable RTT_WR
+ * (and therefore disable dynamic ODT).
+ * This applies for both DDR3 and DDR4.
+ */
+ mr2 &= ~GENMASK(10, 9);
+ stm32mp1_mode_register_write(priv, 2, mr2);
+
+ /*
+ * 6. Perform an MRS command (using MRCTRL0 and MRCTRL1 registers)
+ * to disable the DLL. The timing of this MRS is automatically
+ * handled by the uMCTL2.
+ * a. DDR3: Write to MR1[0]
+ * b. DDR4: Write to MR1[0]
+ */
+ mr1 |= BIT(0);
+ stm32mp1_mode_register_write(priv, 1, mr1);
+
+ /*
+ * 7. Put the SDRAM into self-refresh mode by setting
+ * PWRCTL.selfref_sw = 1, and polling STAT.operating_mode to ensure
+ * the DDRC has entered self-refresh.
+ */
+ mmio_setbits_32((uint32_t)&priv->ctl->pwrctl,
+ DDRCTRL_PWRCTL_SELFREF_SW);
+ VERBOSE("[0x%x] pwrctl = 0x%x\n",
+ (uint32_t)&priv->ctl->pwrctl,
+ mmio_read_32((uint32_t)&priv->ctl->pwrctl));
+
+ /*
+ * 8. Wait until STAT.operating_mode[1:0]==11 indicating that the
+ * DWC_ddr_umctl2 core is in self-refresh mode.
+ * Ensure transition to self-refresh was due to software
+ * by checking that STAT.selfref_type[1:0]=2.
+ */
+ stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_SR);
+
+ /*
+ * 9. Set the MSTR.dll_off_mode = 1.
+ * warning: MSTR.dll_off_mode is a quasi-dynamic type 2 field
+ */
+ stm32mp1_start_sw_done(priv->ctl);
+
+ mmio_setbits_32((uint32_t)&priv->ctl->mstr, DDRCTRL_MSTR_DLL_OFF_MODE);
+ VERBOSE("[0x%x] mstr = 0x%x\n",
+ (uint32_t)&priv->ctl->mstr,
+ mmio_read_32((uint32_t)&priv->ctl->mstr));
+
+ stm32mp1_wait_sw_done_ack(priv->ctl);
+
+ /* 10. Change the clock frequency to the desired value. */
+
+ /*
+ * 11. Update any registers which may be required to change for the new
+ * frequency. This includes static and dynamic registers.
+ * This includes both uMCTL2 registers and PHY registers.
+ */
+
+ /* Change Bypass Mode Frequency Range */
+ if (stm32mp1_clk_get_rate(DDRPHYC) < 100000000U) {
+ mmio_clrbits_32((uint32_t)&priv->phy->dllgcr,
+ DDRPHYC_DLLGCR_BPS200);
+ } else {
+ mmio_setbits_32((uint32_t)&priv->phy->dllgcr,
+ DDRPHYC_DLLGCR_BPS200);
+ }
+
+ mmio_setbits_32((uint32_t)&priv->phy->acdllcr, DDRPHYC_ACDLLCR_DLLDIS);
+
+ mmio_setbits_32((uint32_t)&priv->phy->dx0dllcr,
+ DDRPHYC_DXNDLLCR_DLLDIS);
+ mmio_setbits_32((uint32_t)&priv->phy->dx1dllcr,
+ DDRPHYC_DXNDLLCR_DLLDIS);
+ mmio_setbits_32((uint32_t)&priv->phy->dx2dllcr,
+ DDRPHYC_DXNDLLCR_DLLDIS);
+ mmio_setbits_32((uint32_t)&priv->phy->dx3dllcr,
+ DDRPHYC_DXNDLLCR_DLLDIS);
+
+ /* 12. Exit the self-refresh state by setting PWRCTL.selfref_sw = 0. */
+ mmio_clrbits_32((uint32_t)&priv->ctl->pwrctl,
+ DDRCTRL_PWRCTL_SELFREF_SW);
+ stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
+
+ /*
+ * 13. If ZQCTL0.dis_srx_zqcl = 0, the uMCTL2 performs a ZQCL command
+ * at this point.
+ */
+
+ /*
+ * 14. Perform MRS commands as required to re-program timing registers
+ * in the SDRAM for the new frequency
+ * (in particular, CL, CWL and WR may need to be changed).
+ */
+
+ /* 15. Write DBG1.dis_hif = 0 to re-enable reads and writes. */
+ mmio_clrbits_32((uint32_t)&priv->ctl->dbg1, DDRCTRL_DBG1_DIS_HIF);
+ VERBOSE("[0x%x] dbg1 = 0x%x\n",
+ (uint32_t)&priv->ctl->dbg1,
+ mmio_read_32((uint32_t)&priv->ctl->dbg1));
+}
+
+static void stm32mp1_refresh_disable(struct stm32mp1_ddrctl *ctl)
+{
+ stm32mp1_start_sw_done(ctl);
+ /* Quasi-dynamic register update*/
+ mmio_setbits_32((uint32_t)&ctl->rfshctl3,
+ DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+ mmio_clrbits_32((uint32_t)&ctl->pwrctl, DDRCTRL_PWRCTL_POWERDOWN_EN);
+ mmio_clrbits_32((uint32_t)&ctl->dfimisc,
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+ stm32mp1_wait_sw_done_ack(ctl);
+}
+
+static void stm32mp1_refresh_restore(struct stm32mp1_ddrctl *ctl,
+ uint32_t rfshctl3, uint32_t pwrctl)
+{
+ stm32mp1_start_sw_done(ctl);
+ if ((rfshctl3 & DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH) == 0U) {
+ mmio_clrbits_32((uint32_t)&ctl->rfshctl3,
+ DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH);
+ }
+ if ((pwrctl & DDRCTRL_PWRCTL_POWERDOWN_EN) != 0U) {
+ mmio_setbits_32((uint32_t)&ctl->pwrctl,
+ DDRCTRL_PWRCTL_POWERDOWN_EN);
+ }
+ mmio_setbits_32((uint32_t)&ctl->dfimisc,
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+ stm32mp1_wait_sw_done_ack(ctl);
+}
+
+static int board_ddr_power_init(enum ddr_type ddr_type)
+{
+ if (dt_check_pmic()) {
+ return pmic_ddr_power_init(ddr_type);
+ }
+
+ return 0;
+}
+
+void stm32mp1_ddr_init(struct ddr_info *priv,
+ struct stm32mp1_ddr_config *config)
+{
+ uint32_t pir;
+ int ret;
+
+ if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+ ret = board_ddr_power_init(STM32MP_DDR3);
+ } else {
+ ret = board_ddr_power_init(STM32MP_LPDDR2);
+ }
+
+ if (ret != 0) {
+ panic();
+ }
+
+ VERBOSE("name = %s\n", config->info.name);
+ VERBOSE("speed = %d MHz\n", config->info.speed);
+ VERBOSE("size = 0x%x\n", config->info.size);
+
+ /* DDR INIT SEQUENCE */
+
+ /*
+ * 1. Program the DWC_ddr_umctl2 registers
+ * nota: check DFIMISC.dfi_init_complete = 0
+ */
+
+ /* 1.1 RESETS: presetn, core_ddrc_rstn, aresetn */
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
+
+ /* 1.2. start CLOCK */
+ if (stm32mp1_ddr_clk_enable(priv, config->info.speed) != 0) {
+ panic();
+ }
+
+ /* 1.3. deassert reset */
+ /* De-assert PHY rstn and ctl_rstn via DPHYRST and DPHYCTLRST. */
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYRST);
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYCTLRST);
+ /*
+ * De-assert presetn once the clocks are active
+ * and stable via DDRCAPBRST bit.
+ */
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAPBRST);
+
+ /* 1.4. wait 128 cycles to permit initialization of end logic */
+ udelay(2);
+ /* For PCLK = 133MHz => 1 us is enough, 2 to allow lower frequency */
+
+ /* 1.5. initialize registers ddr_umctl2 */
+ /* Stop uMCTL2 before PHY is ready */
+ mmio_clrbits_32((uint32_t)&priv->ctl->dfimisc,
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+ VERBOSE("[0x%x] dfimisc = 0x%x\n",
+ (uint32_t)&priv->ctl->dfimisc,
+ mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+
+ set_reg(priv, REG_REG, &config->c_reg);
+
+ /* DDR3 = don't set DLLOFF for init mode */
+ if ((config->c_reg.mstr &
+ (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
+ == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
+ VERBOSE("deactivate DLL OFF in mstr\n");
+ mmio_clrbits_32((uint32_t)&priv->ctl->mstr,
+ DDRCTRL_MSTR_DLL_OFF_MODE);
+ VERBOSE("[0x%x] mstr = 0x%x\n",
+ (uint32_t)&priv->ctl->mstr,
+ mmio_read_32((uint32_t)&priv->ctl->mstr));
+ }
+
+ set_reg(priv, REG_TIMING, &config->c_timing);
+ set_reg(priv, REG_MAP, &config->c_map);
+
+ /* Skip CTRL init, SDRAM init is done by PHY PUBL */
+ mmio_clrsetbits_32((uint32_t)&priv->ctl->init0,
+ DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK,
+ DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL);
+ VERBOSE("[0x%x] init0 = 0x%x\n",
+ (uint32_t)&priv->ctl->init0,
+ mmio_read_32((uint32_t)&priv->ctl->init0));
+
+ set_reg(priv, REG_PERF, &config->c_perf);
+
+ /* 2. deassert reset signal core_ddrc_rstn, aresetn and presetn */
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCORERST);
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DDRCAXIRST);
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_DPHYAPBRST);
+
+ /*
+ * 3. start PHY init by accessing relevant PUBL registers
+ * (DXGCR, DCR, PTR*, MR*, DTPR*)
+ */
+ set_reg(priv, REGPHY_REG, &config->p_reg);
+ set_reg(priv, REGPHY_TIMING, &config->p_timing);
+ set_reg(priv, REGPHY_CAL, &config->p_cal);
+
+ /* DDR3 = don't set DLLOFF for init mode */
+ if ((config->c_reg.mstr &
+ (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE))
+ == (DDRCTRL_MSTR_DDR3 | DDRCTRL_MSTR_DLL_OFF_MODE)) {
+ VERBOSE("deactivate DLL OFF in mr1\n");
+ mmio_clrbits_32((uint32_t)&priv->phy->mr1, BIT(0));
+ VERBOSE("[0x%x] mr1 = 0x%x\n",
+ (uint32_t)&priv->phy->mr1,
+ mmio_read_32((uint32_t)&priv->phy->mr1));
+ }
+
+ /*
+ * 4. Monitor PHY init status by polling PUBL register PGSR.IDONE
+ * Perform DDR PHY DRAM initialization and Gate Training Evaluation
+ */
+ stm32mp1_ddrphy_idone_wait(priv->phy);
+
+ /*
+ * 5. Indicate to PUBL that controller performs SDRAM initialization
+ * by setting PIR.INIT and PIR CTLDINIT and pool PGSR.IDONE
+ * DRAM init is done by PHY, init0.skip_dram.init = 1
+ */
+
+ pir = DDRPHYC_PIR_DLLSRST | DDRPHYC_PIR_DLLLOCK | DDRPHYC_PIR_ZCAL |
+ DDRPHYC_PIR_ITMSRST | DDRPHYC_PIR_DRAMINIT | DDRPHYC_PIR_ICPC;
+
+ if ((config->c_reg.mstr & DDRCTRL_MSTR_DDR3) != 0U) {
+ pir |= DDRPHYC_PIR_DRAMRST; /* Only for DDR3 */
+ }
+
+ stm32mp1_ddrphy_init(priv->phy, pir);
+
+ /*
+ * 6. SET DFIMISC.dfi_init_complete_en to 1
+ * Enable quasi-dynamic register programming.
+ */
+ stm32mp1_start_sw_done(priv->ctl);
+
+ mmio_setbits_32((uint32_t)&priv->ctl->dfimisc,
+ DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN);
+ VERBOSE("[0x%x] dfimisc = 0x%x\n",
+ (uint32_t)&priv->ctl->dfimisc,
+ mmio_read_32((uint32_t)&priv->ctl->dfimisc));
+
+ stm32mp1_wait_sw_done_ack(priv->ctl);
+
+ /*
+ * 7. Wait for DWC_ddr_umctl2 to move to normal operation mode
+ * by monitoring STAT.operating_mode signal
+ */
+
+ /* Wait uMCTL2 ready */
+ stm32mp1_wait_operating_mode(priv, DDRCTRL_STAT_OPERATING_MODE_NORMAL);
+
+ /* Switch to DLL OFF mode */
+ if ((config->c_reg.mstr & DDRCTRL_MSTR_DLL_OFF_MODE) != 0U) {
+ stm32mp1_ddr3_dll_off(priv);
+ }
+
+ VERBOSE("DDR DQS training : ");
+
+ /*
+ * 8. Disable Auto refresh and power down by setting
+ * - RFSHCTL3.dis_au_refresh = 1
+ * - PWRCTL.powerdown_en = 0
+ * - DFIMISC.dfiinit_complete_en = 0
+ */
+ stm32mp1_refresh_disable(priv->ctl);
+
+ /*
+ * 9. Program PUBL PGCR to enable refresh during training
+ * and rank to train
+ * not done => keep the programed value in PGCR
+ */
+
+ /*
+ * 10. configure PUBL PIR register to specify which training step
+ * to run
+ * Warning : RVTRN is not supported by this PUBL
+ */
+ stm32mp1_ddrphy_init(priv->phy, DDRPHYC_PIR_QSTRN);
+
+ /* 11. monitor PUB PGSR.IDONE to poll cpmpletion of training sequence */
+ stm32mp1_ddrphy_idone_wait(priv->phy);
+
+ /*
+ * 12. set back registers in step 8 to the orginal values if desidered
+ */
+ stm32mp1_refresh_restore(priv->ctl, config->c_reg.rfshctl3,
+ config->c_reg.pwrctl);
+
+ /* Enable uMCTL2 AXI port 0 */
+ mmio_setbits_32((uint32_t)&priv->ctl->pctrl_0, DDRCTRL_PCTRL_N_PORT_EN);
+ VERBOSE("[0x%x] pctrl_0 = 0x%x\n",
+ (uint32_t)&priv->ctl->pctrl_0,
+ mmio_read_32((uint32_t)&priv->ctl->pctrl_0));
+
+ /* Enable uMCTL2 AXI port 1 */
+ mmio_setbits_32((uint32_t)&priv->ctl->pctrl_1, DDRCTRL_PCTRL_N_PORT_EN);
+ VERBOSE("[0x%x] pctrl_1 = 0x%x\n",
+ (uint32_t)&priv->ctl->pctrl_1,
+ mmio_read_32((uint32_t)&priv->ctl->pctrl_1));
+}
diff --git a/drivers/st/ddr/stm32mp1_ddr_helpers.c b/drivers/st/ddr/stm32mp1_ddr_helpers.c
new file mode 100644
index 000000000..325c0b897
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ddr_helpers.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_ddr_helpers.h>
+#include <stm32mp1_rcc.h>
+
+void ddr_enable_clock(void)
+{
+ mmio_setbits_32(RCC_BASE + RCC_DDRITFCR,
+ RCC_DDRITFCR_DDRC1EN |
+ RCC_DDRITFCR_DDRC2EN |
+ RCC_DDRITFCR_DDRPHYCEN |
+ RCC_DDRITFCR_DDRPHYCAPBEN |
+ RCC_DDRITFCR_DDRCAPBEN);
+}
diff --git a/drivers/st/ddr/stm32mp1_ram.c b/drivers/st/ddr/stm32mp1_ram.c
new file mode 100644
index 000000000..6d515ec76
--- /dev/null
+++ b/drivers/st/ddr/stm32mp1_ram.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_ddr_helpers.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+
+#define DDR_PATTERN 0xAAAAAAAAU
+#define DDR_ANTIPATTERN 0x55555555U
+
+static struct ddr_info ddr_priv_data;
+
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed)
+{
+ unsigned long ddrphy_clk, ddr_clk, mem_speed_hz;
+
+ ddr_enable_clock();
+
+ ddrphy_clk = stm32mp1_clk_get_rate(DDRPHYC);
+
+ VERBOSE("DDR: mem_speed (%d MHz), RCC %ld MHz\n",
+ mem_speed, ddrphy_clk / 1000U / 1000U);
+
+ mem_speed_hz = (uint32_t)mem_speed * 1000U * 1000U;
+
+ /* Max 10% frequency delta */
+ if (ddrphy_clk > mem_speed_hz) {
+ ddr_clk = ddrphy_clk - mem_speed_hz;
+ } else {
+ ddr_clk = mem_speed_hz - ddrphy_clk;
+ }
+ if (ddr_clk > mem_speed_hz) {
+ ERROR("DDR expected freq %d MHz, current is %ld MHz\n",
+ mem_speed, ddrphy_clk / 1000U / 1000U);
+ return -1;
+ }
+ return 0;
+}
+
+/*******************************************************************************
+ * This function tests the DDR data bus wiring.
+ * This is inspired from the Data Bus Test algorithm written by Michael Barr
+ * in "Programming Embedded Systems in C and C++" book.
+ * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
+ * File: memtest.c - This source code belongs to Public Domain.
+ * Returns 0 if success, and address value else.
+ ******************************************************************************/
+static uint32_t ddr_test_data_bus(void)
+{
+ uint32_t pattern;
+
+ for (pattern = 1U; pattern != 0U; pattern <<= 1) {
+ mmio_write_32(STM32MP1_DDR_BASE, pattern);
+
+ if (mmio_read_32(STM32MP1_DDR_BASE) != pattern) {
+ return (uint32_t)STM32MP1_DDR_BASE;
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function tests the DDR address bus wiring.
+ * This is inspired from the Data Bus Test algorithm written by Michael Barr
+ * in "Programming Embedded Systems in C and C++" book.
+ * resources.oreilly.com/examples/9781565923546/blob/master/Chapter6/
+ * File: memtest.c - This source code belongs to Public Domain.
+ * Returns 0 if success, and address value else.
+ ******************************************************************************/
+static uint32_t ddr_test_addr_bus(void)
+{
+ uint64_t addressmask = (ddr_priv_data.info.size - 1U);
+ uint64_t offset;
+ uint64_t testoffset = 0;
+
+ /* Write the default pattern at each of the power-of-two offsets. */
+ for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+ offset <<= 1) {
+ mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)offset,
+ DDR_PATTERN);
+ }
+
+ /* Check for address bits stuck high. */
+ mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+ DDR_ANTIPATTERN);
+
+ for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+ offset <<= 1) {
+ if (mmio_read_32(STM32MP1_DDR_BASE + (uint32_t)offset) !=
+ DDR_PATTERN) {
+ return (uint32_t)(STM32MP1_DDR_BASE + offset);
+ }
+ }
+
+ mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset, DDR_PATTERN);
+
+ /* Check for address bits stuck low or shorted. */
+ for (testoffset = sizeof(uint32_t); (testoffset & addressmask) != 0U;
+ testoffset <<= 1) {
+ mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+ DDR_ANTIPATTERN);
+
+ if (mmio_read_32(STM32MP1_DDR_BASE) != DDR_PATTERN) {
+ return STM32MP1_DDR_BASE;
+ }
+
+ for (offset = sizeof(uint32_t); (offset & addressmask) != 0U;
+ offset <<= 1) {
+ if ((mmio_read_32(STM32MP1_DDR_BASE +
+ (uint32_t)offset) != DDR_PATTERN) &&
+ (offset != testoffset)) {
+ return (uint32_t)(STM32MP1_DDR_BASE + offset);
+ }
+ }
+
+ mmio_write_32(STM32MP1_DDR_BASE + (uint32_t)testoffset,
+ DDR_PATTERN);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function checks the DDR size. It has to be run with Data Cache off.
+ * This test is run before data have been put in DDR, and is only done for
+ * cold boot. The DDR data can then be overwritten, and it is not useful to
+ * restore its content.
+ * Returns DDR computed size.
+ ******************************************************************************/
+static uint32_t ddr_check_size(void)
+{
+ uint32_t offset = sizeof(uint32_t);
+
+ mmio_write_32(STM32MP1_DDR_BASE, DDR_PATTERN);
+
+ while (offset < STM32MP1_DDR_MAX_SIZE) {
+ mmio_write_32(STM32MP1_DDR_BASE + offset, DDR_ANTIPATTERN);
+ dsb();
+
+ if (mmio_read_32(STM32MP1_DDR_BASE) != DDR_PATTERN) {
+ break;
+ }
+
+ offset <<= 1;
+ }
+
+ INFO("Memory size = 0x%x (%d MB)\n", offset, offset / (1024U * 1024U));
+
+ return offset;
+}
+
+static int stm32mp1_ddr_setup(void)
+{
+ struct ddr_info *priv = &ddr_priv_data;
+ int ret;
+ struct stm32mp1_ddr_config config;
+ int node, len;
+ uint32_t tamp_clk_off = 0, uret, idx;
+ void *fdt;
+
+#define PARAM(x, y) \
+ { \
+ .name = x, \
+ .offset = offsetof(struct stm32mp1_ddr_config, y), \
+ .size = sizeof(config.y) / sizeof(uint32_t) \
+ }
+
+#define CTL_PARAM(x) PARAM("st,ctl-"#x, c_##x)
+#define PHY_PARAM(x) PARAM("st,phy-"#x, p_##x)
+
+ const struct {
+ const char *name; /* Name in DT */
+ const uint32_t offset; /* Offset in config struct */
+ const uint32_t size; /* Size of parameters */
+ } param[] = {
+ CTL_PARAM(reg),
+ CTL_PARAM(timing),
+ CTL_PARAM(map),
+ CTL_PARAM(perf),
+ PHY_PARAM(reg),
+ PHY_PARAM(timing),
+ PHY_PARAM(cal)
+ };
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+ if (node < 0) {
+ ERROR("%s: Cannot read DDR node in DT\n", __func__);
+ return -EINVAL;
+ }
+
+ config.info.speed =
+ (uint16_t)fdt_read_uint32_default(node, "st,mem-speed",
+ STM32MP1_DDR_SPEED_DFLT);
+ config.info.size = fdt_read_uint32_default(node, "st,mem-size",
+ STM32MP1_DDR_SIZE_DFLT);
+ config.info.name = fdt_getprop(fdt, node, "st,mem-name", &len);
+ if (config.info.name == NULL) {
+ VERBOSE("%s: no st,mem-name\n", __func__);
+ return -EINVAL;
+ }
+ INFO("RAM: %s\n", config.info.name);
+
+ for (idx = 0; idx < ARRAY_SIZE(param); idx++) {
+ ret = fdt_read_uint32_array(node, param[idx].name,
+ (void *)((uint32_t)&config +
+ param[idx].offset),
+ param[idx].size);
+
+ VERBOSE("%s: %s[0x%x] = %d\n", __func__,
+ param[idx].name, param[idx].size, ret);
+ if (ret != 0) {
+ ERROR("%s: Cannot read %s\n",
+ __func__, param[idx].name);
+ return -EINVAL;
+ }
+ }
+
+ if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+ tamp_clk_off = 1;
+ if (stm32mp1_clk_enable(RTCAPB) != 0) {
+ return -EINVAL;
+ }
+ }
+
+ if (tamp_clk_off != 0U) {
+ if (stm32mp1_clk_disable(RTCAPB) != 0) {
+ return -EINVAL;
+ }
+ }
+
+ /* Disable axidcg clock gating during init */
+ mmio_clrbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
+
+ stm32mp1_ddr_init(priv, &config);
+
+ /* Enable axidcg clock gating */
+ mmio_setbits_32(priv->rcc + RCC_DDRITFCR, RCC_DDRITFCR_AXIDCGEN);
+
+ priv->info.size = config.info.size;
+
+ VERBOSE("%s : ram size(%x, %x)\n", __func__,
+ (uint32_t)priv->info.base, (uint32_t)priv->info.size);
+
+ dcsw_op_all(DC_OP_CISW);
+ write_sctlr(read_sctlr() & ~SCTLR_C_BIT);
+
+ uret = ddr_test_data_bus();
+ if (uret != 0U) {
+ ERROR("DDR data bus test: can't access memory @ 0x%x\n",
+ uret);
+ panic();
+ }
+
+ uret = ddr_test_addr_bus();
+ if (uret != 0U) {
+ ERROR("DDR addr bus test: can't access memory @ 0x%x\n",
+ uret);
+ panic();
+ }
+
+ uret = ddr_check_size();
+ if (uret < config.info.size) {
+ ERROR("DDR size: 0x%x does not match DT config: 0x%x\n",
+ uret, config.info.size);
+ panic();
+ }
+
+ write_sctlr(read_sctlr() | SCTLR_C_BIT);
+
+ return 0;
+}
+
+int stm32mp1_ddr_probe(void)
+{
+ struct ddr_info *priv = &ddr_priv_data;
+
+ VERBOSE("STM32MP DDR probe\n");
+
+ priv->ctl = (struct stm32mp1_ddrctl *)DDRCTRL_BASE;
+ priv->phy = (struct stm32mp1_ddrphy *)DDRPHYC_BASE;
+ priv->pwr = PWR_BASE;
+ priv->rcc = RCC_BASE;
+
+ priv->info.base = STM32MP1_DDR_BASE;
+ priv->info.size = 0;
+
+ return stm32mp1_ddr_setup();
+}
diff --git a/drivers/st/gpio/stm32_gpio.c b/drivers/st/gpio/stm32_gpio.c
new file mode 100644
index 000000000..200b47340
--- /dev/null
+++ b/drivers/st/gpio/stm32_gpio.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <stm32_gpio.h>
+
+static bool check_gpio(uint32_t bank, uint32_t pin)
+{
+ if (pin > GPIO_PIN_MAX) {
+ ERROR("%s: wrong pin number (%d)\n", __func__, pin);
+ return false;
+ }
+
+ if ((bank > GPIO_BANK_K) && (bank != GPIO_BANK_Z)) {
+ ERROR("%s: wrong GPIO bank number (%d)\n", __func__, bank);
+ return false;
+ }
+
+ return true;
+}
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+ uint32_t pull, uint32_t alternate)
+{
+ volatile uint32_t bank_address;
+
+ if (!check_gpio(bank, pin)) {
+ return;
+ }
+
+ if (bank == GPIO_BANK_Z) {
+ bank_address = STM32_GPIOZ_BANK;
+ } else {
+ bank_address = STM32_GPIOA_BANK +
+ (bank * STM32_GPIO_BANK_OFFSET);
+ }
+
+ mmio_clrbits_32(bank_address + GPIO_MODE_OFFSET,
+ ((uint32_t)GPIO_MODE_MASK << (pin << 1)));
+ mmio_setbits_32(bank_address + GPIO_MODE_OFFSET,
+ (mode & ~GPIO_OPEN_DRAIN) << (pin << 1));
+
+ if ((mode & GPIO_OPEN_DRAIN) != 0U) {
+ mmio_setbits_32(bank_address + GPIO_TYPE_OFFSET,
+ BIT(pin));
+ }
+
+ mmio_clrbits_32(bank_address + GPIO_SPEED_OFFSET,
+ ((uint32_t)GPIO_SPEED_MASK << (pin << 1)));
+ mmio_setbits_32(bank_address + GPIO_SPEED_OFFSET, speed << (pin << 1));
+
+ mmio_clrbits_32(bank_address + GPIO_PUPD_OFFSET,
+ ((uint32_t)GPIO_PULL_MASK << (pin << 1)));
+ mmio_setbits_32(bank_address + GPIO_PUPD_OFFSET, pull << (pin << 1));
+
+ if (pin < GPIO_ALT_LOWER_LIMIT) {
+ mmio_clrbits_32(bank_address + GPIO_AFRL_OFFSET,
+ ((uint32_t)GPIO_ALTERNATE_MASK << (pin << 2)));
+ mmio_setbits_32(bank_address + GPIO_AFRL_OFFSET,
+ alternate << (pin << 2));
+ } else {
+ mmio_clrbits_32(bank_address + GPIO_AFRH_OFFSET,
+ ((uint32_t)GPIO_ALTERNATE_MASK <<
+ ((pin - GPIO_ALT_LOWER_LIMIT) << 2)));
+ mmio_setbits_32(bank_address + GPIO_AFRH_OFFSET,
+ alternate << ((pin - GPIO_ALT_LOWER_LIMIT) <<
+ 2));
+ }
+
+ VERBOSE("GPIO %u mode set to 0x%x\n", bank,
+ mmio_read_32(bank_address + GPIO_MODE_OFFSET));
+ VERBOSE("GPIO %u speed set to 0x%x\n", bank,
+ mmio_read_32(bank_address + GPIO_SPEED_OFFSET));
+ VERBOSE("GPIO %u mode pull to 0x%x\n", bank,
+ mmio_read_32(bank_address + GPIO_PUPD_OFFSET));
+ VERBOSE("GPIO %u mode alternate low to 0x%x\n", bank,
+ mmio_read_32(bank_address + GPIO_AFRL_OFFSET));
+ VERBOSE("GPIO %u mode alternate high to 0x%x\n", bank,
+ mmio_read_32(bank_address + GPIO_AFRH_OFFSET));
+}
diff --git a/drivers/st/pmic/stm32_i2c.c b/drivers/st/pmic/stm32_i2c.c
new file mode 100644
index 000000000..098013947
--- /dev/null
+++ b/drivers/st/pmic/stm32_i2c.c
@@ -0,0 +1,851 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stm32_i2c.h>
+
+/* STM32 I2C registers offsets */
+#define I2C_CR1 0x00U
+#define I2C_CR2 0x04U
+#define I2C_OAR1 0x08U
+#define I2C_OAR2 0x0CU
+#define I2C_TIMINGR 0x10U
+#define I2C_TIMEOUTR 0x14U
+#define I2C_ISR 0x18U
+#define I2C_ICR 0x1CU
+#define I2C_PECR 0x20U
+#define I2C_RXDR 0x24U
+#define I2C_TXDR 0x28U
+
+#define MAX_DELAY 0xFFFFFFFFU
+
+/* I2C TIMING clear register Mask */
+#define TIMING_CLEAR_MASK 0xF0FFFFFFU
+/* Timeout 25 ms */
+#define I2C_TIMEOUT_BUSY 25U
+
+#define MAX_NBYTE_SIZE 255U
+
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+ uint16_t dev_addr, uint16_t mem_addr,
+ uint16_t mem_add_size, uint32_t timeout,
+ uint32_t tick_start);
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint32_t timeout, uint32_t tick_start);
+
+/* Private functions to handle flags during polling transfer */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+ uint8_t awaited_value, uint32_t timeout,
+ uint32_t tick_start);
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start);
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start);
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start);
+
+/* Private function to flush TXDR register */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c);
+
+/* Private function to start, restart or stop a transfer */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t size, uint32_t i2c_mode,
+ uint32_t request);
+
+/*
+ * @brief Initialize the I2C device.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_init(struct i2c_handle_s *hi2c)
+{
+ if (hi2c == NULL) {
+ return -ENOENT;
+ }
+
+ if (hi2c->i2c_state == I2C_STATE_RESET) {
+ hi2c->lock = 0;
+ }
+
+ hi2c->i2c_state = I2C_STATE_BUSY;
+
+ /* Disable the selected I2C peripheral */
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+ /* Configure I2Cx: Frequency range */
+ mmio_write_32(hi2c->i2c_base_addr + I2C_TIMINGR,
+ hi2c->i2c_init.timing & TIMING_CLEAR_MASK);
+
+ /* Disable Own Address1 before set the Own Address1 configuration */
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR1, I2C_OAR1_OA1EN);
+
+ /* Configure I2Cx: Own Address1 and ack own address1 mode */
+ if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+ mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+ I2C_OAR1_OA1EN | hi2c->i2c_init.own_address1);
+ } else { /* I2C_ADDRESSINGMODE_10BIT */
+ mmio_write_32(hi2c->i2c_base_addr + I2C_OAR1,
+ I2C_OAR1_OA1EN | I2C_OAR1_OA1MODE |
+ hi2c->i2c_init.own_address1);
+ }
+
+ /* Configure I2Cx: Addressing Master mode */
+ if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_10BIT) {
+ mmio_write_32(hi2c->i2c_base_addr + I2C_CR2, I2C_CR2_ADD10);
+ }
+
+ /*
+ * Enable the AUTOEND by default, and enable NACK
+ * (should be disable only during Slave process)
+ */
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+ I2C_CR2_AUTOEND | I2C_CR2_NACK);
+
+ /* Disable Own Address2 before set the Own Address2 configuration */
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_OAR2, I2C_DUALADDRESS_ENABLE);
+
+ /* Configure I2Cx: Dual mode and Own Address2 */
+ mmio_write_32(hi2c->i2c_base_addr + I2C_OAR2,
+ hi2c->i2c_init.dual_address_mode |
+ hi2c->i2c_init.own_address2 |
+ (hi2c->i2c_init.own_address2_masks << 8));
+
+ /* Configure I2Cx: Generalcall and NoStretch mode */
+ mmio_write_32(hi2c->i2c_base_addr + I2C_CR1,
+ hi2c->i2c_init.general_call_mode |
+ hi2c->i2c_init.no_stretch_mode);
+
+ /* Enable the selected I2C peripheral */
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+ hi2c->i2c_err = I2C_ERROR_NONE;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ return 0;
+}
+
+/*
+ * @brief Write an amount of data in blocking mode to a specific memory address
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param dev_addr: Target device address
+ * @param mem_addr: Internal memory address
+ * @param mem_add_size: size of internal memory address
+ * @param p_data: Pointer to data buffer
+ * @param size: Amount of data to be sent
+ * @param timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+ uint32_t tickstart;
+
+ if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+ return -EBUSY;
+ }
+
+ if ((p_data == NULL) || (size == 0U)) {
+ return -EINVAL;
+ }
+
+ hi2c->lock = 1;
+
+ tickstart = (uint32_t)read_cntpct_el0();
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ hi2c->i2c_state = I2C_STATE_BUSY_TX;
+ hi2c->i2c_mode = I2C_MODE_MEM;
+ hi2c->i2c_err = I2C_ERROR_NONE;
+
+ hi2c->p_buff = p_data;
+ hi2c->xfer_count = size;
+
+ /* Send Slave Address and Memory Address */
+ if (i2c_request_memory_write(hi2c, dev_addr, mem_addr, mem_add_size,
+ timeout, tickstart) != 0) {
+ hi2c->lock = 0;
+ return -EIO;
+ }
+
+ /*
+ * Set NBYTES to write and reload
+ * if hi2c->xfer_count > MAX_NBYTE_SIZE
+ */
+ if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+ hi2c->xfer_size = MAX_NBYTE_SIZE;
+ i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+ I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
+ } else {
+ hi2c->xfer_size = hi2c->xfer_count;
+ i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+ I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
+ }
+
+ do {
+ if (i2c_wait_txis(hi2c, timeout, tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR, *hi2c->p_buff);
+ hi2c->p_buff++;
+ hi2c->xfer_count--;
+ hi2c->xfer_size--;
+
+ if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+ /* Wait until TCR flag is set */
+ if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+ hi2c->xfer_size = MAX_NBYTE_SIZE;
+ i2c_transfer_config(hi2c, dev_addr,
+ hi2c->xfer_size,
+ I2C_RELOAD_MODE,
+ I2C_NO_STARTSTOP);
+ } else {
+ hi2c->xfer_size = hi2c->xfer_count;
+ i2c_transfer_config(hi2c, dev_addr,
+ hi2c->xfer_size,
+ I2C_AUTOEND_MODE,
+ I2C_NO_STARTSTOP);
+ }
+ }
+
+ } while (hi2c->xfer_count > 0U);
+
+ /*
+ * No need to Check TC flag, with AUTOEND mode the stop
+ * is automatically generated.
+ * Wait until STOPF flag is reset.
+ */
+ if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return 0;
+}
+
+/*
+ * @brief Read an amount of data in blocking mode from a specific memory
+ * address
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param dev_addr: Target device address
+ * @param mem_addr: Internal memory address
+ * @param mem_add_size: size of internal memory address
+ * @param p_data: Pointer to data buffer
+ * @param size: Amount of data to be sent
+ * @param timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+ uint32_t tickstart;
+
+ if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+ return -EBUSY;
+ }
+
+ if ((p_data == NULL) || (size == 0U)) {
+ return -EINVAL;
+ }
+
+ hi2c->lock = 1;
+
+ tickstart = (uint32_t)read_cntpct_el0();
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_BUSY, 1, I2C_TIMEOUT_BUSY,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ hi2c->i2c_state = I2C_STATE_BUSY_RX;
+ hi2c->i2c_mode = I2C_MODE_MEM;
+ hi2c->i2c_err = I2C_ERROR_NONE;
+
+ hi2c->p_buff = p_data;
+ hi2c->xfer_count = size;
+
+ /* Send Slave Address and Memory Address */
+ if (i2c_request_memory_read(hi2c, dev_addr, mem_addr, mem_add_size,
+ timeout, tickstart) != 0) {
+ hi2c->lock = 0;
+ return -EIO;
+ }
+
+ /*
+ * Send Slave Address.
+ * Set NBYTES to write and reload if hi2c->xfer_count > MAX_NBYTE_SIZE
+ * and generate RESTART.
+ */
+ if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+ hi2c->xfer_size = MAX_NBYTE_SIZE;
+ i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+ I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
+ } else {
+ hi2c->xfer_size = hi2c->xfer_count;
+ i2c_transfer_config(hi2c, dev_addr, hi2c->xfer_size,
+ I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
+ }
+
+ do {
+ if (i2c_wait_flag(hi2c, I2C_FLAG_RXNE, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ *hi2c->p_buff = mmio_read_8(hi2c->i2c_base_addr + I2C_RXDR);
+ hi2c->p_buff++;
+ hi2c->xfer_size--;
+ hi2c->xfer_count--;
+
+ if ((hi2c->xfer_count != 0U) && (hi2c->xfer_size == 0U)) {
+ if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ if (hi2c->xfer_count > MAX_NBYTE_SIZE) {
+ hi2c->xfer_size = MAX_NBYTE_SIZE;
+ i2c_transfer_config(hi2c, dev_addr,
+ hi2c->xfer_size,
+ I2C_RELOAD_MODE,
+ I2C_NO_STARTSTOP);
+ } else {
+ hi2c->xfer_size = hi2c->xfer_count;
+ i2c_transfer_config(hi2c, dev_addr,
+ hi2c->xfer_size,
+ I2C_AUTOEND_MODE,
+ I2C_NO_STARTSTOP);
+ }
+ }
+ } while (hi2c->xfer_count > 0U);
+
+ /*
+ * No need to Check TC flag, with AUTOEND mode the stop
+ * is automatically generated
+ * Wait until STOPF flag is reset
+ */
+ if (i2c_wait_stop(hi2c, timeout, tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return 0;
+}
+
+/*
+ * @brief Checks if target device is ready for communication.
+ * @note This function is used with Memory devices
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param dev_addr: Target device address
+ * @param trials: Number of trials
+ * @param timeout: timeout duration
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c,
+ uint16_t dev_addr, uint32_t trials,
+ uint32_t timeout)
+{
+ uint32_t i2c_trials = 0U;
+
+ if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+ return -EBUSY;
+ }
+
+ if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_BUSY) !=
+ 0U) {
+ return -EBUSY;
+ }
+
+ hi2c->lock = 1;
+
+ hi2c->i2c_state = I2C_STATE_BUSY;
+ hi2c->i2c_err = I2C_ERROR_NONE;
+
+ do {
+ uint32_t tickstart;
+
+ /* Generate Start */
+ if (hi2c->i2c_init.addressing_mode == I2C_ADDRESSINGMODE_7BIT) {
+ mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+ (((uint32_t)dev_addr & I2C_CR2_SADD) |
+ I2C_CR2_START | I2C_CR2_AUTOEND) &
+ ~I2C_CR2_RD_WRN);
+ } else {
+ mmio_write_32(hi2c->i2c_base_addr + I2C_CR2,
+ (((uint32_t)dev_addr & I2C_CR2_SADD) |
+ I2C_CR2_START | I2C_CR2_ADD10) &
+ ~I2C_CR2_RD_WRN);
+ }
+
+ /*
+ * No need to Check TC flag, with AUTOEND mode the stop
+ * is automatically generated
+ * Wait until STOPF flag is set or a NACK flag is set
+ */
+ tickstart = (uint32_t)read_cntpct_el0();
+ while (((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ (I2C_FLAG_STOPF | I2C_FLAG_AF)) == 0U) &&
+ (hi2c->i2c_state != I2C_STATE_TIMEOUT)) {
+ if (timeout != MAX_DELAY) {
+ if ((((uint32_t)read_cntpct_el0() - tickstart) >
+ timeout) || (timeout == 0U)) {
+ hi2c->i2c_state = I2C_STATE_READY;
+
+ hi2c->i2c_err |=
+ I2C_ERROR_TIMEOUT;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+ }
+ }
+ }
+
+ /* Check if the NACKF flag has not been set */
+ if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ I2C_FLAG_AF) == 0U) {
+ if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+ I2C_FLAG_STOPF);
+
+ hi2c->i2c_state = I2C_STATE_READY;
+
+ hi2c->lock = 0;
+
+ return 0;
+ }
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+ if (i2c_trials == trials) {
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR2,
+ I2C_CR2_STOP);
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_STOPF, 0, timeout,
+ tickstart) != 0) {
+ return -EIO;
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR,
+ I2C_FLAG_STOPF);
+ }
+
+ i2c_trials++;
+ } while (i2c_trials < trials);
+
+ hi2c->i2c_state = I2C_STATE_READY;
+
+ hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+}
+
+/*
+ * @brief Master sends target device address followed by internal memory
+ * address for write request.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param dev_addr: Target device address
+ * @param mem_addr: Internal memory address
+ * @param mem_add_size: size of internal memory address
+ * @param timeout: timeout duration
+ * @param tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_write(struct i2c_handle_s *hi2c,
+ uint16_t dev_addr, uint16_t mem_addr,
+ uint16_t mem_add_size, uint32_t timeout,
+ uint32_t tick_start)
+{
+ i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_RELOAD_MODE,
+ I2C_GENERATE_START_WRITE);
+
+ if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+ /* Send Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)(mem_addr & 0x00FFU));
+ } else {
+ /* Send MSB of Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+ /* Wait until TXIS flag is set */
+ if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ /* Send LSB of Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)(mem_addr & 0x00FFU));
+ }
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_TCR, 0, timeout, tick_start) !=
+ 0) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * @brief Master sends target device address followed by internal memory
+ * address for read request.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param dev_addr: Target device address
+ * @param mem_addr: Internal memory address
+ * @param mem_add_size: size of internal memory address
+ * @param timeout: timeout duration
+ * @param tick_start Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_request_memory_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint32_t timeout, uint32_t tick_start)
+{
+ i2c_transfer_config(hi2c, dev_addr, mem_add_size, I2C_SOFTEND_MODE,
+ I2C_GENERATE_START_WRITE);
+
+ if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ if (mem_add_size == I2C_MEMADD_SIZE_8BIT) {
+ /* Send Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)(mem_addr & 0x00FFU));
+ } else {
+ /* Send MSB of Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)((mem_addr & 0xFF00U) >> 8));
+
+ /* Wait until TXIS flag is set */
+ if (i2c_wait_txis(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ /* Send LSB of Memory Address */
+ mmio_write_8(hi2c->i2c_base_addr + I2C_TXDR,
+ (uint8_t)(mem_addr & 0x00FFU));
+ }
+
+ if (i2c_wait_flag(hi2c, I2C_FLAG_TC, 0, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/*
+ * @brief I2C Tx data register flush process.
+ * @param hi2c: I2C handle.
+ * @retval None
+ */
+static void i2c_flush_txdr(struct i2c_handle_s *hi2c)
+{
+ /*
+ * If a pending TXIS flag is set,
+ * write a dummy data in TXDR to clear it.
+ */
+ if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXIS) !=
+ 0U) {
+ mmio_write_32(hi2c->i2c_base_addr + I2C_TXDR, 0);
+ }
+
+ /* Flush TX register if not empty */
+ if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_TXE) ==
+ 0U) {
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_ISR,
+ I2C_FLAG_TXE);
+ }
+}
+
+/*
+ * @brief This function handles I2C Communication timeout.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param flag: Specifies the I2C flag to check.
+ * @param awaited_value: The awaited bit value for the flag (0 or 1).
+ * @param timeout: timeout duration
+ * @param tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_flag(struct i2c_handle_s *hi2c, uint32_t flag,
+ uint8_t awaited_value, uint32_t timeout,
+ uint32_t tick_start)
+{
+ uint8_t flag_check;
+
+ do {
+ flag_check = ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ flag) == flag) ? 1U : 0U;
+
+ if (timeout != MAX_DELAY) {
+ if ((((uint32_t)read_cntpct_el0() - tick_start) >
+ timeout) || (timeout == 0U)) {
+ hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+ return -EIO;
+ }
+ }
+ } while (flag_check == awaited_value);
+
+ return 0;
+}
+
+/*
+ * @brief This function handles I2C Communication timeout for specific usage
+ * of TXIS flag.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param timeout: timeout duration
+ * @param tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_txis(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start)
+{
+ while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ I2C_FLAG_TXIS) == 0U) {
+ if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ if (timeout != MAX_DELAY) {
+ if ((((uint32_t)read_cntpct_el0() - tick_start) >
+ timeout) || (timeout == 0U)) {
+ hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * @brief This function handles I2C Communication timeout for specific
+ * usage of STOP flag.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param timeout: timeout duration
+ * @param tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_wait_stop(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start)
+{
+ while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ I2C_FLAG_STOPF) == 0U) {
+ if (i2c_ack_failed(hi2c, timeout, tick_start) != 0) {
+ return -EIO;
+ }
+
+ if ((((uint32_t)read_cntpct_el0() - tick_start) > timeout) ||
+ (timeout == 0U)) {
+ hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * @brief This function handles Acknowledge failed detection during
+ * an I2C Communication.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2C.
+ * @param timeout: timeout duration
+ * @param tick_start: Tick start value
+ * @retval 0 if OK, negative value else
+ */
+static int i2c_ack_failed(struct i2c_handle_s *hi2c, uint32_t timeout,
+ uint32_t tick_start)
+{
+ if ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) & I2C_FLAG_AF) == 0U) {
+ return 0;
+ }
+
+ /*
+ * Wait until STOP Flag is reset.
+ * AutoEnd should be initiate after AF.
+ */
+ while ((mmio_read_32(hi2c->i2c_base_addr + I2C_ISR) &
+ I2C_FLAG_STOPF) == 0U) {
+ if (timeout != MAX_DELAY) {
+ if ((((uint32_t)read_cntpct_el0() - tick_start) >
+ timeout) || (timeout == 0U)) {
+ hi2c->i2c_err |= I2C_ERROR_TIMEOUT;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+ }
+ }
+ }
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_AF);
+
+ mmio_write_32(hi2c->i2c_base_addr + I2C_ICR, I2C_FLAG_STOPF);
+
+ i2c_flush_txdr(hi2c);
+
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR2, I2C_RESET_CR2);
+
+ hi2c->i2c_err |= I2C_ERROR_AF;
+ hi2c->i2c_state = I2C_STATE_READY;
+ hi2c->i2c_mode = I2C_MODE_NONE;
+
+ hi2c->lock = 0;
+
+ return -EIO;
+}
+
+/*
+ * @brief Handles I2Cx communication when starting transfer or during transfer
+ * (TC or TCR flag are set).
+ * @param hi2c: I2C handle.
+ * @param dev_addr: Specifies the slave address to be programmed.
+ * @param size: Specifies the number of bytes to be programmed.
+ * This parameter must be a value between 0 and 255.
+ * @param i2c_mode: New state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg @ref I2C_RELOAD_MODE: Enable Reload mode .
+ * @arg @ref I2C_AUTOEND_MODE: Enable Automatic end mode.
+ * @arg @ref I2C_SOFTEND_MODE: Enable Software end mode.
+ * @param request: New state of the I2C START condition generation.
+ * This parameter can be one of the following values:
+ * @arg @ref I2C_NO_STARTSTOP: Don't Generate stop and start condition.
+ * @arg @ref I2C_GENERATE_STOP: Generate stop condition
+ * (size should be set to 0).
+ * @arg @ref I2C_GENERATE_START_READ: Generate Restart for read request.
+ * @arg @ref I2C_GENERATE_START_WRITE: Generate Restart for write request.
+ * @retval None
+ */
+static void i2c_transfer_config(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t size, uint32_t i2c_mode,
+ uint32_t request)
+{
+ uint32_t clr_value, set_value;
+
+ clr_value = (I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD |
+ I2C_CR2_AUTOEND | I2C_CR2_START | I2C_CR2_STOP) |
+ (I2C_CR2_RD_WRN & (request >> (31U - I2C_CR2_RD_WRN_OFFSET)));
+
+ set_value = ((uint32_t)dev_addr & I2C_CR2_SADD) |
+ (((uint32_t)size << I2C_CR2_NBYTES_OFFSET) & I2C_CR2_NBYTES) |
+ i2c_mode | request;
+
+ mmio_clrsetbits_32(hi2c->i2c_base_addr + I2C_CR2, clr_value, set_value);
+}
+
+/*
+ * @brief Configure I2C Analog noise filter.
+ * @param hi2c: Pointer to a struct i2c_handle_s structure that contains
+ * the configuration information for the specified I2Cx peripheral
+ * @param analog_filter: New state of the Analog filter.
+ * @retval 0 if OK, negative value else
+ */
+int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
+ uint32_t analog_filter)
+{
+ if ((hi2c->i2c_state != I2C_STATE_READY) || (hi2c->lock != 0U)) {
+ return -EBUSY;
+ }
+
+ hi2c->lock = 1;
+
+ hi2c->i2c_state = I2C_STATE_BUSY;
+
+ /* Disable the selected I2C peripheral */
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+ /* Reset I2Cx ANOFF bit */
+ mmio_clrbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_ANFOFF);
+
+ /* Set analog filter bit*/
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, analog_filter);
+
+ /* Enable the selected I2C peripheral */
+ mmio_setbits_32(hi2c->i2c_base_addr + I2C_CR1, I2C_CR1_PE);
+
+ hi2c->i2c_state = I2C_STATE_READY;
+
+ hi2c->lock = 0;
+
+ return 0;
+}
diff --git a/drivers/st/pmic/stm32mp1_pmic.c b/drivers/st/pmic/stm32mp1_pmic.c
new file mode 100644
index 000000000..958de08d9
--- /dev/null
+++ b/drivers/st/pmic/stm32mp1_pmic.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <mmio.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stpmu1.h>
+#include <utils_def.h>
+
+/* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */
+#define I2C_TIMING 0x10D07DB5
+
+#define I2C_TIMEOUT 0xFFFFF
+
+#define MASK_RESET_BUCK3 BIT(2)
+
+#define STPMU1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2))
+#define STPMU1_LDO12356_OUTPUT_SHIFT 2
+#define STPMU1_LDO3_MODE (uint8_t)(BIT(7))
+#define STPMU1_LDO3_DDR_SEL 31U
+#define STPMU1_LDO3_1800000 (9U << STPMU1_LDO12356_OUTPUT_SHIFT)
+
+#define STPMU1_BUCK_OUTPUT_SHIFT 2
+#define STPMU1_BUCK3_1V8 (39U << STPMU1_BUCK_OUTPUT_SHIFT)
+
+#define STPMU1_DEFAULT_START_UP_DELAY_MS 1
+
+static struct i2c_handle_s i2c_handle;
+static uint32_t pmic_i2c_addr;
+
+static int dt_get_pmic_node(void *fdt)
+{
+ return fdt_node_offset_by_compatible(fdt, -1, "st,stpmu1");
+}
+
+bool dt_check_pmic(void)
+{
+ int node;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return false;
+ }
+
+ node = dt_get_pmic_node(fdt);
+ if (node < 0) {
+ VERBOSE("%s: No PMIC node found in DT\n", __func__);
+ return false;
+ }
+
+ return fdt_check_status(node);
+}
+
+static int dt_pmic_i2c_config(struct dt_node_info *i2c_info)
+{
+ int pmic_node, i2c_node;
+ void *fdt;
+ const fdt32_t *cuint;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ pmic_node = dt_get_pmic_node(fdt);
+ if (pmic_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint = fdt_getprop(fdt, pmic_node, "reg", NULL);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1;
+ if (pmic_i2c_addr > UINT16_MAX) {
+ return -EINVAL;
+ }
+
+ i2c_node = fdt_parent_offset(fdt, pmic_node);
+ if (i2c_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ dt_fill_device_info(i2c_info, i2c_node);
+ if (i2c_info->base == 0U) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return dt_set_pinctrl_config(i2c_node);
+}
+
+int dt_pmic_enable_boot_on_regulators(void)
+{
+ int pmic_node, regulators_node, regulator_node;
+ void *fdt;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -ENOENT;
+ }
+
+ pmic_node = dt_get_pmic_node(fdt);
+ if (pmic_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators");
+
+ fdt_for_each_subnode(regulator_node, fdt, regulators_node) {
+ const fdt32_t *cuint;
+ const char *node_name;
+ uint16_t voltage;
+
+ if (fdt_getprop(fdt, regulator_node, "regulator-boot-on",
+ NULL) == NULL) {
+ continue;
+ }
+
+ cuint = fdt_getprop(fdt, regulator_node,
+ "regulator-min-microvolt", NULL);
+ if (cuint == NULL) {
+ continue;
+ }
+
+ /* DT uses microvolts, whereas driver awaits millivolts */
+ voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U);
+ node_name = fdt_get_name(fdt, regulator_node, NULL);
+
+ if (stpmu1_is_regulator_enabled(node_name) == 0U) {
+ int status;
+
+ status = stpmu1_regulator_voltage_set(node_name,
+ voltage);
+ if (status != 0) {
+ return status;
+ }
+
+ status = stpmu1_regulator_enable(node_name);
+ if (status != 0) {
+ return status;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void initialize_pmic_i2c(void)
+{
+ int ret;
+ struct dt_node_info i2c_info;
+
+ if (dt_pmic_i2c_config(&i2c_info) != 0) {
+ ERROR("I2C configuration failed\n");
+ panic();
+ }
+
+ if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) {
+ ERROR("I2C clock enable failed\n");
+ panic();
+ }
+
+ /* Initialize PMIC I2C */
+ i2c_handle.i2c_base_addr = i2c_info.base;
+ i2c_handle.i2c_init.timing = I2C_TIMING;
+ i2c_handle.i2c_init.own_address1 = pmic_i2c_addr;
+ i2c_handle.i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT;
+ i2c_handle.i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE;
+ i2c_handle.i2c_init.own_address2 = 0;
+ i2c_handle.i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK;
+ i2c_handle.i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE;
+ i2c_handle.i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE;
+
+ ret = stm32_i2c_init(&i2c_handle);
+ if (ret != 0) {
+ ERROR("Cannot initialize I2C %x (%d)\n",
+ i2c_handle.i2c_base_addr, ret);
+ panic();
+ }
+
+ ret = stm32_i2c_config_analog_filter(&i2c_handle,
+ I2C_ANALOGFILTER_ENABLE);
+ if (ret != 0) {
+ ERROR("Cannot initialize I2C analog filter (%d)\n", ret);
+ panic();
+ }
+
+ ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1,
+ I2C_TIMEOUT);
+ if (ret != 0) {
+ ERROR("I2C device not ready (%d)\n", ret);
+ panic();
+ }
+
+ stpmu1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr);
+}
+
+void initialize_pmic(void)
+{
+ int status;
+ uint8_t read_val;
+
+ initialize_pmic_i2c();
+
+ status = stpmu1_register_read(VERSION_STATUS_REG, &read_val);
+ if (status != 0) {
+ panic();
+ }
+
+ INFO("PMIC version = 0x%x\n", read_val);
+
+ /* Keep VDD on during the reset cycle */
+ status = stpmu1_register_update(MASK_RESET_BUCK_REG,
+ MASK_RESET_BUCK3,
+ MASK_RESET_BUCK3);
+ if (status != 0) {
+ panic();
+ }
+}
+
+int pmic_ddr_power_init(enum ddr_type ddr_type)
+{
+ bool buck3_at_1v8 = false;
+ uint8_t read_val;
+ int status;
+
+ switch (ddr_type) {
+ case STM32MP_DDR3:
+ /* Set LDO3 to sync mode */
+ status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+ if (status != 0) {
+ return status;
+ }
+
+ read_val &= ~STPMU1_LDO3_MODE;
+ read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
+ read_val |= STPMU1_LDO3_DDR_SEL << STPMU1_LDO12356_OUTPUT_SHIFT;
+
+ status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+ if (status != 0) {
+ return status;
+ }
+
+ status = stpmu1_regulator_voltage_set("buck2", 1350);
+ if (status != 0) {
+ return status;
+ }
+
+ status = stpmu1_regulator_enable("buck2");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+ status = stpmu1_regulator_enable("vref_ddr");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+ status = stpmu1_regulator_enable("ldo3");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ break;
+
+ case STM32MP_LPDDR2:
+ /*
+ * Set LDO3 to 1.8V
+ * Set LDO3 to bypass mode if BUCK3 = 1.8V
+ * Set LDO3 to normal mode if BUCK3 != 1.8V
+ */
+ status = stpmu1_register_read(BUCK3_CONTROL_REG, &read_val);
+ if (status != 0) {
+ return status;
+ }
+
+ if ((read_val & STPMU1_BUCK3_1V8) == STPMU1_BUCK3_1V8) {
+ buck3_at_1v8 = true;
+ }
+
+ status = stpmu1_register_read(LDO3_CONTROL_REG, &read_val);
+ if (status != 0) {
+ return status;
+ }
+
+ read_val &= ~STPMU1_LDO3_MODE;
+ read_val &= ~STPMU1_LDO12356_OUTPUT_MASK;
+ read_val |= STPMU1_LDO3_1800000;
+ if (buck3_at_1v8) {
+ read_val |= STPMU1_LDO3_MODE;
+ }
+
+ status = stpmu1_register_write(LDO3_CONTROL_REG, read_val);
+ if (status != 0) {
+ return status;
+ }
+
+ status = stpmu1_regulator_voltage_set("buck2", 1200);
+ if (status != 0) {
+ return status;
+ }
+
+ status = stpmu1_regulator_enable("ldo3");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+ status = stpmu1_regulator_enable("buck2");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+
+ status = stpmu1_regulator_enable("vref_ddr");
+ if (status != 0) {
+ return status;
+ }
+
+ mdelay(STPMU1_DEFAULT_START_UP_DELAY_MS);
+ break;
+
+ default:
+ break;
+ };
+
+ return 0;
+}
diff --git a/drivers/st/pmic/stpmu1.c b/drivers/st/pmic/stpmu1.c
new file mode 100644
index 000000000..5951899a1
--- /dev/null
+++ b/drivers/st/pmic/stpmu1.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <platform.h>
+#include <stpmu1.h>
+#include <string.h>
+
+struct regul_struct {
+ const char *dt_node_name;
+ const uint16_t *voltage_table;
+ uint8_t voltage_table_size;
+ uint8_t control_reg;
+ uint8_t low_power_reg;
+};
+
+static struct i2c_handle_s *stpmu_i2c_handle;
+static uint16_t stpmu_i2c_addr;
+
+/* Voltage tables in mV */
+static const uint16_t buck1_voltage_table[] = {
+ 600,
+ 625,
+ 650,
+ 675,
+ 700,
+ 725,
+ 750,
+ 775,
+ 800,
+ 825,
+ 850,
+ 875,
+ 900,
+ 925,
+ 950,
+ 975,
+ 1000,
+ 1025,
+ 1050,
+ 1075,
+ 1100,
+ 1125,
+ 1150,
+ 1175,
+ 1200,
+ 1225,
+ 1250,
+ 1275,
+ 1300,
+ 1325,
+ 1350,
+ 1350,
+};
+
+static const uint16_t buck2_voltage_table[] = {
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1050,
+ 1050,
+ 1100,
+ 1100,
+ 1150,
+ 1150,
+ 1200,
+ 1200,
+ 1250,
+ 1250,
+ 1300,
+ 1300,
+ 1350,
+ 1350,
+ 1400,
+ 1400,
+ 1450,
+ 1450,
+ 1500,
+};
+
+static const uint16_t buck3_voltage_table[] = {
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1000,
+ 1100,
+ 1100,
+ 1100,
+ 1100,
+ 1200,
+ 1200,
+ 1200,
+ 1200,
+ 1300,
+ 1300,
+ 1300,
+ 1300,
+ 1400,
+ 1400,
+ 1400,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+};
+
+static const uint16_t buck4_voltage_table[] = {
+ 600,
+ 625,
+ 650,
+ 675,
+ 700,
+ 725,
+ 750,
+ 775,
+ 800,
+ 825,
+ 850,
+ 875,
+ 900,
+ 925,
+ 950,
+ 975,
+ 1000,
+ 1025,
+ 1050,
+ 1075,
+ 1100,
+ 1125,
+ 1150,
+ 1175,
+ 1200,
+ 1225,
+ 1250,
+ 1275,
+ 1300,
+ 1300,
+ 1350,
+ 1350,
+ 1400,
+ 1400,
+ 1450,
+ 1450,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+ 3500,
+ 3600,
+ 3700,
+ 3800,
+ 3900,
+};
+
+static const uint16_t ldo1_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo2_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo3_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 3300,
+ 0xFFFF, /* VREFDDR */
+};
+
+static const uint16_t ldo5_voltage_table[] = {
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+ 3400,
+ 3500,
+ 3600,
+ 3700,
+ 3800,
+ 3900,
+};
+
+static const uint16_t ldo6_voltage_table[] = {
+ 900,
+ 1000,
+ 1100,
+ 1200,
+ 1300,
+ 1400,
+ 1500,
+ 1600,
+ 1700,
+ 1800,
+ 1900,
+ 2000,
+ 2100,
+ 2200,
+ 2300,
+ 2400,
+ 2500,
+ 2600,
+ 2700,
+ 2800,
+ 2900,
+ 3000,
+ 3100,
+ 3200,
+ 3300,
+};
+
+static const uint16_t ldo4_voltage_table[] = {
+ 3300,
+};
+
+static const uint16_t vref_ddr_voltage_table[] = {
+ 3300,
+};
+
+/* Table of Regulators in PMIC SoC */
+static const struct regul_struct regulators_table[] = {
+ {
+ .dt_node_name = "buck1",
+ .voltage_table = buck1_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck1_voltage_table),
+ .control_reg = BUCK1_CONTROL_REG,
+ .low_power_reg = BUCK1_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "buck2",
+ .voltage_table = buck2_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck2_voltage_table),
+ .control_reg = BUCK2_CONTROL_REG,
+ .low_power_reg = BUCK2_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "buck3",
+ .voltage_table = buck3_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck3_voltage_table),
+ .control_reg = BUCK3_CONTROL_REG,
+ .low_power_reg = BUCK3_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "buck4",
+ .voltage_table = buck4_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(buck4_voltage_table),
+ .control_reg = BUCK4_CONTROL_REG,
+ .low_power_reg = BUCK4_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo1",
+ .voltage_table = ldo1_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo1_voltage_table),
+ .control_reg = LDO1_CONTROL_REG,
+ .low_power_reg = LDO1_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo2",
+ .voltage_table = ldo2_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo2_voltage_table),
+ .control_reg = LDO2_CONTROL_REG,
+ .low_power_reg = LDO2_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo3",
+ .voltage_table = ldo3_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo3_voltage_table),
+ .control_reg = LDO3_CONTROL_REG,
+ .low_power_reg = LDO3_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo4",
+ .voltage_table = ldo4_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo4_voltage_table),
+ .control_reg = LDO4_CONTROL_REG,
+ .low_power_reg = LDO4_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo5",
+ .voltage_table = ldo5_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo5_voltage_table),
+ .control_reg = LDO5_CONTROL_REG,
+ .low_power_reg = LDO5_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "ldo6",
+ .voltage_table = ldo6_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(ldo6_voltage_table),
+ .control_reg = LDO6_CONTROL_REG,
+ .low_power_reg = LDO6_PWRCTRL_REG,
+ },
+ {
+ .dt_node_name = "vref_ddr",
+ .voltage_table = vref_ddr_voltage_table,
+ .voltage_table_size = ARRAY_SIZE(vref_ddr_voltage_table),
+ .control_reg = VREF_DDR_CONTROL_REG,
+ .low_power_reg = VREF_DDR_PWRCTRL_REG,
+ },
+};
+
+#define MAX_REGUL ARRAY_SIZE(regulators_table)
+
+static const struct regul_struct *stpmu1_get_regulator_data(const char *name)
+{
+ uint8_t i;
+
+ for (i = 0 ; i < MAX_REGUL ; i++) {
+ if (strncmp(name, regulators_table[i].dt_node_name,
+ strlen(regulators_table[i].dt_node_name)) == 0) {
+ return &regulators_table[i];
+ }
+ }
+
+ /* Regulator not found */
+ panic();
+ return NULL;
+}
+
+static uint8_t stpmu1_voltage_find_index(const char *name,
+ uint16_t millivolts)
+{
+ const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+ uint8_t i;
+
+ for (i = 0 ; i < regul->voltage_table_size ; i++) {
+ if (regul->voltage_table[i] == millivolts) {
+ return i;
+ }
+ }
+
+ /* Voltage not found */
+ panic();
+
+ return 0;
+}
+
+int stpmu1_switch_off(void)
+{
+ return stpmu1_register_update(MAIN_CONTROL_REG, 1,
+ SOFTWARE_SWITCH_OFF_ENABLED);
+}
+
+int stpmu1_regulator_enable(const char *name)
+{
+ const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+ return stpmu1_register_update(regul->control_reg, BIT(0), BIT(0));
+}
+
+int stpmu1_regulator_disable(const char *name)
+{
+ const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+ return stpmu1_register_update(regul->control_reg, 0, BIT(0));
+}
+
+uint8_t stpmu1_is_regulator_enabled(const char *name)
+{
+ uint8_t val;
+ const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+ if (stpmu1_register_read(regul->control_reg, &val) != 0) {
+ panic();
+ }
+
+ return (val & 0x1U);
+}
+
+int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts)
+{
+ uint8_t voltage_index = stpmu1_voltage_find_index(name, millivolts);
+ const struct regul_struct *regul = stpmu1_get_regulator_data(name);
+
+ return stpmu1_register_update(regul->control_reg, voltage_index << 2,
+ 0xFC);
+}
+
+int stpmu1_register_read(uint8_t register_id, uint8_t *value)
+{
+ return stm32_i2c_mem_read(stpmu_i2c_handle, stpmu_i2c_addr,
+ (uint16_t)register_id, I2C_MEMADD_SIZE_8BIT,
+ value, 1, 100000);
+}
+
+int stpmu1_register_write(uint8_t register_id, uint8_t value)
+{
+ int status;
+
+ status = stm32_i2c_mem_write(stpmu_i2c_handle, stpmu_i2c_addr,
+ (uint16_t)register_id,
+ I2C_MEMADD_SIZE_8BIT, &value, 1, 100000);
+
+ if (status != 0) {
+ return status;
+ }
+
+ if ((register_id != WATCHDOG_CONTROL_REG) && (register_id <= 0x40U)) {
+ uint8_t readval;
+
+ status = stpmu1_register_read(register_id, &readval);
+ if (status != 0) {
+ return status;
+ }
+
+ if (readval != value) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask)
+{
+ int status;
+ uint8_t val;
+
+ status = stpmu1_register_read(register_id, &val);
+ if (status != 0) {
+ return status;
+ }
+
+ /* Clear bits to update */
+ val &= ~mask;
+
+ /* Update appropriate bits*/
+ val |= (value & mask);
+
+ /* Send new value on I2C Bus */
+ return stpmu1_register_write(register_id, val);
+}
+
+void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr)
+{
+ stpmu_i2c_handle = i2c_handle;
+ stpmu_i2c_addr = i2c_addr;
+}
diff --git a/drivers/st/reset/stm32mp1_reset.c b/drivers/st/reset/stm32mp1_reset.c
new file mode 100644
index 000000000..106bbfe62
--- /dev/null
+++ b/drivers/st/reset/stm32mp1_reset.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <limits.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_rcc.h>
+#include <stm32mp1_reset.h>
+#include <utils_def.h>
+
+#define RST_CLR_OFFSET 4U
+
+void stm32mp1_reset_assert(uint32_t id)
+{
+ uint32_t offset = (id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t);
+ uint32_t bit = id % (uint32_t)__LONG_BIT;
+
+ mmio_write_32(RCC_BASE + offset, BIT(bit));
+ while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) == 0U) {
+ ;
+ }
+}
+
+void stm32mp1_reset_deassert(uint32_t id)
+{
+ uint32_t offset = ((id / (uint32_t)__LONG_BIT) * sizeof(uintptr_t)) +
+ RST_CLR_OFFSET;
+ uint32_t bit = id % (uint32_t)__LONG_BIT;
+
+ mmio_write_32(RCC_BASE + offset, BIT(bit));
+ while ((mmio_read_32(RCC_BASE + offset) & BIT(bit)) != 0U) {
+ ;
+ }
+}
diff --git a/drivers/st/uart/aarch32/stm32_console.S b/drivers/st/uart/aarch32/stm32_console.S
new file mode 100644
index 000000000..792703a93
--- /dev/null
+++ b/drivers/st/uart/aarch32/stm32_console.S
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+#define USART_TIMEOUT 0x1000
+
+#define USART_CR1 0x00
+#define USART_CR1_UE 0x00000001
+#define USART_CR1_TE 0x00000008
+#define USART_CR1_FIFOEN 0x20000000
+
+#define USART_CR2 0x04
+#define USART_CR2_STOP 0x00003000
+
+#define USART_BRR 0x0C
+
+#define USART_ISR 0x1C
+#define USART_ISR_TC 0x00000040
+#define USART_ISR_TXE 0x00000080
+#define USART_ISR_TEACK 0x00200000
+
+#define USART_TDR 0x28
+
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+
+ /* -----------------------------------------------------------------
+ * int console_core_init(uintptr_t base_addr,
+ * unsigned int uart_clk,
+ * unsigned int baud_rate)
+ *
+ * Function to initialize the console without a C Runtime to print
+ * debug information. This function will be accessed by console_init
+ * and crash reporting.
+ *
+ * In: r0 - console base address
+ * r1 - Uart clock in Hz
+ * r2 - Baud rate
+ * Out: return 1 on success else 0 on error
+ * Clobber list : r1, r2, r3
+ * -----------------------------------------------------------------
+ */
+func console_core_init
+ /* Check the input base address */
+ cmp r0, #0
+ beq core_init_fail
+#if defined(IMAGE_BL2)
+ /* Check baud rate and uart clock for sanity */
+ cmp r1, #0
+ beq core_init_fail
+ cmp r2, #0
+ beq core_init_fail
+ /* Disable UART */
+ ldr r3, [r0, #USART_CR1]
+ bic r3, r3, #USART_CR1_UE
+ str r3, [r0, #USART_CR1]
+ /* Configure UART */
+ orr r3, r3, #(USART_CR1_TE | USART_CR1_FIFOEN)
+ str r3, [r0, #USART_CR1]
+ ldr r3, [r0, #USART_CR2]
+ bic r3, r3, #USART_CR2_STOP
+ str r3, [r0, #USART_CR2]
+ /* Divisor = (Uart clock + (baudrate / 2)) / baudrate */
+ lsl r3, r2, #1
+ add r3, r1, r3
+ udiv r3, r3, r2
+ str r3, [r0, #USART_BRR]
+ /* Enable UART */
+ ldr r3, [r0, #USART_CR1]
+ orr r3, r3, #USART_CR1_UE
+ str r3, [r0, #USART_CR1]
+ /* Check TEACK bit */
+ mov r2, #USART_TIMEOUT
+teack_loop:
+ subs r2, r2, #1
+ beq core_init_fail
+ ldr r3, [r0, #USART_ISR]
+ tst r3, #USART_ISR_TEACK
+ beq teack_loop
+#endif /* IMAGE_BL2 */
+ mov r0, #1
+ bx lr
+core_init_fail:
+ mov r0, #0
+ bx lr
+endfunc console_core_init
+
+ /* ---------------------------------------------------------------
+ * int console_core_putc(int c, uintptr_t base_addr)
+ *
+ * Function to output a character over the console. It returns the
+ * character printed on success or -1 on error.
+ *
+ * In : r0 - character to be printed
+ * r1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : r2
+ * ---------------------------------------------------------------
+ */
+func console_core_putc
+ /* Check the input parameter */
+ cmp r1, #0
+ beq putc_error
+ /* Prepend '\r' to '\n' */
+ cmp r0, #0xA
+ bne 2f
+1:
+ /* Check Transmit Data Register Empty */
+txe_loop_1:
+ ldr r2, [r1, #USART_ISR]
+ tst r2, #USART_ISR_TXE
+ beq txe_loop_1
+ mov r2, #0xD
+ str r2, [r1, #USART_TDR]
+ /* Check transmit complete flag */
+tc_loop_1:
+ ldr r2, [r1, #USART_ISR]
+ tst r2, #USART_ISR_TC
+ beq tc_loop_1
+2:
+ /* Check Transmit Data Register Empty */
+txe_loop_2:
+ ldr r2, [r1, #USART_ISR]
+ tst r2, #USART_ISR_TXE
+ beq txe_loop_2
+ str r0, [r1, #USART_TDR]
+ /* Check transmit complete flag */
+tc_loop_2:
+ ldr r2, [r1, #USART_ISR]
+ tst r2, #USART_ISR_TC
+ beq tc_loop_2
+ bx lr
+putc_error:
+ mov r0, #-1
+ bx lr
+endfunc console_core_putc
+
+ /* -----------------------------------------------------------
+ * int console_core_getc(uintptr_t base_addr)
+ *
+ * Function to get a character from the console.
+ * It returns the character grabbed on success or -1 on error.
+ *
+ * In : r0 - console base address
+ * Out : return -1.
+ * Clobber list : r0, r1
+ * -----------------------------------------------------------
+ */
+func console_core_getc
+ /* Not supported */
+ mov r0, #-1
+ bx lr
+endfunc console_core_getc
+
+ /* ---------------------------------------------------------------
+ * int console_core_flush(uintptr_t base_addr)
+ *
+ * Function to force a write of all buffered data that hasn't been
+ * output.
+ *
+ * In : r0 - console base address
+ * Out : return -1 on error else return 0.
+ * Clobber list : r0, r1
+ * ---------------------------------------------------------------
+ */
+func console_core_flush
+ cmp r0, #0
+ beq flush_error
+ /* Check Transmit Data Register Empty */
+txe_loop_3:
+ ldr r1, [r0, #USART_ISR]
+ tst r1, #USART_ISR_TXE
+ beq txe_loop_3
+ mov r0, #0
+ bx lr
+flush_error:
+ mov r0, #-1
+ bx lr
+endfunc console_core_flush
diff --git a/drivers/synopsys/emmc/dw_mmc.c b/drivers/synopsys/emmc/dw_mmc.c
index 156c2b4eb..b0b0a3fd4 100644
--- a/drivers/synopsys/emmc/dw_mmc.c
+++ b/drivers/synopsys/emmc/dw_mmc.c
@@ -10,8 +10,8 @@
#include <debug.h>
#include <delay_timer.h>
#include <dw_mmc.h>
-#include <emmc.h>
#include <errno.h>
+#include <mmc.h>
#include <mmio.h>
#include <string.h>
@@ -107,6 +107,8 @@
#define DWMMC_8BIT_MODE (1 << 6)
+#define DWMMC_ADDRESS_MASK U(0x0f)
+
#define TIMEOUT 100000
struct dw_idmac_desc {
@@ -117,13 +119,13 @@ struct dw_idmac_desc {
};
static void dw_init(void);
-static int dw_send_cmd(emmc_cmd_t *cmd);
-static int dw_set_ios(int clk, int width);
+static int dw_send_cmd(struct mmc_cmd *cmd);
+static int dw_set_ios(unsigned int clk, unsigned int width);
static int dw_prepare(int lba, uintptr_t buf, size_t size);
static int dw_read(int lba, uintptr_t buf, size_t size);
static int dw_write(int lba, uintptr_t buf, size_t size);
-static const emmc_ops_t dw_mmc_ops = {
+static const struct mmc_ops dw_mmc_ops = {
.init = dw_init,
.send_cmd = dw_send_cmd,
.set_ios = dw_set_ios,
@@ -187,7 +189,7 @@ static void dw_init(void)
unsigned int data;
uintptr_t base;
- assert((dw_params.reg_base & EMMC_BLOCK_MASK) == 0);
+ assert((dw_params.reg_base & MMC_BLOCK_MASK) == 0);
base = dw_params.reg_base;
mmio_write_32(base + DWMMC_PWREN, 1);
@@ -203,7 +205,7 @@ static void dw_init(void)
mmio_write_32(base + DWMMC_INTMASK, 0);
mmio_write_32(base + DWMMC_TMOUT, ~0);
mmio_write_32(base + DWMMC_IDINTEN, ~0);
- mmio_write_32(base + DWMMC_BLKSIZ, EMMC_BLOCK_SIZE);
+ mmio_write_32(base + DWMMC_BLKSIZ, MMC_BLOCK_SIZE);
mmio_write_32(base + DWMMC_BYTCNT, 256 * 1024);
mmio_write_32(base + DWMMC_DEBNCE, 0x00ffffff);
mmio_write_32(base + DWMMC_BMOD, BMOD_SWRESET);
@@ -215,11 +217,11 @@ static void dw_init(void)
mmio_write_32(base + DWMMC_BMOD, data);
udelay(100);
- dw_set_clk(EMMC_BOOT_CLK_RATE);
+ dw_set_clk(MMC_BOOT_CLK_RATE);
udelay(100);
}
-static int dw_send_cmd(emmc_cmd_t *cmd)
+static int dw_send_cmd(struct mmc_cmd *cmd)
{
unsigned int op, data, err_mask;
uintptr_t base;
@@ -230,22 +232,22 @@ static int dw_send_cmd(emmc_cmd_t *cmd)
base = dw_params.reg_base;
switch (cmd->cmd_idx) {
- case EMMC_CMD0:
+ case 0:
op = CMD_SEND_INIT;
break;
- case EMMC_CMD12:
+ case 12:
op = CMD_STOP_ABORT_CMD;
break;
- case EMMC_CMD13:
+ case 13:
op = CMD_WAIT_PRVDATA_COMPLETE;
break;
- case EMMC_CMD8:
- case EMMC_CMD17:
- case EMMC_CMD18:
+ case 8:
+ case 17:
+ case 18:
op = CMD_DATA_TRANS_EXPECT | CMD_WAIT_PRVDATA_COMPLETE;
break;
- case EMMC_CMD24:
- case EMMC_CMD25:
+ case 24:
+ case 25:
op = CMD_WRITE | CMD_DATA_TRANS_EXPECT |
CMD_WAIT_PRVDATA_COMPLETE;
break;
@@ -257,11 +259,11 @@ static int dw_send_cmd(emmc_cmd_t *cmd)
switch (cmd->resp_type) {
case 0:
break;
- case EMMC_RESPONSE_R2:
+ case MMC_RESPONSE_R(2):
op |= CMD_RESP_EXPECT | CMD_CHECK_RESP_CRC |
CMD_RESP_LEN;
break;
- case EMMC_RESPONSE_R3:
+ case MMC_RESPONSE_R(3):
op |= CMD_RESP_EXPECT;
break;
default:
@@ -307,16 +309,16 @@ static int dw_send_cmd(emmc_cmd_t *cmd)
return 0;
}
-static int dw_set_ios(int clk, int width)
+static int dw_set_ios(unsigned int clk, unsigned int width)
{
switch (width) {
- case EMMC_BUS_WIDTH_1:
+ case MMC_BUS_WIDTH_1:
mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_1BIT);
break;
- case EMMC_BUS_WIDTH_4:
+ case MMC_BUS_WIDTH_4:
mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_4BIT);
break;
- case EMMC_BUS_WIDTH_8:
+ case MMC_BUS_WIDTH_8:
mmio_write_32(dw_params.reg_base + DWMMC_CTYPE, CTYPE_8BIT);
break;
default:
@@ -333,12 +335,14 @@ static int dw_prepare(int lba, uintptr_t buf, size_t size)
int desc_cnt, i, last;
uintptr_t base;
- assert(((buf & EMMC_BLOCK_MASK) == 0) &&
- ((size % EMMC_BLOCK_SIZE) == 0) &&
+ assert(((buf & DWMMC_ADDRESS_MASK) == 0) &&
+ ((size % MMC_BLOCK_SIZE) == 0) &&
(dw_params.desc_size > 0) &&
- ((dw_params.reg_base & EMMC_BLOCK_MASK) == 0) &&
- ((dw_params.desc_base & EMMC_BLOCK_MASK) == 0) &&
- ((dw_params.desc_size & EMMC_BLOCK_MASK) == 0));
+ ((dw_params.reg_base & MMC_BLOCK_MASK) == 0) &&
+ ((dw_params.desc_base & MMC_BLOCK_MASK) == 0) &&
+ ((dw_params.desc_size & MMC_BLOCK_MASK) == 0));
+
+ flush_dcache_range(buf, size);
desc_cnt = (size + DWMMC_DMA_MAX_BUFFER_SIZE - 1) /
DWMMC_DMA_MAX_BUFFER_SIZE;
@@ -367,7 +371,7 @@ static int dw_prepare(int lba, uintptr_t buf, size_t size)
(desc + last)->des3 = 0;
mmio_write_32(base + DWMMC_DBADDR, dw_params.desc_base);
- clean_dcache_range(dw_params.desc_base,
+ flush_dcache_range(dw_params.desc_base,
desc_cnt * DWMMC_DMA_MAX_BUFFER_SIZE);
return 0;
@@ -383,19 +387,19 @@ static int dw_write(int lba, uintptr_t buf, size_t size)
return 0;
}
-void dw_mmc_init(dw_mmc_params_t *params)
+void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info)
{
assert((params != 0) &&
- ((params->reg_base & EMMC_BLOCK_MASK) == 0) &&
- ((params->desc_base & EMMC_BLOCK_MASK) == 0) &&
- ((params->desc_size & EMMC_BLOCK_MASK) == 0) &&
+ ((params->reg_base & MMC_BLOCK_MASK) == 0) &&
+ ((params->desc_base & MMC_BLOCK_MASK) == 0) &&
+ ((params->desc_size & MMC_BLOCK_MASK) == 0) &&
(params->desc_size > 0) &&
(params->clk_rate > 0) &&
- ((params->bus_width == EMMC_BUS_WIDTH_1) ||
- (params->bus_width == EMMC_BUS_WIDTH_4) ||
- (params->bus_width == EMMC_BUS_WIDTH_8)));
+ ((params->bus_width == MMC_BUS_WIDTH_1) ||
+ (params->bus_width == MMC_BUS_WIDTH_4) ||
+ (params->bus_width == MMC_BUS_WIDTH_8)));
memcpy(&dw_params, params, sizeof(dw_mmc_params_t));
- emmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width,
- params->flags);
+ mmc_init(&dw_mmc_ops, params->clk_rate, params->bus_width,
+ params->flags, info);
}
diff --git a/fdts/stm32mp15-ddr.dtsi b/fdts/stm32mp15-ddr.dtsi
new file mode 100644
index 000000000..be4e2c372
--- /dev/null
+++ b/fdts/stm32mp15-ddr.dtsi
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+/ {
+ soc {
+ ddr: ddr@0x5A003000{
+
+ compatible = "st,stm32mp1-ddr";
+
+ reg = <0x5A003000 0x550
+ 0x5A004000 0x234>;
+
+ clocks = <&rcc AXIDCG>,
+ <&rcc DDRC1>,
+ <&rcc DDRC2>,
+ <&rcc DDRPHYC>,
+ <&rcc DDRCAPB>,
+ <&rcc DDRPHYCAPB>;
+
+ clock-names = "axidcg",
+ "ddrc1",
+ "ddrc2",
+ "ddrphyc",
+ "ddrcapb",
+ "ddrphycapb";
+
+ st,mem-name = DDR_MEM_NAME;
+ st,mem-speed = <DDR_MEM_SPEED>;
+ st,mem-size = <DDR_MEM_SIZE>;
+
+ st,ctl-reg = <
+ DDR_MSTR
+ DDR_MRCTRL0
+ DDR_MRCTRL1
+ DDR_DERATEEN
+ DDR_DERATEINT
+ DDR_PWRCTL
+ DDR_PWRTMG
+ DDR_HWLPCTL
+ DDR_RFSHCTL0
+ DDR_RFSHCTL3
+ DDR_CRCPARCTL0
+ DDR_ZQCTL0
+ DDR_DFITMG0
+ DDR_DFITMG1
+ DDR_DFILPCFG0
+ DDR_DFIUPD0
+ DDR_DFIUPD1
+ DDR_DFIUPD2
+ DDR_DFIPHYMSTR
+ DDR_ODTMAP
+ DDR_DBG0
+ DDR_DBG1
+ DDR_DBGCMD
+ DDR_POISONCFG
+ DDR_PCCFG
+ >;
+
+ st,ctl-timing = <
+ DDR_RFSHTMG
+ DDR_DRAMTMG0
+ DDR_DRAMTMG1
+ DDR_DRAMTMG2
+ DDR_DRAMTMG3
+ DDR_DRAMTMG4
+ DDR_DRAMTMG5
+ DDR_DRAMTMG6
+ DDR_DRAMTMG7
+ DDR_DRAMTMG8
+ DDR_DRAMTMG14
+ DDR_ODTCFG
+ >;
+
+ st,ctl-map = <
+ DDR_ADDRMAP1
+ DDR_ADDRMAP2
+ DDR_ADDRMAP3
+ DDR_ADDRMAP4
+ DDR_ADDRMAP5
+ DDR_ADDRMAP6
+ DDR_ADDRMAP9
+ DDR_ADDRMAP10
+ DDR_ADDRMAP11
+ >;
+
+ st,ctl-perf = <
+ DDR_SCHED
+ DDR_SCHED1
+ DDR_PERFHPR1
+ DDR_PERFLPR1
+ DDR_PERFWR1
+ DDR_PCFGR_0
+ DDR_PCFGW_0
+ DDR_PCFGQOS0_0
+ DDR_PCFGQOS1_0
+ DDR_PCFGWQOS0_0
+ DDR_PCFGWQOS1_0
+ DDR_PCFGR_1
+ DDR_PCFGW_1
+ DDR_PCFGQOS0_1
+ DDR_PCFGQOS1_1
+ DDR_PCFGWQOS0_1
+ DDR_PCFGWQOS1_1
+ >;
+
+ st,phy-reg = <
+ DDR_PGCR
+ DDR_ACIOCR
+ DDR_DXCCR
+ DDR_DSGCR
+ DDR_DCR
+ DDR_ODTCR
+ DDR_ZQ0CR1
+ DDR_DX0GCR
+ DDR_DX1GCR
+ DDR_DX2GCR
+ DDR_DX3GCR
+ >;
+
+ st,phy-timing = <
+ DDR_PTR0
+ DDR_PTR1
+ DDR_PTR2
+ DDR_DTPR0
+ DDR_DTPR1
+ DDR_DTPR2
+ DDR_MR0
+ DDR_MR1
+ DDR_MR2
+ DDR_MR3
+ >;
+
+ st,phy-cal = <
+ DDR_DX0DLLCR
+ DDR_DX0DQTR
+ DDR_DX0DQSTR
+ DDR_DX1DLLCR
+ DDR_DX1DQTR
+ DDR_DX1DQSTR
+ DDR_DX2DLLCR
+ DDR_DX2DQTR
+ DDR_DX2DQSTR
+ DDR_DX3DLLCR
+ DDR_DX3DQTR
+ DDR_DX3DQSTR
+ >;
+
+ status = "okay";
+ };
+ };
+};
diff --git a/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
new file mode 100644
index 000000000..58a4cdc8c
--- /dev/null
+++ b/fdts/stm32mp15-ddr3-2x4Gb-1066-binG.dtsi
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+/* STM32MP157C ED1 and ED2 BOARD configuration
+ * 2x DDR3L 4Gb each, 16-bit, 533MHz, Single Die Package in flyby topology.
+ * Reference used NT5CC256M16DP-DI from NANYA
+ *
+ * DDR type / Platform DDR3/3L
+ * freq 533MHz
+ * width 32
+ * datasheet 0 = MT41J256M16-187 / DDR3-1066 bin G
+ * DDR density 8
+ * timing mode optimized
+ * Scheduling/QoS options : type = 2
+ * address mapping : RBC
+ */
+
+#define DDR_MEM_NAME "DDR3-1066 bin G 2x4Gb 533MHz v1.39"
+#define DDR_MEM_SPEED 533
+#define DDR_MEM_SIZE 0x40000000
+
+#define DDR_MSTR 0x00040401
+#define DDR_MRCTRL0 0x00000010
+#define DDR_MRCTRL1 0x00000000
+#define DDR_DERATEEN 0x00000000
+#define DDR_DERATEINT 0x00800000
+#define DDR_PWRCTL 0x00000000
+#define DDR_PWRTMG 0x00400010
+#define DDR_HWLPCTL 0x00000000
+#define DDR_RFSHCTL0 0x00210000
+#define DDR_RFSHCTL3 0x00000000
+#define DDR_RFSHTMG 0x0081008B
+#define DDR_CRCPARCTL0 0x00000000
+#define DDR_DRAMTMG0 0x121B2414
+#define DDR_DRAMTMG1 0x000A041C
+#define DDR_DRAMTMG2 0x0608090F
+#define DDR_DRAMTMG3 0x0050400C
+#define DDR_DRAMTMG4 0x08040608
+#define DDR_DRAMTMG5 0x06060403
+#define DDR_DRAMTMG6 0x02020002
+#define DDR_DRAMTMG7 0x00000202
+#define DDR_DRAMTMG8 0x00001005
+#define DDR_DRAMTMG14 0x000000A0
+#define DDR_ZQCTL0 0xC2000040
+#define DDR_DFITMG0 0x02060105
+#define DDR_DFITMG1 0x00000202
+#define DDR_DFILPCFG0 0x07000000
+#define DDR_DFIUPD0 0xC0400003
+#define DDR_DFIUPD1 0x00000000
+#define DDR_DFIUPD2 0x00000000
+#define DDR_DFIPHYMSTR 0x00000000
+#define DDR_ADDRMAP1 0x00080808
+#define DDR_ADDRMAP2 0x00000000
+#define DDR_ADDRMAP3 0x00000000
+#define DDR_ADDRMAP4 0x00001F1F
+#define DDR_ADDRMAP5 0x07070707
+#define DDR_ADDRMAP6 0x0F070707
+#define DDR_ADDRMAP9 0x00000000
+#define DDR_ADDRMAP10 0x00000000
+#define DDR_ADDRMAP11 0x00000000
+#define DDR_ODTCFG 0x06000600
+#define DDR_ODTMAP 0x00000001
+#define DDR_SCHED 0x00001201
+#define DDR_SCHED1 0x00000000
+#define DDR_PERFHPR1 0x01000001
+#define DDR_PERFLPR1 0x08000200
+#define DDR_PERFWR1 0x08000400
+#define DDR_DBG0 0x00000000
+#define DDR_DBG1 0x00000000
+#define DDR_DBGCMD 0x00000000
+#define DDR_POISONCFG 0x00000000
+#define DDR_PCCFG 0x00000010
+#define DDR_PCFGR_0 0x00010000
+#define DDR_PCFGW_0 0x00000000
+#define DDR_PCFGQOS0_0 0x02100B03
+#define DDR_PCFGQOS1_0 0x00800100
+#define DDR_PCFGWQOS0_0 0x01100B03
+#define DDR_PCFGWQOS1_0 0x01000200
+#define DDR_PCFGR_1 0x00010000
+#define DDR_PCFGW_1 0x00000000
+#define DDR_PCFGQOS0_1 0x02100B03
+#define DDR_PCFGQOS1_1 0x00800000
+#define DDR_PCFGWQOS0_1 0x01100B03
+#define DDR_PCFGWQOS1_1 0x01000200
+#define DDR_PGCR 0x01442E02
+#define DDR_PTR0 0x0022AA5B
+#define DDR_PTR1 0x04841104
+#define DDR_PTR2 0x042DA068
+#define DDR_ACIOCR 0x10400812
+#define DDR_DXCCR 0x00000C40
+#define DDR_DSGCR 0xF200001F
+#define DDR_DCR 0x0000000B
+#define DDR_DTPR0 0x38D488D0
+#define DDR_DTPR1 0x098B00D8
+#define DDR_DTPR2 0x10023600
+#define DDR_MR0 0x00000840
+#define DDR_MR1 0x00000000
+#define DDR_MR2 0x00000208
+#define DDR_MR3 0x00000000
+#define DDR_ODTCR 0x00010000
+#define DDR_ZQ0CR1 0x00000038
+#define DDR_DX0GCR 0x0000CE81
+#define DDR_DX0DLLCR 0x40000000
+#define DDR_DX0DQTR 0xFFFFFFFF
+#define DDR_DX0DQSTR 0x3DB02000
+#define DDR_DX1GCR 0x0000CE81
+#define DDR_DX1DLLCR 0x40000000
+#define DDR_DX1DQTR 0xFFFFFFFF
+#define DDR_DX1DQSTR 0x3DB02000
+#define DDR_DX2GCR 0x0000CE81
+#define DDR_DX2DLLCR 0x40000000
+#define DDR_DX2DQTR 0xFFFFFFFF
+#define DDR_DX2DQSTR 0x3DB02000
+#define DDR_DX3GCR 0x0000CE81
+#define DDR_DX3DLLCR 0x40000000
+#define DDR_DX3DQTR 0xFFFFFFFF
+#define DDR_DX3DQSTR 0x3DB02000
+
+#include "stm32mp15-ddr.dtsi"
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
new file mode 100644
index 000000000..21bd34e0b
--- /dev/null
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+/ {
+ soc {
+ pinctrl: pin-controller {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x50002000 0xa400>;
+ pins-are-numbered;
+
+ gpioa: gpio@50002000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x0 0x400>;
+ clocks = <&rcc GPIOA>;
+ st,bank-name = "GPIOA";
+ status = "disabled";
+ };
+
+ gpiob: gpio@50003000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x1000 0x400>;
+ clocks = <&rcc GPIOB>;
+ st,bank-name = "GPIOB";
+ status = "disabled";
+ };
+
+ gpioc: gpio@50004000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x2000 0x400>;
+ clocks = <&rcc GPIOC>;
+ st,bank-name = "GPIOC";
+ status = "disabled";
+ };
+
+ gpiod: gpio@50005000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x3000 0x400>;
+ clocks = <&rcc GPIOD>;
+ st,bank-name = "GPIOD";
+ status = "disabled";
+ };
+
+ gpioe: gpio@50006000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x4000 0x400>;
+ clocks = <&rcc GPIOE>;
+ st,bank-name = "GPIOE";
+ status = "disabled";
+ };
+
+ gpiof: gpio@50007000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x5000 0x400>;
+ clocks = <&rcc GPIOF>;
+ st,bank-name = "GPIOF";
+ status = "disabled";
+ };
+
+ gpiog: gpio@50008000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x6000 0x400>;
+ clocks = <&rcc GPIOG>;
+ st,bank-name = "GPIOG";
+ status = "disabled";
+ };
+
+ gpioh: gpio@50009000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x7000 0x400>;
+ clocks = <&rcc GPIOH>;
+ st,bank-name = "GPIOH";
+ status = "disabled";
+ };
+
+ gpioi: gpio@5000a000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x8000 0x400>;
+ clocks = <&rcc GPIOI>;
+ st,bank-name = "GPIOI";
+ status = "disabled";
+ };
+
+ gpioj: gpio@5000b000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0x9000 0x400>;
+ clocks = <&rcc GPIOJ>;
+ st,bank-name = "GPIOJ";
+ status = "disabled";
+ };
+
+ gpiok: gpio@5000c000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0xa000 0x400>;
+ clocks = <&rcc GPIOK>;
+ st,bank-name = "GPIOK";
+ status = "disabled";
+ };
+
+ uart4_pins_a: uart4@0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+ bias-disable;
+ };
+ };
+
+ usart3_pins_a: usart3@0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('B', 10, AF7)>, /* USART3_TX */
+ <STM32_PINMUX('G', 8, AF8)>; /* USART3_RTS */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <0>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('B', 12, AF8)>, /* USART3_RX */
+ <STM32_PINMUX('I', 10, AF8)>; /* USART3_CTS_NSS */
+ bias-disable;
+ };
+ };
+
+ sdmmc1_b4_pins_a: sdmmc1-b4@0 {
+ pins {
+ pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+ <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+ <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+ <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+ <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
+ <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-disable;
+ };
+ };
+
+ sdmmc1_dir_pins_a: sdmmc1-dir@0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+ <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
+ <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ pins2{
+ pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_b4_pins_a: sdmmc2-b4@0 {
+ pins {
+ pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+ <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+ <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+ <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+ <STM32_PINMUX('E', 3, AF9)>, /* SDMMC2_CK */
+ <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+
+ sdmmc2_d47_pins_a: sdmmc2-d47@0 {
+ pins {
+ pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+ <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+ <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
+ <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
+ slew-rate = <3>;
+ drive-push-pull;
+ bias-pull-up;
+ };
+ };
+ };
+
+ pinctrl_z: pin-controller-z {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x54004000 0x400>;
+ pins-are-numbered;
+
+ gpioz: gpio@54004000 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ reg = <0 0x400>;
+ clocks = <&rcc GPIOZ>;
+ st,bank-name = "GPIOZ";
+ st,bank-ioport = <11>;
+ status = "disabled";
+ };
+
+ i2c4_pins_a: i2c4@0 {
+ pins {
+ pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
+ <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <0>;
+ };
+ };
+ };
+ };
+};
diff --git a/fdts/stm32mp157c-ed1.dts b/fdts/stm32mp157c-ed1.dts
new file mode 100644
index 000000000..e3dabe8b2
--- /dev/null
+++ b/fdts/stm32mp157c-ed1.dts
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include "stm32mp157caa-pinctrl.dtsi"
+
+/ {
+ model = "STMicroelectronics STM32MP157C-ED1 pmic eval daughter";
+ compatible = "st,stm32mp157c-ed1", "st,stm32mp157";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
+ stdout-path = "serial3:115200n8";
+ };
+};
+
+&i2c4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c4_pins_a>;
+ i2c-scl-rising-time-ns = <185>;
+ i2c-scl-falling-time-ns = <20>;
+ status = "okay";
+
+ pmic: stpmu1@33 {
+ compatible = "st,stpmu1";
+ reg = <0x33>;
+ status = "okay";
+
+ st,main_control_register = <0x04>;
+ st,vin_control_register = <0xc0>;
+ st,usb_control_register = <0x30>;
+
+ regulators {
+ compatible = "st,stpmu1-regulators";
+
+ v3v3: buck4 {
+ regulator-name = "v3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ regulator-over-current-protection;
+ regulator-initial-mode = <8>;
+
+ regulator-state-standby {
+ regulator-suspend-microvolt = <3300000>;
+ regulator-unchanged-in-suspend;
+ regulator-mode = <8>;
+ };
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ regulator-state-disk {
+ regulator-off-in-suspend;
+ };
+ };
+
+ vdd_sd: ldo5 {
+ regulator-name = "vdd_sd";
+ regulator-min-microvolt = <2900000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-boot-on;
+
+ regulator-state-standby {
+ regulator-suspend-microvolt = <2900000>;
+ regulator-unchanged-in-suspend;
+ };
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ regulator-state-disk {
+ regulator-off-in-suspend;
+ };
+ };
+ };
+ };
+};
+
+&iwdg2 {
+ instance = <2>;
+ timeout-sec = <32>;
+ status = "okay";
+};
+
+&rng1 {
+ status = "okay";
+};
+
+&sdmmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc1_b4_pins_a &sdmmc1_dir_pins_a>;
+ broken-cd;
+ st,dirpol;
+ st,negedge;
+ st,pin-ckin;
+ bus-width = <4>;
+ sd-uhs-sdr12;
+ sd-uhs-sdr25;
+ sd-uhs-sdr50;
+ sd-uhs-ddr50;
+ sd-uhs-sdr104;
+ status = "okay";
+};
+
+&sdmmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+ non-removable;
+ no-sd;
+ no-sdio;
+ st,dirpol;
+ st,negedge;
+ bus-width = <8>;
+ status = "okay";
+};
+
+&uart4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins_a>;
+ resets = <&rcc UART4_R>;
+ status = "okay";
+};
+
+/* ATF Specific */
+#include <dt-bindings/clock/stm32mp1-clksrc.h>
+#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi"
+
+/ {
+ aliases {
+ gpio0 = &gpioa;
+ gpio1 = &gpiob;
+ gpio2 = &gpioc;
+ gpio3 = &gpiod;
+ gpio4 = &gpioe;
+ gpio5 = &gpiof;
+ gpio6 = &gpiog;
+ gpio7 = &gpioh;
+ gpio8 = &gpioi;
+ gpio9 = &gpioj;
+ gpio10 = &gpiok;
+ gpio25 = &gpioz;
+ i2c3 = &i2c4;
+ };
+
+ soc {
+ stgen: stgen@5C008000 {
+ compatible = "st,stm32-stgen";
+ reg = <0x5C008000 0x1000>;
+ status = "okay";
+ };
+ };
+};
+
+/* CLOCK init */
+&rcc {
+ st,clksrc = <
+ CLK_MPU_PLL1P
+ CLK_AXI_PLL2P
+ CLK_PLL12_HSE
+ CLK_PLL3_HSE
+ CLK_PLL4_HSE
+ CLK_RTC_LSE
+ CLK_MCO1_DISABLED
+ CLK_MCO2_DISABLED
+ >;
+
+ st,clkdiv = <
+ 1 /*MPU*/
+ 0 /*AXI*/
+ 1 /*APB1*/
+ 1 /*APB2*/
+ 1 /*APB3*/
+ 1 /*APB4*/
+ 2 /*APB5*/
+ 23 /*RTC*/
+ 0 /*MCO1*/
+ 0 /*MCO2*/
+ >;
+
+ st,pkcs = <
+ CLK_CKPER_HSE
+ CLK_FMC_ACLK
+ CLK_QSPI_ACLK
+ CLK_ETH_DISABLED
+ CLK_SDMMC12_PLL3R
+ CLK_DSI_DSIPLL
+ CLK_STGEN_HSE
+ CLK_USBPHY_HSE
+ CLK_SPI2S1_PLL3Q
+ CLK_SPI2S23_PLL3Q
+ CLK_SPI45_HSI
+ CLK_SPI6_HSI
+ CLK_I2C46_HSI
+ CLK_SDMMC3_PLL3R
+ CLK_USBO_USBPHY
+ CLK_ADC_CKPER
+ CLK_CEC_LSE
+ CLK_I2C12_HSI
+ CLK_I2C35_HSI
+ CLK_UART1_HSI
+ CLK_UART24_HSI
+ CLK_UART35_HSI
+ CLK_UART6_HSI
+ CLK_UART78_HSI
+ CLK_SPDIF_PLL3Q
+ CLK_FDCAN_PLL4Q
+ CLK_SAI1_PLL3Q
+ CLK_SAI2_PLL3Q
+ CLK_SAI3_PLL3Q
+ CLK_SAI4_PLL3Q
+ CLK_RNG1_CSI
+ CLK_RNG2_CSI
+ CLK_LPTIM1_PCLK1
+ CLK_LPTIM23_PCLK3
+ CLK_LPTIM45_PCLK3
+ >;
+
+ /* VCO = 1300.0 MHz => P = 650 (CPU) */
+ pll1: st,pll@0 {
+ cfg = < 2 80 0 0 0 PQR(1,0,0) >;
+ frac = < 0x800 >;
+ };
+
+ /* VCO = 1066.0 MHz => P = 266 (AXI), Q = 533 (GPU), R = 533 (DDR) */
+ pll2: st,pll@1 {
+ cfg = < 2 65 1 0 0 PQR(1,1,1) >;
+ frac = < 0x1400 >;
+ };
+
+ /* VCO = 786.4 MHz => P = 197, Q = 49, R = 98 */
+ pll3: st,pll@2 {
+ cfg = < 2 97 3 15 7 PQR(1,1,1) >;
+ frac = < 0x9ba >;
+ };
+
+ /* VCO = 508.0 MHz => P = 56, Q = 56, R = 56 */
+ pll4: st,pll@3 {
+ cfg = < 5 126 8 8 8 PQR(1,1,1) >;
+ };
+};
+
+/delete-node/ &clk_csi;
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
new file mode 100644
index 000000000..98a9d3500
--- /dev/null
+++ b/fdts/stm32mp157c-ev1.dts
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+/dts-v1/;
+#include "stm32mp157c-ed1.dts"
+
+/ {
+ model = "STMicroelectronics STM32MP157C-EV1 pmic eval daughter on eval mother";
+ compatible = "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", "st,stm32mp157";
+
+ chosen {
+ bootargs = "earlyprintk console=ttyS3,115200 root=/dev/ram";
+ stdout-path = "serial3:115200n8";
+ };
+};
+
+&usart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&usart3_pins_a>;
+ resets = <&rcc USART3_R>;
+ status = "disabled";
+};
diff --git a/fdts/stm32mp157c.dtsi b/fdts/stm32mp157c.dtsi
new file mode 100644
index 000000000..8b13c0e38
--- /dev/null
+++ b/fdts/stm32mp157c.dtsi
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <dt-bindings/reset/stm32mp1-resets.h>
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ aliases {
+ serial0 = &usart1;
+ serial1 = &usart2;
+ serial2 = &usart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ serial5 = &usart6;
+ serial6 = &uart7;
+ serial7 = &uart8;
+ };
+
+ clocks {
+ clk_hse: clk-hse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+
+ clk_hsi: clk-hsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <64000000>;
+ };
+
+ clk_lse: clk-lse {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ clk_lsi: clk-lsi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32000>;
+ };
+
+ clk_csi: clk-csi {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <4000000>;
+ };
+
+ clk_i2s_ckin: i2s_ckin {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <64000000>;
+ };
+
+ clk_dsi_phy: ck_dsi_phy {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ clk_usbo_48m: ck_usbo_48m {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <48000000>;
+ };
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ usart2: serial@4000e000 {
+ compatible = "st,stm32h7-usart";
+ reg = <0x4000e000 0x400>;
+ clocks = <&rcc USART2_K>;
+ status = "disabled";
+ };
+
+ usart3: serial@4000f000 {
+ compatible = "st,stm32h7-usart";
+ reg = <0x4000f000 0x400>;
+ clocks = <&rcc USART3_K>;
+ status = "disabled";
+ };
+
+ uart4: serial@40010000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40010000 0x400>;
+ clocks = <&rcc UART4_K>;
+ status = "disabled";
+ };
+
+ uart5: serial@40011000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40011000 0x400>;
+ clocks = <&rcc UART5_K>;
+ status = "disabled";
+ };
+
+
+ uart7: serial@40018000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40018000 0x400>;
+ clocks = <&rcc UART7_K>;
+ status = "disabled";
+ };
+
+ uart8: serial@40019000 {
+ compatible = "st,stm32h7-uart";
+ reg = <0x40019000 0x400>;
+ clocks = <&rcc UART8_K>;
+ status = "disabled";
+ };
+
+ usart6: serial@44003000 {
+ compatible = "st,stm32h7-usart";
+ reg = <0x44003000 0x400>;
+ clocks = <&rcc USART6_K>;
+ status = "disabled";
+ };
+
+ sdmmc3: sdmmc@48004000 {
+ compatible = "st,stm32-sdmmc2";
+ reg = <0x48004000 0x400>, <0x48005000 0x400>;
+ reg-names = "sdmmc", "delay";
+ clocks = <&rcc SDMMC3_K>;
+ resets = <&rcc SDMMC3_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <120000000>;
+ status = "disabled";
+ };
+
+ rcc: rcc@50000000 {
+ compatible = "syscon", "st,stm32mp1-rcc";
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ reg = <0x50000000 0x1000>;
+ };
+
+ rcc_reboot: rcc-reboot@50000000 {
+ compatible = "syscon-reboot";
+ regmap = <&rcc>;
+ offset = <0x404>;
+ mask = <0x1>;
+ };
+
+ rng1: rng@54003000 {
+ compatible = "st,stm32-rng";
+ reg = <0x54003000 0x400>;
+ clocks = <&rcc RNG1_K>;
+ resets = <&rcc RNG1_R>;
+ status = "disabled";
+ };
+
+ fmc_nand: fmc_nand@58002000 {
+ compatible = "st,stm32mp1-fmc";
+ reg = <0x58002000 0x1000>,
+ <0x80000000 0x40000>,
+ <0x81000000 0x40000>,
+ <0x88000000 0x40000>,
+ <0x89000000 0x40000>;
+ clocks = <&rcc FMC_K>;
+ resets = <&rcc FMC_R>;
+ status = "disabled";
+ };
+
+ qspi: qspi@58003000 {
+ compatible = "st,stm32f469-qspi";
+ reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
+ clocks = <&rcc QSPI_K>;
+ status = "disabled";
+ };
+
+ sdmmc1: sdmmc@58005000 {
+ compatible = "st,stm32-sdmmc2";
+ reg = <0x58005000 0x1000>, <0x58006000 0x1000>;
+ reg-names = "sdmmc", "delay";
+ clocks = <&rcc SDMMC1_K>;
+ resets = <&rcc SDMMC1_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <120000000>;
+ status = "disabled";
+ };
+
+ sdmmc2: sdmmc@58007000 {
+ compatible = "st,stm32-sdmmc2";
+ reg = <0x58007000 0x1000>, <0x58008000 0x1000>;
+ reg-names = "sdmmc", "delay";
+ clocks = <&rcc SDMMC2_K>;
+ resets = <&rcc SDMMC2_R>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+ max-frequency = <120000000>;
+ status = "disabled";
+ };
+
+ iwdg2: iwdg@5a002000 {
+ compatible = "st,stm32mp1-iwdg";
+ reg = <0x5a002000 0x400>;
+ clocks = <&rcc IWDG2>, <&rcc CK_LSI>;
+ clock-names = "pclk", "lsi";
+ status = "disabled";
+ };
+
+ usart1: serial@5c000000 {
+ compatible = "st,stm32h7-usart";
+ reg = <0x5c000000 0x400>;
+ clocks = <&rcc USART1_K>;
+ status = "disabled";
+ };
+
+ i2c4: i2c@5c002000 {
+ compatible = "st,stm32f7-i2c";
+ reg = <0x5c002000 0x400>;
+ clocks = <&rcc I2C4_K>;
+ resets = <&rcc I2C4_R>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
+ rtc: rtc@5c004000 {
+ compatible = "st,stm32mp1-rtc";
+ reg = <0x5c004000 0x400>;
+ clocks = <&rcc RTCAPB>, <&rcc RTC>;
+ clock-names = "pclk", "rtc_ck";
+ };
+ };
+};
diff --git a/fdts/stm32mp157caa-pinctrl.dtsi b/fdts/stm32mp157caa-pinctrl.dtsi
new file mode 100644
index 000000000..774561aed
--- /dev/null
+++ b/fdts/stm32mp157caa-pinctrl.dtsi
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
+ */
+
+#include "stm32mp157-pinctrl.dtsi"
+/ {
+ soc {
+ pinctrl: pin-controller {
+ compatible = "st,stm32mp157caa-pinctrl";
+
+ gpioa: gpio@50002000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 0 16>;
+ };
+
+ gpiob: gpio@50003000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 16 16>;
+ };
+
+ gpioc: gpio@50004000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 32 16>;
+ };
+
+ gpiod: gpio@50005000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 48 16>;
+ };
+
+ gpioe: gpio@50006000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 64 16>;
+ };
+
+ gpiof: gpio@50007000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 80 16>;
+ };
+
+ gpiog: gpio@50008000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 96 16>;
+ };
+
+ gpioh: gpio@50009000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 112 16>;
+ };
+
+ gpioi: gpio@5000a000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 128 16>;
+ };
+
+ gpioj: gpio@5000b000 {
+ status = "okay";
+ ngpios = <16>;
+ gpio-ranges = <&pinctrl 0 144 16>;
+ };
+
+ gpiok: gpio@5000c000 {
+ status = "okay";
+ ngpios = <8>;
+ gpio-ranges = <&pinctrl 0 160 8>;
+ };
+ };
+
+ pinctrl_z: pin-controller-z {
+ compatible = "st,stm32mp157caa-z-pinctrl";
+
+ gpioz: gpio@54004000 {
+ status = "okay";
+ ngpios = <8>;
+ gpio-ranges = <&pinctrl_z 0 400 8>;
+ };
+ };
+ };
+};
diff --git a/include/bl31/ehf.h b/include/bl31/ehf.h
index f963f8d0c..f35d81002 100644
--- a/include/bl31/ehf.h
+++ b/include/bl31/ehf.h
@@ -4,36 +4,37 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __EHF_H__
-#define __EHF_H__
+#ifndef EHF_H
+#define EHF_H
#ifndef __ASSEMBLY__
+#include <cdefs.h>
#include <stdint.h>
#include <utils_def.h>
/* Valid priorities set bit 0 of the priority handler. */
-#define _EHF_PRI_VALID (((uintptr_t) 1) << 0)
+#define EHF_PRI_VALID_ BIT(0)
/* Marker for no handler registered for a valid priority */
-#define _EHF_NO_HANDLER (0 | _EHF_PRI_VALID)
+#define EHF_NO_HANDLER_ (0U | EHF_PRI_VALID_)
/* Extract the specified number of top bits from 7 lower bits of priority */
#define EHF_PRI_TO_IDX(pri, plat_bits) \
- ((pri & 0x7f) >> (7 - plat_bits))
+ ((((unsigned) (pri)) & 0x7fu) >> (7u - (plat_bits)))
/* Install exception priority descriptor at a suitable index */
#define EHF_PRI_DESC(plat_bits, priority) \
[EHF_PRI_TO_IDX(priority, plat_bits)] = { \
- .ehf_handler = _EHF_NO_HANDLER, \
+ .ehf_handler = EHF_NO_HANDLER_, \
}
/* Macro for platforms to regiter its exception priorities */
#define EHF_REGISTER_PRIORITIES(priorities, num, bits) \
const ehf_priorities_t exception_data = { \
- .num_priorities = num, \
- .ehf_priorities = priorities, \
- .pri_bits = bits, \
+ .num_priorities = (num), \
+ .ehf_priorities = (priorities), \
+ .pri_bits = (bits), \
}
/*
@@ -72,10 +73,10 @@ typedef struct ehf_pri_desc {
uintptr_t ehf_handler;
} ehf_pri_desc_t;
-typedef struct ehf_priorities {
+typedef struct ehf_priority_type {
ehf_pri_desc_t *ehf_priorities;
unsigned int num_priorities;
- int pri_bits;
+ unsigned int pri_bits;
} ehf_priorities_t;
void ehf_init(void);
@@ -87,4 +88,4 @@ unsigned int ehf_is_ns_preemption_allowed(void);
#endif /* __ASSEMBLY__ */
-#endif /* __EHF_H__ */
+#endif /* EHF_H */
diff --git a/include/bl31/interrupt_mgmt.h b/include/bl31/interrupt_mgmt.h
index 905dcd669..0cdbda02b 100644
--- a/include/bl31/interrupt_mgmt.h
+++ b/include/bl31/interrupt_mgmt.h
@@ -8,6 +8,7 @@
#define __INTERRUPT_MGMT_H__
#include <arch.h>
+#include <utils_def.h>
/*******************************************************************************
* Constants for the types of interrupts recognised by the IM framework
@@ -61,38 +62,10 @@
#define INTR_RM_FROM_SEC_SHIFT SECURE /* BIT[0] */
#define INTR_RM_FROM_NS_SHIFT NON_SECURE /* BIT[1] */
#define INTR_RM_FROM_FLAG_MASK U(1)
-#define get_interrupt_rm_flag(flag, ss) (((flag >> INTR_RM_FLAGS_SHIFT) >> ss) \
- & INTR_RM_FROM_FLAG_MASK)
-#define set_interrupt_rm_flag(flag, ss) (flag |= U(1) << ss)
-#define clr_interrupt_rm_flag(flag, ss) (flag &= ~(U(1) << ss))
-
-
-/*******************************************************************************
- * Macros to validate the routing model bits in the 'flags' for a type
- * of interrupt. If the model does not match one of the valid masks
- * -EINVAL is returned.
- ******************************************************************************/
-#define validate_sel1_interrupt_rm(x) ((x) == INTR_SEL1_VALID_RM0 ? 0 : \
- ((x) == INTR_SEL1_VALID_RM1 ? 0 :\
- -EINVAL))
-
-#define validate_ns_interrupt_rm(x) ((x) == INTR_NS_VALID_RM0 ? 0 : \
- ((x) == INTR_NS_VALID_RM1 ? 0 :\
- -EINVAL))
-
-#if EL3_EXCEPTION_HANDLING
-/*
- * With EL3 exception handling, EL3 interrupts are always routed to EL3 from
- * both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is the only
- * valid routing model.
- */
-#define validate_el3_interrupt_rm(x) ((x) == INTR_EL3_VALID_RM1 ? 0 : \
- -EINVAL)
-#else
-#define validate_el3_interrupt_rm(x) ((x) == INTR_EL3_VALID_RM0 ? 0 : \
- ((x) == INTR_EL3_VALID_RM1 ? 0 :\
- -EINVAL))
-#endif
+#define get_interrupt_rm_flag(flag, ss) \
+ ((((flag) >> INTR_RM_FLAGS_SHIFT) >> (ss)) & INTR_RM_FROM_FLAG_MASK)
+#define set_interrupt_rm_flag(flag, ss) ((flag) |= U(1) << (ss))
+#define clr_interrupt_rm_flag(flag, ss) ((flag) &= ~(U(1) << (ss)))
/*******************************************************************************
* Macros to set the 'flags' parameter passed to an interrupt type handler. Only
@@ -101,16 +74,58 @@
******************************************************************************/
#define INTR_SRC_SS_FLAG_SHIFT U(0) /* BIT[0] */
#define INTR_SRC_SS_FLAG_MASK U(1)
-#define set_interrupt_src_ss(flag, val) (flag |= val << INTR_SRC_SS_FLAG_SHIFT)
-#define clr_interrupt_src_ss(flag) (flag &= ~(U(1) << INTR_SRC_SS_FLAG_SHIFT))
-#define get_interrupt_src_ss(flag) ((flag >> INTR_SRC_SS_FLAG_SHIFT) & \
+#define set_interrupt_src_ss(flag, val) ((flag) |= (val) << INTR_SRC_SS_FLAG_SHIFT)
+#define clr_interrupt_src_ss(flag) ((flag) &= ~(U(1) << INTR_SRC_SS_FLAG_SHIFT))
+#define get_interrupt_src_ss(flag) (((flag) >> INTR_SRC_SS_FLAG_SHIFT) & \
INTR_SRC_SS_FLAG_MASK)
#ifndef __ASSEMBLY__
+#include <errno.h>
#include <stdint.h>
-/* Prototype for defining a handler for an interrupt type */
+/*******************************************************************************
+ * Helpers to validate the routing model bits in the 'flags' for a type
+ * of interrupt. If the model does not match one of the valid masks
+ * -EINVAL is returned.
+ ******************************************************************************/
+static inline int32_t validate_sel1_interrupt_rm(uint32_t x)
+{
+ if ((x == INTR_SEL1_VALID_RM0) || (x == INTR_SEL1_VALID_RM1))
+ return 0;
+
+ return -EINVAL;
+}
+
+static inline int32_t validate_ns_interrupt_rm(uint32_t x)
+{
+ if ((x == INTR_NS_VALID_RM0) || (x == INTR_NS_VALID_RM1))
+ return 0;
+
+ return -EINVAL;
+}
+
+static inline int32_t validate_el3_interrupt_rm(uint32_t x)
+{
+#if EL3_EXCEPTION_HANDLING
+ /*
+ * With EL3 exception handling, EL3 interrupts are always routed to EL3
+ * from both Secure and Non-secure, and therefore INTR_EL3_VALID_RM1 is
+ * the only valid routing model.
+ */
+ if (x == INTR_EL3_VALID_RM1)
+ return 0;
+#else
+ if ((x == INTR_EL3_VALID_RM0) || (x == INTR_EL3_VALID_RM1))
+ return 0;
+#endif
+
+ return -EINVAL;
+}
+
+/*******************************************************************************
+ * Prototype for defining a handler for an interrupt type
+ ******************************************************************************/
typedef uint64_t (*interrupt_type_handler_t)(uint32_t id,
uint32_t flags,
void *handle,
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index f64e6aee6..6478f12fc 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -61,7 +61,6 @@
#include <cassert.h>
#include <stddef.h>
#include <stdint.h>
-#include <types.h>
#include <utils_def.h> /* To retain compatibility */
diff --git a/include/common/debug.h b/include/common/debug.h
index 3f0f84a1b..8ee55b882 100644
--- a/include/common/debug.h
+++ b/include/common/debug.h
@@ -1,30 +1,37 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __DEBUG_H__
-#define __DEBUG_H__
+#ifndef DEBUG_H
+#define DEBUG_H
-/* The log output macros print output to the console. These macros produce
+#include <utils_def.h>
+
+/*
+ * The log output macros print output to the console. These macros produce
* compiled log output only if the LOG_LEVEL defined in the makefile (or the
* make command line) is greater or equal than the level required for that
* type of log output.
+ *
* The format expected is the same as for printf(). For example:
* INFO("Info %s.\n", "message") -> INFO: Info message.
* WARN("Warning %s.\n", "message") -> WARNING: Warning message.
*/
-#define LOG_LEVEL_NONE 0
-#define LOG_LEVEL_ERROR 10
-#define LOG_LEVEL_NOTICE 20
-#define LOG_LEVEL_WARNING 30
-#define LOG_LEVEL_INFO 40
-#define LOG_LEVEL_VERBOSE 50
+#define LOG_LEVEL_NONE U(0)
+#define LOG_LEVEL_ERROR U(10)
+#define LOG_LEVEL_NOTICE U(20)
+#define LOG_LEVEL_WARNING U(30)
+#define LOG_LEVEL_INFO U(40)
+#define LOG_LEVEL_VERBOSE U(50)
#ifndef __ASSEMBLY__
+#include <cdefs.h>
+#include <console.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdio.h>
/*
@@ -38,48 +45,68 @@
#define LOG_MARKER_INFO "\x28" /* 40 */
#define LOG_MARKER_VERBOSE "\x32" /* 50 */
+/*
+ * If the log output is too low then this macro is used in place of tf_log()
+ * below. The intent is to get the compiler to evaluate the function call for
+ * type checking and format specifier correctness but let it optimize it out.
+ */
+#define no_tf_log(fmt, ...) \
+ do { \
+ if (false) { \
+ tf_log(fmt, ##__VA_ARGS__); \
+ } \
+ } while (false)
+
#if LOG_LEVEL >= LOG_LEVEL_NOTICE
# define NOTICE(...) tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
#else
-# define NOTICE(...)
+# define NOTICE(...) no_tf_log(LOG_MARKER_NOTICE __VA_ARGS__)
#endif
#if LOG_LEVEL >= LOG_LEVEL_ERROR
# define ERROR(...) tf_log(LOG_MARKER_ERROR __VA_ARGS__)
#else
-# define ERROR(...)
+# define ERROR(...) no_tf_log(LOG_MARKER_ERROR __VA_ARGS__)
#endif
#if LOG_LEVEL >= LOG_LEVEL_WARNING
# define WARN(...) tf_log(LOG_MARKER_WARNING __VA_ARGS__)
#else
-# define WARN(...)
+# define WARN(...) no_tf_log(LOG_MARKER_WARNING __VA_ARGS__)
#endif
#if LOG_LEVEL >= LOG_LEVEL_INFO
# define INFO(...) tf_log(LOG_MARKER_INFO __VA_ARGS__)
#else
-# define INFO(...)
+# define INFO(...) no_tf_log(LOG_MARKER_INFO __VA_ARGS__)
#endif
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
# define VERBOSE(...) tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
#else
-# define VERBOSE(...)
+# define VERBOSE(...) no_tf_log(LOG_MARKER_VERBOSE __VA_ARGS__)
+#endif
+
+#if ENABLE_BACKTRACE
+void backtrace(const char *cookie);
+#else
+#define backtrace(x)
#endif
void __dead2 do_panic(void);
-#define panic() do_panic()
+
+#define panic() \
+ do { \
+ backtrace(__func__); \
+ (void)console_flush(); \
+ do_panic(); \
+ } while (false)
/* Function called when stack protection check code detects a corrupted stack */
void __dead2 __stack_chk_fail(void);
void tf_log(const char *fmt, ...) __printflike(1, 2);
-void tf_printf(const char *fmt, ...) __printflike(1, 2);
-int tf_snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4);
-void tf_vprintf(const char *fmt, va_list args);
-void tf_string_print(const char *str);
void tf_log_set_max_level(unsigned int log_level);
#endif /* __ASSEMBLY__ */
-#endif /* __DEBUG_H__ */
+#endif /* DEBUG_H */
diff --git a/include/common/ep_info.h b/include/common/ep_info.h
index 99a03906b..bf3f78236 100644
--- a/include/common/ep_info.h
+++ b/include/common/ep_info.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -65,7 +65,7 @@
#ifndef __ASSEMBLY__
#include <cassert.h>
-#include <types.h>
+#include <stdint.h>
typedef struct aapcs64_params {
u_register_t arg0;
diff --git a/include/common/param_header.h b/include/common/param_header.h
index c982fc90a..ec4ee4ee1 100644
--- a/include/common/param_header.h
+++ b/include/common/param_header.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,25 +7,28 @@
#ifndef __PARAM_HEADER_H__
#define __PARAM_HEADER_H__
+#include <stdbool.h>
+#include <utils_def.h>
+
/* Param header types */
-#define PARAM_EP 0x01
-#define PARAM_IMAGE_BINARY 0x02
-#define PARAM_BL31 0x03
-#define PARAM_BL_LOAD_INFO 0x04
-#define PARAM_BL_PARAMS 0x05
-#define PARAM_PSCI_LIB_ARGS 0x06
-#define PARAM_SP_IMAGE_BOOT_INFO 0x07
+#define PARAM_EP U(0x01)
+#define PARAM_IMAGE_BINARY U(0x02)
+#define PARAM_BL31 U(0x03)
+#define PARAM_BL_LOAD_INFO U(0x04)
+#define PARAM_BL_PARAMS U(0x05)
+#define PARAM_PSCI_LIB_ARGS U(0x06)
+#define PARAM_SP_IMAGE_BOOT_INFO U(0x07)
/* Param header version */
-#define VERSION_1 0x01
-#define VERSION_2 0x02
+#define VERSION_1 U(0x01)
+#define VERSION_2 U(0x02)
#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
(_p)->h.type = (uint8_t)(_type); \
(_p)->h.version = (uint8_t)(_ver); \
- (_p)->h.size = (uint16_t)sizeof(*_p); \
+ (_p)->h.size = (uint16_t)sizeof(*(_p)); \
(_p)->h.attr = (uint32_t)(_attr) ; \
- } while (0)
+ } while (false)
/* Following is used for populating structure members statically. */
#define SET_STATIC_PARAM_HEAD(_p, _type, _ver, _p_type, _attr) \
@@ -36,7 +39,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
/***************************************************************************
* This structure provides version information and the size of the
diff --git a/include/common/romlib.h b/include/common/romlib.h
new file mode 100644
index 000000000..81a6f5c1e
--- /dev/null
+++ b/include/common/romlib.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ROMLIB_H_
+
+#define ROMLIB_MAJOR 0
+#define ROMLIB_MINOR 1
+#define ROMLIB_VERSION ((ROMLIB_MAJOR << 8) | ROMLIB_MINOR)
+
+int rom_lib_init(int version);
+
+#endif
diff --git a/include/common/tbbr/tbbr_img_def.h b/include/common/tbbr/tbbr_img_def.h
index 273abbea0..a97914de6 100644
--- a/include/common/tbbr/tbbr_img_def.h
+++ b/include/common/tbbr/tbbr_img_def.h
@@ -7,75 +7,77 @@
#ifndef __TBBR_IMG_DEF_H__
#define __TBBR_IMG_DEF_H__
+#include <utils_def.h>
+
/* Firmware Image Package */
-#define FIP_IMAGE_ID 0
+#define FIP_IMAGE_ID U(0)
/* Trusted Boot Firmware BL2 */
-#define BL2_IMAGE_ID 1
+#define BL2_IMAGE_ID U(1)
/* SCP Firmware SCP_BL2 */
-#define SCP_BL2_IMAGE_ID 2
+#define SCP_BL2_IMAGE_ID U(2)
/* EL3 Runtime Firmware BL31 */
-#define BL31_IMAGE_ID 3
+#define BL31_IMAGE_ID U(3)
/* Secure Payload BL32 (Trusted OS) */
-#define BL32_IMAGE_ID 4
+#define BL32_IMAGE_ID U(4)
/* Non-Trusted Firmware BL33 */
-#define BL33_IMAGE_ID 5
+#define BL33_IMAGE_ID U(5)
/* Certificates */
-#define TRUSTED_BOOT_FW_CERT_ID 6
-#define TRUSTED_KEY_CERT_ID 7
+#define TRUSTED_BOOT_FW_CERT_ID U(6)
+#define TRUSTED_KEY_CERT_ID U(7)
-#define SCP_FW_KEY_CERT_ID 8
-#define SOC_FW_KEY_CERT_ID 9
-#define TRUSTED_OS_FW_KEY_CERT_ID 10
-#define NON_TRUSTED_FW_KEY_CERT_ID 11
+#define SCP_FW_KEY_CERT_ID U(8)
+#define SOC_FW_KEY_CERT_ID U(9)
+#define TRUSTED_OS_FW_KEY_CERT_ID U(10)
+#define NON_TRUSTED_FW_KEY_CERT_ID U(11)
-#define SCP_FW_CONTENT_CERT_ID 12
-#define SOC_FW_CONTENT_CERT_ID 13
-#define TRUSTED_OS_FW_CONTENT_CERT_ID 14
-#define NON_TRUSTED_FW_CONTENT_CERT_ID 15
+#define SCP_FW_CONTENT_CERT_ID U(12)
+#define SOC_FW_CONTENT_CERT_ID U(13)
+#define TRUSTED_OS_FW_CONTENT_CERT_ID U(14)
+#define NON_TRUSTED_FW_CONTENT_CERT_ID U(15)
/* Non-Trusted ROM Firmware NS_BL1U */
-#define NS_BL1U_IMAGE_ID 16
+#define NS_BL1U_IMAGE_ID U(16)
/* Trusted FWU Certificate */
-#define FWU_CERT_ID 17
+#define FWU_CERT_ID U(17)
/* Trusted FWU SCP Firmware SCP_BL2U */
-#define SCP_BL2U_IMAGE_ID 18
+#define SCP_BL2U_IMAGE_ID U(18)
/* Trusted FWU Boot Firmware BL2U */
-#define BL2U_IMAGE_ID 19
+#define BL2U_IMAGE_ID U(19)
/* Non-Trusted FWU Firmware NS_BL2U */
-#define NS_BL2U_IMAGE_ID 20
+#define NS_BL2U_IMAGE_ID U(20)
/* Secure Payload BL32_EXTRA1 (Trusted OS Extra1) */
-#define BL32_EXTRA1_IMAGE_ID 21
+#define BL32_EXTRA1_IMAGE_ID U(21)
/* Secure Payload BL32_EXTRA2 (Trusted OS Extra2) */
-#define BL32_EXTRA2_IMAGE_ID 22
+#define BL32_EXTRA2_IMAGE_ID U(22)
/* HW_CONFIG (e.g. Kernel DT) */
-#define HW_CONFIG_ID 23
+#define HW_CONFIG_ID U(23)
/* TB_FW_CONFIG */
-#define TB_FW_CONFIG_ID 24
+#define TB_FW_CONFIG_ID U(24)
/* SOC_FW_CONFIG */
-#define SOC_FW_CONFIG_ID 25
+#define SOC_FW_CONFIG_ID U(25)
/* TOS_FW_CONFIG */
-#define TOS_FW_CONFIG_ID 26
+#define TOS_FW_CONFIG_ID U(26)
/* NT_FW_CONFIG */
-#define NT_FW_CONFIG_ID 27
+#define NT_FW_CONFIG_ID U(27)
/* Define size of the array */
-#define MAX_NUMBER_IDS 28
+#define MAX_NUMBER_IDS U(28)
#endif /* __TBBR_IMG_DEF_H__ */
diff --git a/include/drivers/arm/arm_gic.h b/include/drivers/arm/arm_gic.h
index 019159f92..8d2a23228 100644
--- a/include/drivers/arm/arm_gic.h
+++ b/include/drivers/arm/arm_gic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#ifndef __ARM_GIC_H__
#define __ARM_GIC_H__
+#include <cdefs.h>
#include <stdint.h>
/*******************************************************************************
diff --git a/include/drivers/arm/cci.h b/include/drivers/arm/cci.h
index 1def6a8f2..41a3de257 100644
--- a/include/drivers/arm/cci.h
+++ b/include/drivers/arm/cci.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,94 +7,96 @@
#ifndef __CCI_H__
#define __CCI_H__
+#include <utils_def.h>
+
/* Slave interface offsets from PERIPHBASE */
-#define SLAVE_IFACE6_OFFSET 0x7000
-#define SLAVE_IFACE5_OFFSET 0x6000
-#define SLAVE_IFACE4_OFFSET 0x5000
-#define SLAVE_IFACE3_OFFSET 0x4000
-#define SLAVE_IFACE2_OFFSET 0x3000
-#define SLAVE_IFACE1_OFFSET 0x2000
-#define SLAVE_IFACE0_OFFSET 0x1000
-#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \
- (0x1000 * (index)))
+#define SLAVE_IFACE6_OFFSET UL(0x7000)
+#define SLAVE_IFACE5_OFFSET UL(0x6000)
+#define SLAVE_IFACE4_OFFSET UL(0x5000)
+#define SLAVE_IFACE3_OFFSET UL(0x4000)
+#define SLAVE_IFACE2_OFFSET UL(0x3000)
+#define SLAVE_IFACE1_OFFSET UL(0x2000)
+#define SLAVE_IFACE0_OFFSET UL(0x1000)
+#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \
+ (UL(0x1000) * (index)))
/* Slave interface event and count register offsets from PERIPHBASE */
-#define EVENT_SELECT7_OFFSET 0x80000
-#define EVENT_SELECT6_OFFSET 0x70000
-#define EVENT_SELECT5_OFFSET 0x60000
-#define EVENT_SELECT4_OFFSET 0x50000
-#define EVENT_SELECT3_OFFSET 0x40000
-#define EVENT_SELECT2_OFFSET 0x30000
-#define EVENT_SELECT1_OFFSET 0x20000
-#define EVENT_SELECT0_OFFSET 0x10000
-#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \
- (0x10000 * (index)))
+#define EVENT_SELECT7_OFFSET UL(0x80000)
+#define EVENT_SELECT6_OFFSET UL(0x70000)
+#define EVENT_SELECT5_OFFSET UL(0x60000)
+#define EVENT_SELECT4_OFFSET UL(0x50000)
+#define EVENT_SELECT3_OFFSET UL(0x40000)
+#define EVENT_SELECT2_OFFSET UL(0x30000)
+#define EVENT_SELECT1_OFFSET UL(0x20000)
+#define EVENT_SELECT0_OFFSET UL(0x10000)
+#define EVENT_OFFSET(index) (EVENT_SELECT0_OFFSET + \
+ (UL(0x10000) * (index)))
/* Control and ID register offsets */
-#define CTRL_OVERRIDE_REG 0x0
-#define SECURE_ACCESS_REG 0x8
-#define STATUS_REG 0xc
-#define IMPRECISE_ERR_REG 0x10
-#define PERFMON_CTRL_REG 0x100
-#define IFACE_MON_CTRL_REG 0x104
+#define CTRL_OVERRIDE_REG U(0x0)
+#define SECURE_ACCESS_REG U(0x8)
+#define STATUS_REG U(0xc)
+#define IMPRECISE_ERR_REG U(0x10)
+#define PERFMON_CTRL_REG U(0x100)
+#define IFACE_MON_CTRL_REG U(0x104)
/* Component and peripheral ID registers */
-#define PERIPHERAL_ID0 0xFE0
-#define PERIPHERAL_ID1 0xFE4
-#define PERIPHERAL_ID2 0xFE8
-#define PERIPHERAL_ID3 0xFEC
-#define PERIPHERAL_ID4 0xFD0
-#define PERIPHERAL_ID5 0xFD4
-#define PERIPHERAL_ID6 0xFD8
-#define PERIPHERAL_ID7 0xFDC
-
-#define COMPONENT_ID0 0xFF0
-#define COMPONENT_ID1 0xFF4
-#define COMPONENT_ID2 0xFF8
-#define COMPONENT_ID3 0xFFC
-#define COMPONENT_ID4 0x1000
-#define COMPONENT_ID5 0x1004
-#define COMPONENT_ID6 0x1008
-#define COMPONENT_ID7 0x100C
+#define PERIPHERAL_ID0 U(0xFE0)
+#define PERIPHERAL_ID1 U(0xFE4)
+#define PERIPHERAL_ID2 U(0xFE8)
+#define PERIPHERAL_ID3 U(0xFEC)
+#define PERIPHERAL_ID4 U(0xFD0)
+#define PERIPHERAL_ID5 U(0xFD4)
+#define PERIPHERAL_ID6 U(0xFD8)
+#define PERIPHERAL_ID7 U(0xFDC)
+
+#define COMPONENT_ID0 U(0xFF0)
+#define COMPONENT_ID1 U(0xFF4)
+#define COMPONENT_ID2 U(0xFF8)
+#define COMPONENT_ID3 U(0xFFC)
+#define COMPONENT_ID4 U(0x1000)
+#define COMPONENT_ID5 U(0x1004)
+#define COMPONENT_ID6 U(0x1008)
+#define COMPONENT_ID7 U(0x100C)
/* Slave interface register offsets */
-#define SNOOP_CTRL_REG 0x0
-#define SH_OVERRIDE_REG 0x4
-#define READ_CHNL_QOS_VAL_OVERRIDE_REG 0x100
-#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG 0x104
-#define MAX_OT_REG 0x110
+#define SNOOP_CTRL_REG U(0x0)
+#define SH_OVERRIDE_REG U(0x4)
+#define READ_CHNL_QOS_VAL_OVERRIDE_REG U(0x100)
+#define WRITE_CHNL_QOS_VAL_OVERRIDE_REG U(0x104)
+#define MAX_OT_REG U(0x110)
/* Snoop Control register bit definitions */
-#define DVM_EN_BIT (1 << 1)
-#define SNOOP_EN_BIT (1 << 0)
-#define SUPPORT_SNOOPS (1 << 30)
-#define SUPPORT_DVM (1 << 31)
+#define DVM_EN_BIT BIT_32(1)
+#define SNOOP_EN_BIT BIT_32(0)
+#define SUPPORT_SNOOPS BIT_32(30)
+#define SUPPORT_DVM BIT_32(31)
/* Status register bit definitions */
-#define CHANGE_PENDING_BIT (1 << 0)
+#define CHANGE_PENDING_BIT BIT_32(0)
/* Event and count register offsets */
-#define EVENT_SELECT_REG 0x0
-#define EVENT_COUNT_REG 0x4
-#define COUNT_CNTRL_REG 0x8
-#define COUNT_OVERFLOW_REG 0xC
+#define EVENT_SELECT_REG U(0x0)
+#define EVENT_COUNT_REG U(0x4)
+#define COUNT_CNTRL_REG U(0x8)
+#define COUNT_OVERFLOW_REG U(0xC)
/* Slave interface monitor registers */
-#define INT_MON_REG_SI0 0x90000
-#define INT_MON_REG_SI1 0x90004
-#define INT_MON_REG_SI2 0x90008
-#define INT_MON_REG_SI3 0x9000C
-#define INT_MON_REG_SI4 0x90010
-#define INT_MON_REG_SI5 0x90014
-#define INT_MON_REG_SI6 0x90018
+#define INT_MON_REG_SI0 U(0x90000)
+#define INT_MON_REG_SI1 U(0x90004)
+#define INT_MON_REG_SI2 U(0x90008)
+#define INT_MON_REG_SI3 U(0x9000C)
+#define INT_MON_REG_SI4 U(0x90010)
+#define INT_MON_REG_SI5 U(0x90014)
+#define INT_MON_REG_SI6 U(0x90018)
/* Master interface monitor registers */
-#define INT_MON_REG_MI0 0x90100
-#define INT_MON_REG_MI1 0x90104
-#define INT_MON_REG_MI2 0x90108
-#define INT_MON_REG_MI3 0x9010c
-#define INT_MON_REG_MI4 0x90110
-#define INT_MON_REG_MI5 0x90114
+#define INT_MON_REG_MI0 U(0x90100)
+#define INT_MON_REG_MI1 U(0x90104)
+#define INT_MON_REG_MI2 U(0x90108)
+#define INT_MON_REG_MI3 U(0x9010c)
+#define INT_MON_REG_MI4 U(0x90110)
+#define INT_MON_REG_MI5 U(0x90114)
#define SLAVE_IF_UNUSED -1
diff --git a/include/drivers/arm/gic_common.h b/include/drivers/arm/gic_common.h
index 6e953a0dc..0ef114833 100644
--- a/include/drivers/arm/gic_common.h
+++ b/include/drivers/arm/gic_common.h
@@ -7,73 +7,75 @@
#ifndef __GIC_COMMON_H__
#define __GIC_COMMON_H__
+#include <utils_def.h>
+
/*******************************************************************************
* GIC Distributor interface general definitions
******************************************************************************/
/* Constants to categorise interrupts */
-#define MIN_SGI_ID 0
-#define MIN_SEC_SGI_ID 8
-#define MIN_PPI_ID 16
-#define MIN_SPI_ID 32
-#define MAX_SPI_ID 1019
+#define MIN_SGI_ID U(0)
+#define MIN_SEC_SGI_ID U(8)
+#define MIN_PPI_ID U(16)
+#define MIN_SPI_ID U(32)
+#define MAX_SPI_ID U(1019)
-#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + 1)
+#define TOTAL_SPI_INTR_NUM (MAX_SPI_ID - MIN_SPI_ID + U(1))
#define TOTAL_PCPU_INTR_NUM (MIN_SPI_ID - MIN_SGI_ID)
/* Mask for the priority field common to all GIC interfaces */
-#define GIC_PRI_MASK 0xff
+#define GIC_PRI_MASK U(0xff)
/* Mask for the configuration field common to all GIC interfaces */
-#define GIC_CFG_MASK 0x3
+#define GIC_CFG_MASK U(0x3)
/* Constant to indicate a spurious interrupt in all GIC versions */
-#define GIC_SPURIOUS_INTERRUPT 1023
+#define GIC_SPURIOUS_INTERRUPT U(1023)
/* Interrupt configurations: 2-bit fields with LSB reserved */
#define GIC_INTR_CFG_LEVEL (0 << 1)
#define GIC_INTR_CFG_EDGE (1 << 1)
/* Constants to categorise priorities */
-#define GIC_HIGHEST_SEC_PRIORITY 0x0
-#define GIC_LOWEST_SEC_PRIORITY 0x7f
-#define GIC_HIGHEST_NS_PRIORITY 0x80
-#define GIC_LOWEST_NS_PRIORITY 0xfe /* 0xff would disable all interrupts */
+#define GIC_HIGHEST_SEC_PRIORITY U(0x00)
+#define GIC_LOWEST_SEC_PRIORITY U(0x7f)
+#define GIC_HIGHEST_NS_PRIORITY U(0x80)
+#define GIC_LOWEST_NS_PRIORITY U(0xfe) /* 0xff would disable all interrupts */
/*******************************************************************************
* GIC Distributor interface register offsets that are common to GICv3 & GICv2
******************************************************************************/
-#define GICD_CTLR 0x0
-#define GICD_TYPER 0x4
-#define GICD_IIDR 0x8
-#define GICD_IGROUPR 0x80
-#define GICD_ISENABLER 0x100
-#define GICD_ICENABLER 0x180
-#define GICD_ISPENDR 0x200
-#define GICD_ICPENDR 0x280
-#define GICD_ISACTIVER 0x300
-#define GICD_ICACTIVER 0x380
-#define GICD_IPRIORITYR 0x400
-#define GICD_ICFGR 0xc00
-#define GICD_NSACR 0xe00
+#define GICD_CTLR U(0x0)
+#define GICD_TYPER U(0x4)
+#define GICD_IIDR U(0x8)
+#define GICD_IGROUPR U(0x80)
+#define GICD_ISENABLER U(0x100)
+#define GICD_ICENABLER U(0x180)
+#define GICD_ISPENDR U(0x200)
+#define GICD_ICPENDR U(0x280)
+#define GICD_ISACTIVER U(0x300)
+#define GICD_ICACTIVER U(0x380)
+#define GICD_IPRIORITYR U(0x400)
+#define GICD_ICFGR U(0xc00)
+#define GICD_NSACR U(0xe00)
/* GICD_CTLR bit definitions */
#define CTLR_ENABLE_G0_SHIFT 0
-#define CTLR_ENABLE_G0_MASK 0x1
-#define CTLR_ENABLE_G0_BIT (1 << CTLR_ENABLE_G0_SHIFT)
+#define CTLR_ENABLE_G0_MASK U(0x1)
+#define CTLR_ENABLE_G0_BIT BIT_32(CTLR_ENABLE_G0_SHIFT)
/*******************************************************************************
* GIC Distributor interface register constants that are common to GICv3 & GICv2
******************************************************************************/
#define PIDR2_ARCH_REV_SHIFT 4
-#define PIDR2_ARCH_REV_MASK 0xf
+#define PIDR2_ARCH_REV_MASK U(0xf)
/* GICv3 revision as reported by the PIDR2 register */
-#define ARCH_REV_GICV3 0x3
+#define ARCH_REV_GICV3 U(0x3)
/* GICv2 revision as reported by the PIDR2 register */
-#define ARCH_REV_GICV2 0x2
+#define ARCH_REV_GICV2 U(0x2)
/* GICv1 revision as reported by the PIDR2 register */
-#define ARCH_REV_GICV1 0x1
+#define ARCH_REV_GICV1 U(0x1)
#define IGROUPR_SHIFT 5
#define ISENABLER_SHIFT 5
@@ -88,8 +90,8 @@
#define NSACR_SHIFT 4
/* GICD_TYPER shifts and masks */
-#define TYPER_IT_LINES_NO_SHIFT 0
-#define TYPER_IT_LINES_NO_MASK 0x1f
+#define TYPER_IT_LINES_NO_SHIFT U(0)
+#define TYPER_IT_LINES_NO_MASK U(0x1f)
/* Value used to initialize Normal world interrupt priorities four at a time */
#define GICD_IPRIORITYR_DEF_VAL \
diff --git a/include/drivers/arm/gic_v3.h b/include/drivers/arm/gic_v3.h
index 02f9006f3..549b4d9f3 100644
--- a/include/drivers/arm/gic_v3.h
+++ b/include/drivers/arm/gic_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,8 +17,6 @@
#include <mmio.h>
#include <stdint.h>
-#include <types.h>
-
/* GICv3 Re-distributor interface registers & shifts */
#define GICR_PCPUBASE_SHIFT 0x11
diff --git a/include/drivers/arm/gicv2.h b/include/drivers/arm/gicv2.h
index 39c73027e..02ffa0235 100644
--- a/include/drivers/arm/gicv2.h
+++ b/include/drivers/arm/gicv2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,37 +12,37 @@
******************************************************************************/
/* Interrupt group definitions */
-#define GICV2_INTR_GROUP0 0
-#define GICV2_INTR_GROUP1 1
+#define GICV2_INTR_GROUP0 U(0)
+#define GICV2_INTR_GROUP1 U(1)
/* Interrupt IDs reported by the HPPIR and IAR registers */
-#define PENDING_G1_INTID 1022
+#define PENDING_G1_INTID U(1022)
/* GICv2 can only target up to 8 PEs */
-#define GICV2_MAX_TARGET_PE 8
+#define GICV2_MAX_TARGET_PE U(8)
/*******************************************************************************
* GICv2 specific Distributor interface register offsets and constants.
******************************************************************************/
-#define GICD_ITARGETSR 0x800
-#define GICD_SGIR 0xF00
-#define GICD_CPENDSGIR 0xF10
-#define GICD_SPENDSGIR 0xF20
-#define GICD_PIDR2_GICV2 0xFE8
+#define GICD_ITARGETSR U(0x800)
+#define GICD_SGIR U(0xF00)
+#define GICD_CPENDSGIR U(0xF10)
+#define GICD_SPENDSGIR U(0xF20)
+#define GICD_PIDR2_GICV2 U(0xFE8)
#define ITARGETSR_SHIFT 2
-#define GIC_TARGET_CPU_MASK 0xff
+#define GIC_TARGET_CPU_MASK U(0xff)
#define CPENDSGIR_SHIFT 2
#define SPENDSGIR_SHIFT CPENDSGIR_SHIFT
#define SGIR_TGTLSTFLT_SHIFT 24
-#define SGIR_TGTLSTFLT_MASK 0x3
+#define SGIR_TGTLSTFLT_MASK U(0x3)
#define SGIR_TGTLST_SHIFT 16
-#define SGIR_TGTLST_MASK 0xff
-#define SGIR_INTID_MASK 0xf
+#define SGIR_TGTLST_MASK U(0xff)
+#define SGIR_INTID_MASK ULL(0xf)
-#define SGIR_TGT_SPECIFIC 0
+#define SGIR_TGT_SPECIFIC U(0)
#define GICV2_SGIR_VALUE(tgt_lst_flt, tgt, intid) \
((((tgt_lst_flt) & SGIR_TGTLSTFLT_MASK) << SGIR_TGTLSTFLT_SHIFT) | \
@@ -53,29 +53,29 @@
* GICv2 specific CPU interface register offsets and constants.
******************************************************************************/
/* Physical CPU Interface registers */
-#define GICC_CTLR 0x0
-#define GICC_PMR 0x4
-#define GICC_BPR 0x8
-#define GICC_IAR 0xC
-#define GICC_EOIR 0x10
-#define GICC_RPR 0x14
-#define GICC_HPPIR 0x18
-#define GICC_AHPPIR 0x28
-#define GICC_IIDR 0xFC
-#define GICC_DIR 0x1000
+#define GICC_CTLR U(0x0)
+#define GICC_PMR U(0x4)
+#define GICC_BPR U(0x8)
+#define GICC_IAR U(0xC)
+#define GICC_EOIR U(0x10)
+#define GICC_RPR U(0x14)
+#define GICC_HPPIR U(0x18)
+#define GICC_AHPPIR U(0x28)
+#define GICC_IIDR U(0xFC)
+#define GICC_DIR U(0x1000)
#define GICC_PRIODROP GICC_EOIR
/* GICC_CTLR bit definitions */
-#define EOI_MODE_NS (1 << 10)
-#define EOI_MODE_S (1 << 9)
-#define IRQ_BYP_DIS_GRP1 (1 << 8)
-#define FIQ_BYP_DIS_GRP1 (1 << 7)
-#define IRQ_BYP_DIS_GRP0 (1 << 6)
-#define FIQ_BYP_DIS_GRP0 (1 << 5)
-#define CBPR (1 << 4)
+#define EOI_MODE_NS BIT_32(10)
+#define EOI_MODE_S BIT_32(9)
+#define IRQ_BYP_DIS_GRP1 BIT_32(8)
+#define FIQ_BYP_DIS_GRP1 BIT_32(7)
+#define IRQ_BYP_DIS_GRP0 BIT_32(6)
+#define FIQ_BYP_DIS_GRP0 BIT_32(5)
+#define CBPR BIT_32(4)
#define FIQ_EN_SHIFT 3
-#define FIQ_EN_BIT (1 << FIQ_EN_SHIFT)
-#define ACK_CTL (1 << 2)
+#define FIQ_EN_BIT BIT_32(FIQ_EN_SHIFT)
+#define ACK_CTL BIT_32(2)
/* GICC_IIDR bit masks and shifts */
#define GICC_IIDR_PID_SHIFT 20
@@ -83,39 +83,40 @@
#define GICC_IIDR_REV_SHIFT 12
#define GICC_IIDR_IMP_SHIFT 0
-#define GICC_IIDR_PID_MASK 0xfff
-#define GICC_IIDR_ARCH_MASK 0xf
-#define GICC_IIDR_REV_MASK 0xf
-#define GICC_IIDR_IMP_MASK 0xfff
+#define GICC_IIDR_PID_MASK U(0xfff)
+#define GICC_IIDR_ARCH_MASK U(0xf)
+#define GICC_IIDR_REV_MASK U(0xf)
+#define GICC_IIDR_IMP_MASK U(0xfff)
/* HYP view virtual CPU Interface registers */
-#define GICH_CTL 0x0
-#define GICH_VTR 0x4
-#define GICH_ELRSR0 0x30
-#define GICH_ELRSR1 0x34
-#define GICH_APR0 0xF0
-#define GICH_LR_BASE 0x100
+#define GICH_CTL U(0x0)
+#define GICH_VTR U(0x4)
+#define GICH_ELRSR0 U(0x30)
+#define GICH_ELRSR1 U(0x34)
+#define GICH_APR0 U(0xF0)
+#define GICH_LR_BASE U(0x100)
/* Virtual CPU Interface registers */
-#define GICV_CTL 0x0
-#define GICV_PRIMASK 0x4
-#define GICV_BP 0x8
-#define GICV_INTACK 0xC
-#define GICV_EOI 0x10
-#define GICV_RUNNINGPRI 0x14
-#define GICV_HIGHESTPEND 0x18
-#define GICV_DEACTIVATE 0x1000
+#define GICV_CTL U(0x0)
+#define GICV_PRIMASK U(0x4)
+#define GICV_BP U(0x8)
+#define GICV_INTACK U(0xC)
+#define GICV_EOI U(0x10)
+#define GICV_RUNNINGPRI U(0x14)
+#define GICV_HIGHESTPEND U(0x18)
+#define GICV_DEACTIVATE U(0x1000)
/* GICD_CTLR bit definitions */
#define CTLR_ENABLE_G1_SHIFT 1
-#define CTLR_ENABLE_G1_MASK 0x1
-#define CTLR_ENABLE_G1_BIT (1 << CTLR_ENABLE_G1_SHIFT)
+#define CTLR_ENABLE_G1_MASK U(0x1)
+#define CTLR_ENABLE_G1_BIT BIT_32(CTLR_ENABLE_G1_SHIFT)
/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
-#define INT_ID_MASK 0x3ff
+#define INT_ID_MASK U(0x3ff)
#ifndef __ASSEMBLY__
+#include <cdefs.h>
#include <interrupt_props.h>
#include <stdint.h>
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 37c92e4f8..c9e28bae6 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -11,35 +11,35 @@
* GICv3 miscellaneous definitions
******************************************************************************/
/* Interrupt group definitions */
-#define INTR_GROUP1S 0
-#define INTR_GROUP0 1
-#define INTR_GROUP1NS 2
+#define INTR_GROUP1S U(0)
+#define INTR_GROUP0 U(1)
+#define INTR_GROUP1NS U(2)
/* Interrupt IDs reported by the HPPIR and IAR registers */
-#define PENDING_G1S_INTID 1020
-#define PENDING_G1NS_INTID 1021
+#define PENDING_G1S_INTID U(1020)
+#define PENDING_G1NS_INTID U(1021)
/* Constant to categorize LPI interrupt */
-#define MIN_LPI_ID 8192
+#define MIN_LPI_ID U(8192)
/* GICv3 can only target up to 16 PEs with SGI */
-#define GICV3_MAX_SGI_TARGETS 16
+#define GICV3_MAX_SGI_TARGETS U(16)
/*******************************************************************************
* GICv3 specific Distributor interface register offsets and constants.
******************************************************************************/
-#define GICD_STATUSR 0x10
-#define GICD_SETSPI_NSR 0x40
-#define GICD_CLRSPI_NSR 0x48
-#define GICD_SETSPI_SR 0x50
-#define GICD_CLRSPI_SR 0x50
-#define GICD_IGRPMODR 0xd00
+#define GICD_STATUSR U(0x10)
+#define GICD_SETSPI_NSR U(0x40)
+#define GICD_CLRSPI_NSR U(0x48)
+#define GICD_SETSPI_SR U(0x50)
+#define GICD_CLRSPI_SR U(0x50)
+#define GICD_IGRPMODR U(0xd00)
/*
* GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt id and
* n >= 32, making the effective offset as 0x6100.
*/
-#define GICD_IROUTER 0x6000
-#define GICD_PIDR2_GICV3 0xffe8
+#define GICD_IROUTER U(0x6000)
+#define GICD_PIDR2_GICV3 U(0xffe8)
#define IGRPMODR_SHIFT 5
@@ -52,29 +52,29 @@
#define CTLR_E1NWF_SHIFT 7
#define GICD_CTLR_RWP_SHIFT 31
-#define CTLR_ENABLE_G1NS_MASK 0x1
-#define CTLR_ENABLE_G1S_MASK 0x1
-#define CTLR_ARE_S_MASK 0x1
-#define CTLR_ARE_NS_MASK 0x1
-#define CTLR_DS_MASK 0x1
-#define CTLR_E1NWF_MASK 0x1
-#define GICD_CTLR_RWP_MASK 0x1
-
-#define CTLR_ENABLE_G1NS_BIT (1 << CTLR_ENABLE_G1NS_SHIFT)
-#define CTLR_ENABLE_G1S_BIT (1 << CTLR_ENABLE_G1S_SHIFT)
-#define CTLR_ARE_S_BIT (1 << CTLR_ARE_S_SHIFT)
-#define CTLR_ARE_NS_BIT (1 << CTLR_ARE_NS_SHIFT)
-#define CTLR_DS_BIT (1 << CTLR_DS_SHIFT)
-#define CTLR_E1NWF_BIT (1 << CTLR_E1NWF_SHIFT)
-#define GICD_CTLR_RWP_BIT (1 << GICD_CTLR_RWP_SHIFT)
+#define CTLR_ENABLE_G1NS_MASK U(0x1)
+#define CTLR_ENABLE_G1S_MASK U(0x1)
+#define CTLR_ARE_S_MASK U(0x1)
+#define CTLR_ARE_NS_MASK U(0x1)
+#define CTLR_DS_MASK U(0x1)
+#define CTLR_E1NWF_MASK U(0x1)
+#define GICD_CTLR_RWP_MASK U(0x1)
+
+#define CTLR_ENABLE_G1NS_BIT BIT_32(CTLR_ENABLE_G1NS_SHIFT)
+#define CTLR_ENABLE_G1S_BIT BIT_32(CTLR_ENABLE_G1S_SHIFT)
+#define CTLR_ARE_S_BIT BIT_32(CTLR_ARE_S_SHIFT)
+#define CTLR_ARE_NS_BIT BIT_32(CTLR_ARE_NS_SHIFT)
+#define CTLR_DS_BIT BIT_32(CTLR_DS_SHIFT)
+#define CTLR_E1NWF_BIT BIT_32(CTLR_E1NWF_SHIFT)
+#define GICD_CTLR_RWP_BIT BIT_32(GICD_CTLR_RWP_SHIFT)
/* GICD_IROUTER shifts and masks */
#define IROUTER_SHIFT 0
#define IROUTER_IRM_SHIFT 31
-#define IROUTER_IRM_MASK 0x1
+#define IROUTER_IRM_MASK U(0x1)
-#define GICV3_IRM_PE 0
-#define GICV3_IRM_ANY 1
+#define GICV3_IRM_PE U(0)
+#define GICV3_IRM_ANY U(1)
#define NUM_OF_DIST_REGS 30
@@ -82,54 +82,54 @@
* GICv3 Re-distributor interface registers & constants
******************************************************************************/
#define GICR_PCPUBASE_SHIFT 0x11
-#define GICR_SGIBASE_OFFSET (1 << 0x10) /* 64 KB */
-#define GICR_CTLR 0x0
-#define GICR_TYPER 0x08
-#define GICR_WAKER 0x14
-#define GICR_PROPBASER 0x70
-#define GICR_PENDBASER 0x78
-#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + 0x80)
-#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + 0x100)
-#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + 0x180)
-#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + 0x200)
-#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + 0x280)
-#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + 0x300)
-#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + 0x380)
-#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + 0x400)
-#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + 0xc00)
-#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + 0xc04)
-#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + 0xd00)
-#define GICR_NSACR (GICR_SGIBASE_OFFSET + 0xe00)
+#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
+#define GICR_CTLR U(0x0)
+#define GICR_TYPER U(0x08)
+#define GICR_WAKER U(0x14)
+#define GICR_PROPBASER U(0x70)
+#define GICR_PENDBASER U(0x78)
+#define GICR_IGROUPR0 (GICR_SGIBASE_OFFSET + U(0x80))
+#define GICR_ISENABLER0 (GICR_SGIBASE_OFFSET + U(0x100))
+#define GICR_ICENABLER0 (GICR_SGIBASE_OFFSET + U(0x180))
+#define GICR_ISPENDR0 (GICR_SGIBASE_OFFSET + U(0x200))
+#define GICR_ICPENDR0 (GICR_SGIBASE_OFFSET + U(0x280))
+#define GICR_ISACTIVER0 (GICR_SGIBASE_OFFSET + U(0x300))
+#define GICR_ICACTIVER0 (GICR_SGIBASE_OFFSET + U(0x380))
+#define GICR_IPRIORITYR (GICR_SGIBASE_OFFSET + U(0x400))
+#define GICR_ICFGR0 (GICR_SGIBASE_OFFSET + U(0xc00))
+#define GICR_ICFGR1 (GICR_SGIBASE_OFFSET + U(0xc04))
+#define GICR_IGRPMODR0 (GICR_SGIBASE_OFFSET + U(0xd00))
+#define GICR_NSACR (GICR_SGIBASE_OFFSET + U(0xe00))
/* GICR_CTLR bit definitions */
#define GICR_CTLR_UWP_SHIFT 31
-#define GICR_CTLR_UWP_MASK 0x1
-#define GICR_CTLR_UWP_BIT (1U << GICR_CTLR_UWP_SHIFT)
+#define GICR_CTLR_UWP_MASK U(0x1)
+#define GICR_CTLR_UWP_BIT BIT_32(GICR_CTLR_UWP_SHIFT)
#define GICR_CTLR_RWP_SHIFT 3
-#define GICR_CTLR_RWP_MASK 0x1
-#define GICR_CTLR_RWP_BIT (1U << GICR_CTLR_RWP_SHIFT)
-#define GICR_CTLR_EN_LPIS_BIT (1U << 0)
+#define GICR_CTLR_RWP_MASK U(0x1)
+#define GICR_CTLR_RWP_BIT BIT_32(GICR_CTLR_RWP_SHIFT)
+#define GICR_CTLR_EN_LPIS_BIT BIT_32(0)
/* GICR_WAKER bit definitions */
#define WAKER_CA_SHIFT 2
#define WAKER_PS_SHIFT 1
-#define WAKER_CA_MASK 0x1
-#define WAKER_PS_MASK 0x1
+#define WAKER_CA_MASK U(0x1)
+#define WAKER_PS_MASK U(0x1)
-#define WAKER_CA_BIT (1 << WAKER_CA_SHIFT)
-#define WAKER_PS_BIT (1 << WAKER_PS_SHIFT)
+#define WAKER_CA_BIT BIT_32(WAKER_CA_SHIFT)
+#define WAKER_PS_BIT BIT_32(WAKER_PS_SHIFT)
/* GICR_TYPER bit definitions */
#define TYPER_AFF_VAL_SHIFT 32
#define TYPER_PROC_NUM_SHIFT 8
#define TYPER_LAST_SHIFT 4
-#define TYPER_AFF_VAL_MASK 0xffffffff
-#define TYPER_PROC_NUM_MASK 0xffff
-#define TYPER_LAST_MASK 0x1
+#define TYPER_AFF_VAL_MASK U(0xffffffff)
+#define TYPER_PROC_NUM_MASK U(0xffff)
+#define TYPER_LAST_MASK U(0x1)
-#define TYPER_LAST_BIT (1 << TYPER_LAST_SHIFT)
+#define TYPER_LAST_BIT BIT_32(TYPER_LAST_SHIFT)
#define NUM_OF_REDIST_REGS 30
@@ -137,103 +137,120 @@
* GICv3 CPU interface registers & constants
******************************************************************************/
/* ICC_SRE bit definitions*/
-#define ICC_SRE_EN_BIT (1 << 3)
-#define ICC_SRE_DIB_BIT (1 << 2)
-#define ICC_SRE_DFB_BIT (1 << 1)
-#define ICC_SRE_SRE_BIT (1 << 0)
+#define ICC_SRE_EN_BIT BIT_32(3)
+#define ICC_SRE_DIB_BIT BIT_32(2)
+#define ICC_SRE_DFB_BIT BIT_32(1)
+#define ICC_SRE_SRE_BIT BIT_32(0)
/* ICC_IGRPEN1_EL3 bit definitions */
#define IGRPEN1_EL3_ENABLE_G1NS_SHIFT 0
#define IGRPEN1_EL3_ENABLE_G1S_SHIFT 1
-#define IGRPEN1_EL3_ENABLE_G1NS_BIT (1 << IGRPEN1_EL3_ENABLE_G1NS_SHIFT)
-#define IGRPEN1_EL3_ENABLE_G1S_BIT (1 << IGRPEN1_EL3_ENABLE_G1S_SHIFT)
+#define IGRPEN1_EL3_ENABLE_G1NS_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1NS_SHIFT)
+#define IGRPEN1_EL3_ENABLE_G1S_BIT BIT_32(IGRPEN1_EL3_ENABLE_G1S_SHIFT)
/* ICC_IGRPEN0_EL1 bit definitions */
#define IGRPEN1_EL1_ENABLE_G0_SHIFT 0
-#define IGRPEN1_EL1_ENABLE_G0_BIT (1 << IGRPEN1_EL1_ENABLE_G0_SHIFT)
+#define IGRPEN1_EL1_ENABLE_G0_BIT BIT_32(IGRPEN1_EL1_ENABLE_G0_SHIFT)
/* ICC_HPPIR0_EL1 bit definitions */
#define HPPIR0_EL1_INTID_SHIFT 0
-#define HPPIR0_EL1_INTID_MASK 0xffffff
+#define HPPIR0_EL1_INTID_MASK U(0xffffff)
/* ICC_HPPIR1_EL1 bit definitions */
#define HPPIR1_EL1_INTID_SHIFT 0
-#define HPPIR1_EL1_INTID_MASK 0xffffff
+#define HPPIR1_EL1_INTID_MASK U(0xffffff)
/* ICC_IAR0_EL1 bit definitions */
#define IAR0_EL1_INTID_SHIFT 0
-#define IAR0_EL1_INTID_MASK 0xffffff
+#define IAR0_EL1_INTID_MASK U(0xffffff)
/* ICC_IAR1_EL1 bit definitions */
#define IAR1_EL1_INTID_SHIFT 0
-#define IAR1_EL1_INTID_MASK 0xffffff
+#define IAR1_EL1_INTID_MASK U(0xffffff)
/* ICC SGI macros */
-#define SGIR_TGT_MASK 0xffff
+#define SGIR_TGT_MASK ULL(0xffff)
#define SGIR_AFF1_SHIFT 16
#define SGIR_INTID_SHIFT 24
-#define SGIR_INTID_MASK 0xf
+#define SGIR_INTID_MASK ULL(0xf)
#define SGIR_AFF2_SHIFT 32
#define SGIR_IRM_SHIFT 40
-#define SGIR_IRM_MASK 0x1
+#define SGIR_IRM_MASK ULL(0x1)
#define SGIR_AFF3_SHIFT 48
-#define SGIR_AFF_MASK 0xf
+#define SGIR_AFF_MASK ULL(0xf)
-#define SGIR_IRM_TO_AFF 0
+#define SGIR_IRM_TO_AFF U(0)
-#define GICV3_SGIR_VALUE(aff3, aff2, aff1, intid, irm, tgt) \
- ((((uint64_t) (aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \
- (((uint64_t) (irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \
- (((uint64_t) (aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \
- (((intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \
- (((aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
- ((tgt) & SGIR_TGT_MASK))
+#define GICV3_SGIR_VALUE(_aff3, _aff2, _aff1, _intid, _irm, _tgt) \
+ ((((uint64_t) (_aff3) & SGIR_AFF_MASK) << SGIR_AFF3_SHIFT) | \
+ (((uint64_t) (_irm) & SGIR_IRM_MASK) << SGIR_IRM_SHIFT) | \
+ (((uint64_t) (_aff2) & SGIR_AFF_MASK) << SGIR_AFF2_SHIFT) | \
+ (((_intid) & SGIR_INTID_MASK) << SGIR_INTID_SHIFT) | \
+ (((_aff1) & SGIR_AFF_MASK) << SGIR_AFF1_SHIFT) | \
+ ((_tgt) & SGIR_TGT_MASK))
/*****************************************************************************
* GICv3 ITS registers and constants
*****************************************************************************/
-#define GITS_CTLR 0x0
-#define GITS_IIDR 0x4
-#define GITS_TYPER 0x8
-#define GITS_CBASER 0x80
-#define GITS_CWRITER 0x88
-#define GITS_CREADR 0x90
-#define GITS_BASER 0x100
+#define GITS_CTLR U(0x0)
+#define GITS_IIDR U(0x4)
+#define GITS_TYPER U(0x8)
+#define GITS_CBASER U(0x80)
+#define GITS_CWRITER U(0x88)
+#define GITS_CREADR U(0x90)
+#define GITS_BASER U(0x100)
/* GITS_CTLR bit definitions */
-#define GITS_CTLR_ENABLED_BIT 1
+#define GITS_CTLR_ENABLED_BIT BIT_32(0)
#define GITS_CTLR_QUIESCENT_SHIFT 31
-#define GITS_CTLR_QUIESCENT_BIT (1U << GITS_CTLR_QUIESCENT_SHIFT)
+#define GITS_CTLR_QUIESCENT_BIT BIT_32(GITS_CTLR_QUIESCENT_SHIFT)
#ifndef __ASSEMBLY__
+#include <arch_helpers.h>
#include <gic_common.h>
#include <interrupt_props.h>
+#include <stdbool.h>
#include <stdint.h>
-#include <types.h>
#include <utils_def.h>
-#define gicv3_is_intr_id_special_identifier(id) \
- (((id) >= PENDING_G1S_INTID) && ((id) <= GIC_SPURIOUS_INTERRUPT))
+static inline bool gicv3_is_intr_id_special_identifier(unsigned int id)
+{
+ return (id >= PENDING_G1S_INTID) && (id <= GIC_SPURIOUS_INTERRUPT);
+}
/*******************************************************************************
* Helper GICv3 macros for SEL1
******************************************************************************/
-#define gicv3_acknowledge_interrupt_sel1() read_icc_iar1_el1() &\
- IAR1_EL1_INTID_MASK
-#define gicv3_get_pending_interrupt_id_sel1() read_icc_hppir1_el1() &\
- HPPIR1_EL1_INTID_MASK
-#define gicv3_end_of_interrupt_sel1(id) write_icc_eoir1_el1(id)
+static inline uint32_t gicv3_acknowledge_interrupt_sel1(void)
+{
+ return (uint32_t)read_icc_iar1_el1() & IAR1_EL1_INTID_MASK;
+}
+static inline uint32_t gicv3_get_pending_interrupt_id_sel1(void)
+{
+ return (uint32_t)read_icc_hppir1_el1() & HPPIR1_EL1_INTID_MASK;
+}
+
+static inline void gicv3_end_of_interrupt_sel1(unsigned int id)
+{
+ write_icc_eoir1_el1(id);
+}
/*******************************************************************************
* Helper GICv3 macros for EL3
******************************************************************************/
-#define gicv3_acknowledge_interrupt() read_icc_iar0_el1() &\
- IAR0_EL1_INTID_MASK
-#define gicv3_end_of_interrupt(id) write_icc_eoir0_el1(id)
+static inline uint32_t gicv3_acknowledge_interrupt(void)
+{
+ return (uint32_t)read_icc_iar0_el1() & IAR0_EL1_INTID_MASK;
+}
+
+static inline void gicv3_end_of_interrupt(unsigned int id)
+{
+ return write_icc_eoir0_el1(id);
+}
/*
* This macro returns the total number of GICD registers corresponding to
@@ -246,7 +263,7 @@
DIV_ROUND_UP_2EVAL(TOTAL_PCPU_INTR_NUM, (1 << reg_name ## _SHIFT))
/* Interrupt ID mask for HPPIR, AHPPIR, IAR and AIAR CPU Interface registers */
-#define INT_ID_MASK 0xffffff
+#define INT_ID_MASK U(0xffffff)
/*******************************************************************************
* This structure describes some of the implementation defined attributes of the
@@ -403,7 +420,7 @@ void gicv3_set_interrupt_priority(unsigned int id, unsigned int proc_num,
unsigned int priority);
void gicv3_set_interrupt_type(unsigned int id, unsigned int proc_num,
unsigned int type);
-void gicv3_raise_secure_g0_sgi(int sgi_num, u_register_t target);
+void gicv3_raise_secure_g0_sgi(unsigned int sgi_num, u_register_t target);
void gicv3_set_spi_routing(unsigned int id, unsigned int irm,
u_register_t mpidr);
void gicv3_set_interrupt_pending(unsigned int id, unsigned int proc_num);
diff --git a/include/drivers/arm/pl011.h b/include/drivers/arm/pl011.h
index 06d754353..137764d3e 100644
--- a/include/drivers/arm/pl011.h
+++ b/include/drivers/arm/pl011.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -85,7 +85,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct {
console_t console;
diff --git a/include/drivers/arm/smmu_v3.h b/include/drivers/arm/smmu_v3.h
index b7efde462..e3912e31d 100644
--- a/include/drivers/arm/smmu_v3.h
+++ b/include/drivers/arm/smmu_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,18 +7,19 @@
#ifndef __SMMU_V3_H__
#define __SMMU_V3_H__
+#include <utils_def.h>
#include <stdint.h>
/* SMMUv3 register offsets from device base */
-#define SMMU_S_IDR1 0x8004
-#define SMMU_S_INIT 0x803c
+#define SMMU_S_IDR1 U(0x8004)
+#define SMMU_S_INIT U(0x803c)
/* SMMU_S_IDR1 register fields */
#define SMMU_S_IDR1_SECURE_IMPL_SHIFT 31
-#define SMMU_S_IDR1_SECURE_IMPL_MASK 0x1
+#define SMMU_S_IDR1_SECURE_IMPL_MASK U(0x1)
/* SMMU_S_INIT register fields */
-#define SMMU_S_INIT_INV_ALL_MASK 0x1
+#define SMMU_S_INIT_INV_ALL_MASK U(0x1)
int smmuv3_init(uintptr_t smmu_base);
diff --git a/include/drivers/arm/sp805.h b/include/drivers/arm/sp805.h
index f00bcbac2..e7714a393 100644
--- a/include/drivers/arm/sp805.h
+++ b/include/drivers/arm/sp805.h
@@ -1,23 +1,25 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SP805_H__
-#define __SP805_H__
+#ifndef SP805_H
+#define SP805_H
+
+#include <utils_def.h>
/* SP805 register offset */
-#define SP805_WDOG_LOAD_OFF 0x000
-#define SP805_WDOG_CTR_OFF 0x008
-#define SP805_WDOG_LOCK_OFF 0xc00
+#define SP805_WDOG_LOAD_OFF UL(0x000)
+#define SP805_WDOG_CTR_OFF UL(0x008)
+#define SP805_WDOG_LOCK_OFF UL(0xc00)
/* Magic word to unlock the wd registers */
-#define WDOG_UNLOCK_KEY 0x1ACCE551
+#define WDOG_UNLOCK_KEY U(0x1ACCE551)
/* Register field definitions */
-#define SP805_CTR_RESEN (1 << 1)
-#define SP805_CTR_INTEN (1 << 0)
+#define SP805_CTR_RESEN (U(1) << 1)
+#define SP805_CTR_INTEN (U(1) << 0)
#ifndef __ASSEMBLY__
@@ -25,10 +27,10 @@
/* Public high level API */
-void sp805_start(uintptr_t base, unsigned long ticks);
+void sp805_start(uintptr_t base, unsigned int ticks);
void sp805_stop(uintptr_t base);
-void sp805_refresh(uintptr_t base, unsigned long ticks);
+void sp805_refresh(uintptr_t base, unsigned int ticks);
#endif /* __ASSEMBLY__ */
-#endif /* __SP805_H__ */
+#endif /* SP805_H */
diff --git a/include/drivers/cadence/cdns_uart.h b/include/drivers/cadence/cdns_uart.h
index 7ab6df047..51de8e3d5 100644
--- a/include/drivers/cadence/cdns_uart.h
+++ b/include/drivers/cadence/cdns_uart.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,7 +29,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct {
console_t console;
diff --git a/include/drivers/console.h b/include/drivers/console.h
index 6e7ebbf9c..1f041b97b 100644
--- a/include/drivers/console.h
+++ b/include/drivers/console.h
@@ -30,7 +30,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct console {
struct console *next;
@@ -39,9 +39,9 @@ typedef struct console {
* fields of the struct to 64 bits in AArch64 and 32 bits in AArch32
*/
u_register_t flags;
- int (*putc)(int character, struct console *console);
- int (*getc)(struct console *console);
- int (*flush)(struct console *console);
+ int (*const putc)(int character, struct console *console);
+ int (*const getc)(struct console *console);
+ int (*const flush)(struct console *console);
/* Additional private driver data may follow here. */
} console_t;
#include <console_assertions.h> /* offset macro assertions for console_t */
diff --git a/include/drivers/dw_ufs.h b/include/drivers/dw_ufs.h
index b05c7f547..a9774cf18 100644
--- a/include/drivers/dw_ufs.h
+++ b/include/drivers/dw_ufs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef __DW_UFS_H__
#define __DW_UFS_H__
-#include <sys/types.h>
+#include <stdint.h>
/* Bus Throtting */
#define BUSTHRTL 0xC0
diff --git a/include/drivers/emmc.h b/include/drivers/emmc.h
deleted file mode 100644
index 286c014a9..000000000
--- a/include/drivers/emmc.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __EMMC_H__
-#define __EMMC_H__
-
-#include <stdint.h>
-
-#define EMMC_BLOCK_SIZE 512
-#define EMMC_BLOCK_MASK (EMMC_BLOCK_SIZE - 1)
-#define EMMC_BOOT_CLK_RATE (400 * 1000)
-
-#define EMMC_CMD0 0
-#define EMMC_CMD1 1
-#define EMMC_CMD2 2
-#define EMMC_CMD3 3
-#define EMMC_CMD6 6
-#define EMMC_CMD7 7
-#define EMMC_CMD8 8
-#define EMMC_CMD9 9
-#define EMMC_CMD12 12
-#define EMMC_CMD13 13
-#define EMMC_CMD17 17
-#define EMMC_CMD18 18
-#define EMMC_CMD21 21
-#define EMMC_CMD23 23
-#define EMMC_CMD24 24
-#define EMMC_CMD25 25
-#define EMMC_CMD35 35
-#define EMMC_CMD36 36
-#define EMMC_CMD38 38
-
-#define OCR_POWERUP (1 << 31)
-#define OCR_BYTE_MODE (0 << 29)
-#define OCR_SECTOR_MODE (2 << 29)
-#define OCR_ACCESS_MODE_MASK (3 << 29)
-#define OCR_VDD_MIN_2V7 (0x1ff << 15)
-#define OCR_VDD_MIN_2V0 (0x7f << 8)
-#define OCR_VDD_MIN_1V7 (1 << 7)
-
-#define EMMC_RESPONSE_R1 1
-#define EMMC_RESPONSE_R1B 1
-#define EMMC_RESPONSE_R2 4
-#define EMMC_RESPONSE_R3 1
-#define EMMC_RESPONSE_R4 1
-#define EMMC_RESPONSE_R5 1
-
-#define EMMC_FIX_RCA 6 /* > 1 */
-#define RCA_SHIFT_OFFSET 16
-
-#define CMD_EXTCSD_PARTITION_CONFIG 179
-#define CMD_EXTCSD_BUS_WIDTH 183
-#define CMD_EXTCSD_HS_TIMING 185
-
-#define PART_CFG_BOOT_PARTITION1_ENABLE (1 << 3)
-#define PART_CFG_PARTITION1_ACCESS (1 << 0)
-
-/* values in EXT CSD register */
-#define EMMC_BUS_WIDTH_1 0
-#define EMMC_BUS_WIDTH_4 1
-#define EMMC_BUS_WIDTH_8 2
-#define EMMC_BUS_WIDTH_DDR_4 5
-#define EMMC_BUS_WIDTH_DDR_8 6
-#define EMMC_BOOT_MODE_BACKWARD (0 << 3)
-#define EMMC_BOOT_MODE_HS_TIMING (1 << 3)
-#define EMMC_BOOT_MODE_DDR (2 << 3)
-
-#define EXTCSD_SET_CMD (0 << 24)
-#define EXTCSD_SET_BITS (1 << 24)
-#define EXTCSD_CLR_BITS (2 << 24)
-#define EXTCSD_WRITE_BYTES (3 << 24)
-#define EXTCSD_CMD(x) (((x) & 0xff) << 16)
-#define EXTCSD_VALUE(x) (((x) & 0xff) << 8)
-
-#define STATUS_CURRENT_STATE(x) (((x) & 0xf) << 9)
-#define STATUS_READY_FOR_DATA (1 << 8)
-#define STATUS_SWITCH_ERROR (1 << 7)
-#define EMMC_GET_STATE(x) (((x) >> 9) & 0xf)
-#define EMMC_STATE_IDLE 0
-#define EMMC_STATE_READY 1
-#define EMMC_STATE_IDENT 2
-#define EMMC_STATE_STBY 3
-#define EMMC_STATE_TRAN 4
-#define EMMC_STATE_DATA 5
-#define EMMC_STATE_RCV 6
-#define EMMC_STATE_PRG 7
-#define EMMC_STATE_DIS 8
-#define EMMC_STATE_BTST 9
-#define EMMC_STATE_SLP 10
-
-#define EMMC_FLAG_CMD23 (1 << 0)
-
-typedef struct emmc_cmd {
- unsigned int cmd_idx;
- unsigned int cmd_arg;
- unsigned int resp_type;
- unsigned int resp_data[4];
-} emmc_cmd_t;
-
-typedef struct emmc_ops {
- void (*init)(void);
- int (*send_cmd)(emmc_cmd_t *cmd);
- int (*set_ios)(int clk, int width);
- int (*prepare)(int lba, uintptr_t buf, size_t size);
- int (*read)(int lba, uintptr_t buf, size_t size);
- int (*write)(int lba, const uintptr_t buf, size_t size);
-} emmc_ops_t;
-
-typedef struct emmc_csd {
- unsigned int not_used: 1;
- unsigned int crc: 7;
- unsigned int ecc: 2;
- unsigned int file_format: 2;
- unsigned int tmp_write_protect: 1;
- unsigned int perm_write_protect: 1;
- unsigned int copy: 1;
- unsigned int file_format_grp: 1;
-
- unsigned int reserved_1: 5;
- unsigned int write_bl_partial: 1;
- unsigned int write_bl_len: 4;
- unsigned int r2w_factor: 3;
- unsigned int default_ecc: 2;
- unsigned int wp_grp_enable: 1;
-
- unsigned int wp_grp_size: 5;
- unsigned int erase_grp_mult: 5;
- unsigned int erase_grp_size: 5;
- unsigned int c_size_mult: 3;
- unsigned int vdd_w_curr_max: 3;
- unsigned int vdd_w_curr_min: 3;
- unsigned int vdd_r_curr_max: 3;
- unsigned int vdd_r_curr_min: 3;
- unsigned int c_size_low: 2;
-
- unsigned int c_size_high: 10;
- unsigned int reserved_2: 2;
- unsigned int dsr_imp: 1;
- unsigned int read_blk_misalign: 1;
- unsigned int write_blk_misalign: 1;
- unsigned int read_bl_partial: 1;
- unsigned int read_bl_len: 4;
- unsigned int ccc: 12;
-
- unsigned int tran_speed: 8;
- unsigned int nsac: 8;
- unsigned int taac: 8;
- unsigned int reserved_3: 2;
- unsigned int spec_vers: 4;
- unsigned int csd_structure: 2;
-} emmc_csd_t;
-
-size_t emmc_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t emmc_write_blocks(int lba, const uintptr_t buf, size_t size);
-size_t emmc_erase_blocks(int lba, size_t size);
-size_t emmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
-size_t emmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
-size_t emmc_rpmb_erase_blocks(int lba, size_t size);
-void emmc_init(const emmc_ops_t *ops, int clk, int bus_width,
- unsigned int flags);
-
-#endif /* __EMMC_H__ */
diff --git a/include/drivers/marvell/a8k_i2c.h b/include/drivers/marvell/a8k_i2c.h
new file mode 100644
index 000000000..8a9abe8d4
--- /dev/null
+++ b/include/drivers/marvell/a8k_i2c.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* This driver provides I2C support for Marvell A8K and compatible SoCs */
+
+#ifndef _A8K_I2C_H_
+#define _A8K_I2C_H_
+
+#include <stdint.h>
+
+/*
+ * Initialization, must be called once on start up, may be called
+ * repeatedly to change the speed and slave addresses.
+ */
+void i2c_init(void *i2c_base);
+
+/*
+ * Read/Write interface:
+ * chip: I2C chip address, range 0..127
+ * addr: Memory (register) address within the chip
+ * alen: Number of bytes to use for addr (typically 1, 2 for larger
+ * memories, 0 for register type devices with only one
+ * register)
+ * buffer: Where to read/write the data
+ * len: How many bytes to read/write
+ *
+ * Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(uint8_t chip,
+ unsigned int addr, int alen, uint8_t *buffer, int len);
+
+int i2c_write(uint8_t chip,
+ unsigned int addr, int alen, uint8_t *buffer, int len);
+#endif
diff --git a/include/drivers/marvell/addr_map.h b/include/drivers/marvell/addr_map.h
new file mode 100644
index 000000000..6b957a165
--- /dev/null
+++ b/include/drivers/marvell/addr_map.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Address map types for Marvell address translation unit drivers */
+
+#ifndef _ADDR_MAP_H_
+#define _ADDR_MAP_H_
+
+#include <stdint.h>
+
+struct addr_map_win {
+ uint64_t base_addr;
+ uint64_t win_size;
+ uint32_t target_id;
+};
+
+#endif /* _ADDR_MAP_H_ */
diff --git a/include/drivers/marvell/amb_adec.h b/include/drivers/marvell/amb_adec.h
new file mode 100644
index 000000000..087864a45
--- /dev/null
+++ b/include/drivers/marvell/amb_adec.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* AXI to M-Bridge decoding unit driver for Marvell Armada 8K and 8K+ SoCs */
+
+#ifndef _AMB_ADEC_H_
+#define _AMB_ADEC_H_
+
+#include <stdint.h>
+
+enum amb_attribute_ids {
+ AMB_SPI0_CS0_ID = 0x1E,
+ AMB_SPI0_CS1_ID = 0x5E,
+ AMB_SPI0_CS2_ID = 0x9E,
+ AMB_SPI0_CS3_ID = 0xDE,
+ AMB_SPI1_CS0_ID = 0x1A,
+ AMB_SPI1_CS1_ID = 0x5A,
+ AMB_SPI1_CS2_ID = 0x9A,
+ AMB_SPI1_CS3_ID = 0xDA,
+ AMB_DEV_CS0_ID = 0x3E,
+ AMB_DEV_CS1_ID = 0x3D,
+ AMB_DEV_CS2_ID = 0x3B,
+ AMB_DEV_CS3_ID = 0x37,
+ AMB_BOOT_CS_ID = 0x2f,
+ AMB_BOOT_ROM_ID = 0x1D,
+};
+
+#define AMB_MAX_WIN_ID 7
+
+int init_amb_adec(uintptr_t base);
+
+#endif /* _AMB_ADEC_H_ */
diff --git a/include/drivers/marvell/aro.h b/include/drivers/marvell/aro.h
new file mode 100644
index 000000000..3627a201c
--- /dev/null
+++ b/include/drivers/marvell/aro.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+#ifndef _ARO_H_
+#define _ARO_H_
+
+enum hws_freq {
+ CPU_FREQ_2000,
+ CPU_FREQ_1800,
+ CPU_FREQ_1600,
+ CPU_FREQ_1400,
+ CPU_FREQ_1300,
+ CPU_FREQ_1200,
+ CPU_FREQ_1000,
+ CPU_FREQ_600,
+ CPU_FREQ_800,
+ DDR_FREQ_LAST,
+ DDR_FREQ_SAR
+};
+
+enum cpu_clock_freq_mode {
+ CPU_2000_DDR_1200_RCLK_1200 = 0x0,
+ CPU_2000_DDR_1050_RCLK_1050 = 0x1,
+ CPU_1600_DDR_800_RCLK_800 = 0x4,
+ CPU_1800_DDR_1200_RCLK_1200 = 0x6,
+ CPU_1800_DDR_1050_RCLK_1050 = 0x7,
+ CPU_1600_DDR_900_RCLK_900 = 0x0B,
+ CPU_1600_DDR_1050_RCLK_1050 = 0x0D,
+ CPU_1600_DDR_900_RCLK_900_2 = 0x0E,
+ CPU_1000_DDR_650_RCLK_650 = 0x13,
+ CPU_1300_DDR_800_RCLK_800 = 0x14,
+ CPU_1300_DDR_650_RCLK_650 = 0x17,
+ CPU_1200_DDR_800_RCLK_800 = 0x19,
+ CPU_1400_DDR_800_RCLK_800 = 0x1a,
+ CPU_600_DDR_800_RCLK_800 = 0x1B,
+ CPU_800_DDR_800_RCLK_800 = 0x1C,
+ CPU_1000_DDR_800_RCLK_800 = 0x1D,
+ CPU_DDR_RCLK_INVALID
+};
+
+int init_aro(void);
+
+#endif /* _ARO_H_ */
diff --git a/include/drivers/marvell/cache_llc.h b/include/drivers/marvell/cache_llc.h
new file mode 100644
index 000000000..9e4179397
--- /dev/null
+++ b/include/drivers/marvell/cache_llc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* LLC driver is the Last Level Cache (L3C) driver
+ * for Marvell SoCs in AP806, AP807, and AP810
+ */
+
+#ifndef _CACHE_LLC_H_
+#define _CACHE_LLC_H_
+
+#define LLC_CTRL(ap) (MVEBU_LLC_BASE(ap) + 0x100)
+#define LLC_SYNC(ap) (MVEBU_LLC_BASE(ap) + 0x700)
+#define L2X0_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x77C)
+#define L2X0_CLEAN_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7BC)
+#define L2X0_CLEAN_INV_WAY(ap) (MVEBU_LLC_BASE(ap) + 0x7FC)
+#define LLC_TC0_LOCK(ap) (MVEBU_LLC_BASE(ap) + 0x920)
+
+#define MASTER_LLC_CTRL LLC_CTRL(MVEBU_AP0)
+#define MASTER_L2X0_INV_WAY L2X0_INV_WAY(MVEBU_AP0)
+#define MASTER_LLC_TC0_LOCK LLC_TC0_LOCK(MVEBU_AP0)
+
+#define LLC_CTRL_EN 1
+#define LLC_EXCLUSIVE_EN 0x100
+#define LLC_WAY_MASK 0xFFFFFFFF
+
+#ifndef __ASSEMBLY__
+void llc_cache_sync(int ap_index);
+void llc_flush_all(int ap_index);
+void llc_clean_all(int ap_index);
+void llc_inv_all(int ap_index);
+void llc_disable(int ap_index);
+void llc_enable(int ap_index, int excl_mode);
+int llc_is_exclusive(int ap_index);
+void llc_runtime_enable(int ap_index);
+#endif
+
+#endif /* _CACHE_LLC_H_ */
+
diff --git a/include/drivers/marvell/ccu.h b/include/drivers/marvell/ccu.h
new file mode 100644
index 000000000..ff30a76a9
--- /dev/null
+++ b/include/drivers/marvell/ccu.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* CCU unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+
+#ifndef _CCU_H_
+#define _CCU_H_
+
+#ifndef __ASSEMBLY__
+#include <addr_map.h>
+#endif
+
+/* CCU registers definitions */
+#define CCU_WIN_CR_OFFSET(ap, win) (MVEBU_CCU_BASE(ap) + 0x0 + \
+ (0x10 * win))
+#define CCU_TARGET_ID_OFFSET (8)
+#define CCU_TARGET_ID_MASK (0x7F)
+
+#define CCU_WIN_SCR_OFFSET(ap, win) (MVEBU_CCU_BASE(ap) + 0x4 + \
+ (0x10 * win))
+#define CCU_WIN_ENA_WRITE_SECURE (0x1)
+#define CCU_WIN_ENA_READ_SECURE (0x2)
+
+#define CCU_WIN_ALR_OFFSET(ap, win) (MVEBU_CCU_BASE(ap) + 0x8 + \
+ (0x10 * win))
+#define CCU_WIN_AHR_OFFSET(ap, win) (MVEBU_CCU_BASE(ap) + 0xC + \
+ (0x10 * win))
+
+#define CCU_WIN_GCR_OFFSET(ap) (MVEBU_CCU_BASE(ap) + 0xD0)
+#define CCU_GCR_TARGET_OFFSET (8)
+#define CCU_GCR_TARGET_MASK (0xFF)
+
+#define CCU_SRAM_WIN_CR CCU_WIN_CR_OFFSET(MVEBU_AP0, 1)
+
+#ifndef __ASSEMBLY__
+int init_ccu(int);
+void ccu_win_check(struct addr_map_win *win);
+void ccu_enable_win(int ap_index, struct addr_map_win *win, uint32_t win_id);
+void ccu_temp_win_insert(int ap_index, struct addr_map_win *win, int size);
+void ccu_temp_win_remove(int ap_index, struct addr_map_win *win, int size);
+void ccu_dram_win_config(int ap_index, struct addr_map_win *win);
+void ccu_dram_target_set(int ap_index, uint32_t target);
+void ccu_save_win_all(int ap_id);
+void ccu_restore_win_all(int ap_id);
+#endif
+
+#endif /* _CCU_H_ */
diff --git a/include/drivers/marvell/gwin.h b/include/drivers/marvell/gwin.h
new file mode 100644
index 000000000..5dc9f244e
--- /dev/null
+++ b/include/drivers/marvell/gwin.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* GWIN unit device driver for Marvell AP810 SoC */
+
+#ifndef _GWIN_H_
+#define _GWIN_H_
+
+#include <addr_map.h>
+
+int init_gwin(int ap_index);
+void gwin_temp_win_insert(int ap_index, struct addr_map_win *win, int size);
+void gwin_temp_win_remove(int ap_index, struct addr_map_win *win, int size);
+
+#endif /* _GWIN_H_ */
diff --git a/include/drivers/marvell/i2c.h b/include/drivers/marvell/i2c.h
new file mode 100644
index 000000000..bd1438526
--- /dev/null
+++ b/include/drivers/marvell/i2c.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef _I2C_H_
+#define _I2C_H_
+
+
+void i2c_init(void);
+
+int i2c_read(uint8_t chip,
+ unsigned int addr, int alen, uint8_t *buffer, int len);
+
+int i2c_write(uint8_t chip,
+ unsigned int addr, int alen, uint8_t *buffer, int len);
+#endif
diff --git a/include/drivers/marvell/io_win.h b/include/drivers/marvell/io_win.h
new file mode 100644
index 000000000..4102a11a5
--- /dev/null
+++ b/include/drivers/marvell/io_win.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* IO Window unit device driver for Marvell AP807, AP807 and AP810 SoCs */
+
+#ifndef _IO_WIN_H_
+#define _IO_WIN_H_
+
+#include <addr_map.h>
+
+int init_io_win(int ap_index);
+void iow_temp_win_insert(int ap_index, struct addr_map_win *win, int size);
+void iow_temp_win_remove(int ap_index, struct addr_map_win *win, int size);
+void iow_save_win_all(int ap_id);
+void iow_restore_win_all(int ap_id);
+
+#endif /* _IO_WIN_H_ */
diff --git a/include/drivers/marvell/iob.h b/include/drivers/marvell/iob.h
new file mode 100644
index 000000000..9848c0ab3
--- /dev/null
+++ b/include/drivers/marvell/iob.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* IOW unit device driver for Marvell CP110 and CP115 SoCs */
+
+#ifndef _IOB_H_
+#define _IOB_H_
+
+#include <addr_map.h>
+
+enum target_ids_iob {
+ INTERNAL_TID = 0x0,
+ MCI0_TID = 0x1,
+ PEX1_TID = 0x2,
+ PEX2_TID = 0x3,
+ PEX0_TID = 0x4,
+ NAND_TID = 0x5,
+ RUNIT_TID = 0x6,
+ MCI1_TID = 0x7,
+ IOB_MAX_TID
+};
+
+int init_iob(uintptr_t base);
+void iob_cfg_space_update(int ap_idx, int cp_idx,
+ uintptr_t base, uintptr_t new_base);
+
+#endif /* _IOB_H_ */
diff --git a/include/drivers/marvell/mci.h b/include/drivers/marvell/mci.h
new file mode 100644
index 000000000..789b3b961
--- /dev/null
+++ b/include/drivers/marvell/mci.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* MCI bus driver for Marvell ARMADA 8K and 8K+ SoCs */
+
+#ifndef _MCI_H_
+#define _MCI_H_
+
+int mci_initialize(int mci_index);
+void mci_turn_link_down(void);
+void mci_turn_link_on(void);
+int mci_get_link_status(void);
+
+#endif /* _MCI_H_ */
diff --git a/include/drivers/marvell/mochi/ap_setup.h b/include/drivers/marvell/mochi/ap_setup.h
new file mode 100644
index 000000000..41f2bac35
--- /dev/null
+++ b/include/drivers/marvell/mochi/ap_setup.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* AP8xx Marvell SoC driver */
+
+#ifndef __AP_SETUP_H__
+#define __AP_SETUP_H__
+
+void ap_init(void);
+void ap_ble_init(void);
+int ap_get_count(void);
+
+#endif /* __AP_SETUP_H__ */
diff --git a/include/drivers/marvell/mochi/cp110_setup.h b/include/drivers/marvell/mochi/cp110_setup.h
new file mode 100644
index 000000000..1c88980ae
--- /dev/null
+++ b/include/drivers/marvell/mochi/cp110_setup.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* CP110 Marvell SoC driver */
+
+#ifndef __CP110_SETUP_H__
+#define __CP110_SETUP_H__
+
+#include <mmio.h>
+#include <mvebu_def.h>
+
+#define MVEBU_DEVICE_ID_REG (MVEBU_CP_DFX_OFFSET + 0x40)
+#define MVEBU_DEVICE_ID_OFFSET (0)
+#define MVEBU_DEVICE_ID_MASK (0xffff << MVEBU_DEVICE_ID_OFFSET)
+#define MVEBU_DEVICE_REV_OFFSET (16)
+#define MVEBU_DEVICE_REV_MASK (0xf << MVEBU_DEVICE_REV_OFFSET)
+#define MVEBU_70X0_DEV_ID (0x7040)
+#define MVEBU_70X0_CP115_DEV_ID (0x7045)
+#define MVEBU_80X0_DEV_ID (0x8040)
+#define MVEBU_80X0_CP115_DEV_ID (0x8045)
+#define MVEBU_CP110_SA_DEV_ID (0x110)
+#define MVEBU_CP110_REF_ID_A1 1
+#define MVEBU_CP110_REF_ID_A2 2
+#define MAX_STREAM_ID_PER_CP (0x10)
+#define STREAM_ID_BASE (0x40)
+
+static inline uint32_t cp110_device_id_get(uintptr_t base)
+{
+ /* Returns:
+ * - MVEBU_70X0_DEV_ID for A70X0 family
+ * - MVEBU_80X0_DEV_ID for A80X0 family
+ * - MVEBU_CP110_SA_DEV_ID for CP that connected stand alone
+ */
+ return (mmio_read_32(base + MVEBU_DEVICE_ID_REG) >>
+ MVEBU_DEVICE_ID_OFFSET) &
+ MVEBU_DEVICE_ID_MASK;
+}
+
+static inline uint32_t cp110_rev_id_get(uintptr_t base)
+{
+ return (mmio_read_32(base + MVEBU_DEVICE_ID_REG) &
+ MVEBU_DEVICE_REV_MASK) >>
+ MVEBU_DEVICE_REV_OFFSET;
+}
+
+void cp110_init(uintptr_t cp110_base, uint32_t stream_id);
+void cp110_ble_init(uintptr_t cp110_base);
+
+#endif /* __CP110_SETUP_H__ */
diff --git a/include/drivers/marvell/thermal.h b/include/drivers/marvell/thermal.h
new file mode 100644
index 000000000..191f97bab
--- /dev/null
+++ b/include/drivers/marvell/thermal.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+/* Driver for thermal unit located in Marvell ARMADA 8K and compatible SoCs */
+
+#ifndef _THERMAL_H
+#define _THERMAL_H
+
+struct tsen_config {
+ /* thermal temperature parameters */
+ int tsen_offset;
+ int tsen_gain;
+ int tsen_divisor;
+ /* thermal data */
+ int tsen_ready;
+ void *regs_base;
+ /* thermal functionality */
+ int (*ptr_tsen_probe)(struct tsen_config *cfg);
+ int (*ptr_tsen_read)(struct tsen_config *cfg, int *temp);
+};
+
+/* Thermal driver APIs */
+int marvell_thermal_init(struct tsen_config *tsen_cfg);
+int marvell_thermal_read(struct tsen_config *tsen_cfg, int *temp);
+struct tsen_config *marvell_thermal_config_get(void);
+
+#endif /* _THERMAL_H */
diff --git a/include/drivers/mmc.h b/include/drivers/mmc.h
index 65f4bbdc3..0a513bd64 100644
--- a/include/drivers/mmc.h
+++ b/include/drivers/mmc.h
@@ -208,13 +208,12 @@ struct mmc_device_info {
enum mmc_device_type mmc_dev_type; /* Type of MMC */
};
-size_t mmc_read_blocks(unsigned int lba, uintptr_t buf, size_t size);
-size_t mmc_write_blocks(unsigned int lba, const uintptr_t buf, size_t size);
-size_t mmc_erase_blocks(unsigned int lba, size_t size);
-size_t mmc_rpmb_read_blocks(unsigned int lba, uintptr_t buf, size_t size);
-size_t mmc_rpmb_write_blocks(unsigned int lba, const uintptr_t buf,
- size_t size);
-size_t mmc_rpmb_erase_blocks(unsigned int lba, size_t size);
+size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t mmc_write_blocks(int lba, const uintptr_t buf, size_t size);
+size_t mmc_erase_blocks(int lba, size_t size);
+size_t mmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
+size_t mmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
+size_t mmc_rpmb_erase_blocks(int lba, size_t size);
int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
unsigned int width, unsigned int flags,
struct mmc_device_info *device_info);
diff --git a/include/drivers/partition/partition.h b/include/drivers/partition/partition.h
index 4951f8cfd..047c7ddaa 100644
--- a/include/drivers/partition/partition.h
+++ b/include/drivers/partition/partition.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,7 @@
#define __PARTITION_H__
#include <cassert.h>
-#include <types.h>
+#include <stdint.h>
#if !PLAT_PARTITION_MAX_ENTRIES
# define PLAT_PARTITION_MAX_ENTRIES 128
diff --git a/include/drivers/st/stm32_gpio.h b/include/drivers/st/stm32_gpio.h
new file mode 100644
index 000000000..7a5ccd376
--- /dev/null
+++ b/include/drivers/st/stm32_gpio.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_GPIO_H__
+#define __PLAT_GPIO_H__
+
+#include <utils_def.h>
+
+#define STM32_GPIOA_BANK U(0x50002000)
+#define STM32_GPIOZ_BANK U(0x54004000)
+#define STM32_GPIO_BANK_OFFSET U(0x1000)
+
+#define GPIO_MODE_OFFSET U(0x00)
+#define GPIO_TYPE_OFFSET U(0x04)
+#define GPIO_SPEED_OFFSET U(0x08)
+#define GPIO_PUPD_OFFSET U(0x0C)
+#define GPIO_BSRR_OFFSET U(0x18)
+#define GPIO_AFRL_OFFSET U(0x20)
+#define GPIO_AFRH_OFFSET U(0x24)
+
+#define GPIO_ALT_LOWER_LIMIT U(0x08)
+
+#define GPIO_BANK_A U(0x00)
+#define GPIO_BANK_B U(0x01)
+#define GPIO_BANK_C U(0x02)
+#define GPIO_BANK_D U(0x03)
+#define GPIO_BANK_E U(0x04)
+#define GPIO_BANK_F U(0x05)
+#define GPIO_BANK_G U(0x06)
+#define GPIO_BANK_H U(0x07)
+#define GPIO_BANK_I U(0x08)
+#define GPIO_BANK_J U(0x09)
+#define GPIO_BANK_K U(0x0A)
+#define GPIO_BANK_Z U(0x19)
+
+#define GPIO_PIN_0 U(0x00)
+#define GPIO_PIN_1 U(0x01)
+#define GPIO_PIN_2 U(0x02)
+#define GPIO_PIN_3 U(0x03)
+#define GPIO_PIN_4 U(0x04)
+#define GPIO_PIN_5 U(0x05)
+#define GPIO_PIN_6 U(0x06)
+#define GPIO_PIN_7 U(0x07)
+#define GPIO_PIN_8 U(0x08)
+#define GPIO_PIN_9 U(0x09)
+#define GPIO_PIN_10 U(0x0A)
+#define GPIO_PIN_11 U(0x0B)
+#define GPIO_PIN_12 U(0x0C)
+#define GPIO_PIN_13 U(0x0D)
+#define GPIO_PIN_14 U(0x0E)
+#define GPIO_PIN_15 U(0x0F)
+#define GPIO_PIN_MAX GPIO_PIN_15
+
+#define GPIO_ALTERNATE_0 0x00
+#define GPIO_ALTERNATE_1 0x01
+#define GPIO_ALTERNATE_2 0x02
+#define GPIO_ALTERNATE_3 0x03
+#define GPIO_ALTERNATE_4 0x04
+#define GPIO_ALTERNATE_5 0x05
+#define GPIO_ALTERNATE_6 0x06
+#define GPIO_ALTERNATE_7 0x07
+#define GPIO_ALTERNATE_8 0x08
+#define GPIO_ALTERNATE_9 0x09
+#define GPIO_ALTERNATE_10 0x0A
+#define GPIO_ALTERNATE_11 0x0B
+#define GPIO_ALTERNATE_12 0x0C
+#define GPIO_ALTERNATE_13 0x0D
+#define GPIO_ALTERNATE_14 0x0E
+#define GPIO_ALTERNATE_15 0x0F
+#define GPIO_ALTERNATE_MASK U(0x0F)
+
+#define GPIO_MODE_INPUT 0x00
+#define GPIO_MODE_OUTPUT 0x01
+#define GPIO_MODE_ALTERNATE 0x02
+#define GPIO_MODE_ANALOG 0x03
+#define GPIO_MODE_MASK U(0x03)
+
+#define GPIO_OPEN_DRAIN U(0x10)
+
+#define GPIO_SPEED_LOW 0x00
+#define GPIO_SPEED_MEDIUM 0x01
+#define GPIO_SPEED_FAST 0x02
+#define GPIO_SPEED_HIGH 0x03
+#define GPIO_SPEED_MASK U(0x03)
+
+#define GPIO_NO_PULL 0x00
+#define GPIO_PULL_UP 0x01
+#define GPIO_PULL_DOWN 0x02
+#define GPIO_PULL_MASK U(0x03)
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+void set_gpio(uint32_t bank, uint32_t pin, uint32_t mode, uint32_t speed,
+ uint32_t pull, uint32_t alternate);
+#endif /*__ASSEMBLY__*/
+
+#endif /*__PLAT_GPIO_H__*/
diff --git a/include/drivers/st/stm32_i2c.h b/include/drivers/st/stm32_i2c.h
new file mode 100644
index 000000000..29b9d3441
--- /dev/null
+++ b/include/drivers/st/stm32_i2c.h
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_I2C_H
+#define __STM32MP1_I2C_H
+
+#include <stdint.h>
+#include <utils_def.h>
+
+/* Bit definition for I2C_CR1 register */
+#define I2C_CR1_PE BIT(0)
+#define I2C_CR1_TXIE BIT(1)
+#define I2C_CR1_RXIE BIT(2)
+#define I2C_CR1_ADDRIE BIT(3)
+#define I2C_CR1_NACKIE BIT(4)
+#define I2C_CR1_STOPIE BIT(5)
+#define I2C_CR1_TCIE BIT(6)
+#define I2C_CR1_ERRIE BIT(7)
+#define I2C_CR1_DNF GENMASK(11, 8)
+#define I2C_CR1_ANFOFF BIT(12)
+#define I2C_CR1_SWRST BIT(13)
+#define I2C_CR1_TXDMAEN BIT(14)
+#define I2C_CR1_RXDMAEN BIT(15)
+#define I2C_CR1_SBC BIT(16)
+#define I2C_CR1_NOSTRETCH BIT(17)
+#define I2C_CR1_WUPEN BIT(18)
+#define I2C_CR1_GCEN BIT(19)
+#define I2C_CR1_SMBHEN BIT(22)
+#define I2C_CR1_SMBDEN BIT(21)
+#define I2C_CR1_ALERTEN BIT(22)
+#define I2C_CR1_PECEN BIT(23)
+
+/* Bit definition for I2C_CR2 register */
+#define I2C_CR2_SADD GENMASK(9, 0)
+#define I2C_CR2_RD_WRN BIT(10)
+#define I2C_CR2_RD_WRN_OFFSET 10U
+#define I2C_CR2_ADD10 BIT(11)
+#define I2C_CR2_HEAD10R BIT(12)
+#define I2C_CR2_START BIT(13)
+#define I2C_CR2_STOP BIT(14)
+#define I2C_CR2_NACK BIT(15)
+#define I2C_CR2_NBYTES GENMASK(23, 16)
+#define I2C_CR2_NBYTES_OFFSET 16U
+#define I2C_CR2_RELOAD BIT(24)
+#define I2C_CR2_AUTOEND BIT(25)
+#define I2C_CR2_PECBYTE BIT(26)
+
+/* Bit definition for I2C_OAR1 register */
+#define I2C_OAR1_OA1 GENMASK(9, 0)
+#define I2C_OAR1_OA1MODE BIT(10)
+#define I2C_OAR1_OA1EN BIT(15)
+
+/* Bit definition for I2C_OAR2 register */
+#define I2C_OAR2_OA2 GENMASK(7, 1)
+#define I2C_OAR2_OA2MSK GENMASK(10, 8)
+#define I2C_OAR2_OA2NOMASK 0
+#define I2C_OAR2_OA2MASK01 BIT(8)
+#define I2C_OAR2_OA2MASK02 BIT(9)
+#define I2C_OAR2_OA2MASK03 GENMASK(9, 8)
+#define I2C_OAR2_OA2MASK04 BIT(10)
+#define I2C_OAR2_OA2MASK05 (BIT(8) | BIT(10))
+#define I2C_OAR2_OA2MASK06 (BIT(9) | BIT(10))
+#define I2C_OAR2_OA2MASK07 GENMASK(10, 8)
+#define I2C_OAR2_OA2EN BIT(15)
+
+/* Bit definition for I2C_TIMINGR register */
+#define I2C_TIMINGR_SCLL GENMASK(7, 0)
+#define I2C_TIMINGR_SCLH GENMASK(15, 8)
+#define I2C_TIMINGR_SDADEL GENMASK(19, 16)
+#define I2C_TIMINGR_SCLDEL GENMASK(23, 20)
+#define I2C_TIMINGR_PRESC GENMASK(31, 28)
+
+/* Bit definition for I2C_TIMEOUTR register */
+#define I2C_TIMEOUTR_TIMEOUTA GENMASK(11, 0)
+#define I2C_TIMEOUTR_TIDLE BIT(12)
+#define I2C_TIMEOUTR_TIMOUTEN BIT(15)
+#define I2C_TIMEOUTR_TIMEOUTB GENMASK(27, 16)
+#define I2C_TIMEOUTR_TEXTEN BIT(31)
+
+/* Bit definition for I2C_ISR register */
+#define I2C_ISR_TXE BIT(0)
+#define I2C_ISR_TXIS BIT(1)
+#define I2C_ISR_RXNE BIT(2)
+#define I2C_ISR_ADDR BIT(3)
+#define I2C_ISR_NACKF BIT(4)
+#define I2C_ISR_STOPF BIT(5)
+#define I2C_ISR_TC BIT(6)
+#define I2C_ISR_TCR BIT(7)
+#define I2C_ISR_BERR BIT(8)
+#define I2C_ISR_ARLO BIT(9)
+#define I2C_ISR_OVR BIT(10)
+#define I2C_ISR_PECERR BIT(11)
+#define I2C_ISR_TIMEOUT BIT(12)
+#define I2C_ISR_ALERT BIT(13)
+#define I2C_ISR_BUSY BIT(15)
+#define I2C_ISR_DIR BIT(16)
+#define I2C_ISR_ADDCODE GENMASK(23, 17)
+
+/* Bit definition for I2C_ICR register */
+#define I2C_ICR_ADDRCF BIT(3)
+#define I2C_ICR_NACKCF BIT(4)
+#define I2C_ICR_STOPCF BIT(5)
+#define I2C_ICR_BERRCF BIT(8)
+#define I2C_ICR_ARLOCF BIT(9)
+#define I2C_ICR_OVRCF BIT(10)
+#define I2C_ICR_PECCF BIT(11)
+#define I2C_ICR_TIMOUTCF BIT(12)
+#define I2C_ICR_ALERTCF BIT(13)
+
+struct stm32_i2c_init_s {
+ uint32_t timing; /* Specifies the I2C_TIMINGR_register value
+ * This parameter is calculated by referring
+ * to I2C initialization section in Reference
+ * manual.
+ */
+
+ uint32_t own_address1; /* Specifies the first device own address.
+ * This parameter can be a 7-bit or 10-bit
+ * address.
+ */
+
+ uint32_t addressing_mode; /* Specifies if 7-bit or 10-bit addressing
+ * mode is selected.
+ * This parameter can be a value of @ref
+ * I2C_ADDRESSING_MODE.
+ */
+
+ uint32_t dual_address_mode; /* Specifies if dual addressing mode is
+ * selected.
+ * This parameter can be a value of @ref
+ * I2C_DUAL_ADDRESSING_MODE.
+ */
+
+ uint32_t own_address2; /* Specifies the second device own address
+ * if dual addressing mode is selected.
+ * This parameter can be a 7-bit address.
+ */
+
+ uint32_t own_address2_masks; /* Specifies the acknowledge mask address
+ * second device own address if dual
+ * addressing mode is selected.
+ * This parameter can be a value of @ref
+ * I2C_OWN_ADDRESS2_MASKS.
+ */
+
+ uint32_t general_call_mode; /* Specifies if general call mode is
+ * selected.
+ * This parameter can be a value of @ref
+ * I2C_GENERAL_CALL_ADDRESSING_MODE.
+ */
+
+ uint32_t no_stretch_mode; /* Specifies if nostretch mode is
+ * selected.
+ * This parameter can be a value of @ref
+ * I2C_NOSTRETCH_MODE.
+ */
+
+};
+
+enum i2c_state_e {
+ I2C_STATE_RESET = 0x00U, /* Peripheral is not yet
+ * initialized.
+ */
+ I2C_STATE_READY = 0x20U, /* Peripheral Initialized
+ * and ready for use.
+ */
+ I2C_STATE_BUSY = 0x24U, /* An internal process is
+ * ongoing.
+ */
+ I2C_STATE_BUSY_TX = 0x21U, /* Data Transmission process
+ * is ongoing.
+ */
+ I2C_STATE_BUSY_RX = 0x22U, /* Data Reception process
+ * is ongoing.
+ */
+ I2C_STATE_LISTEN = 0x28U, /* Address Listen Mode is
+ * ongoing.
+ */
+ I2C_STATE_BUSY_TX_LISTEN = 0x29U, /* Address Listen Mode
+ * and Data Transmission
+ * process is ongoing.
+ */
+ I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /* Address Listen Mode
+ * and Data Reception
+ * process is ongoing.
+ */
+ I2C_STATE_ABORT = 0x60U, /* Abort user request ongoing. */
+ I2C_STATE_TIMEOUT = 0xA0U, /* Timeout state. */
+ I2C_STATE_ERROR = 0xE0U /* Error. */
+
+};
+
+enum i2c_mode_e {
+ I2C_MODE_NONE = 0x00U, /* No I2C communication on going. */
+ I2C_MODE_MASTER = 0x10U, /* I2C communication is in Master Mode. */
+ I2C_MODE_SLAVE = 0x20U, /* I2C communication is in Slave Mode. */
+ I2C_MODE_MEM = 0x40U /* I2C communication is in Memory Mode. */
+
+};
+
+#define I2C_ERROR_NONE 0x00000000U /* No error */
+#define I2C_ERROR_BERR 0x00000001U /* BERR error */
+#define I2C_ERROR_ARLO 0x00000002U /* ARLO error */
+#define I2C_ERROR_AF 0x00000004U /* ACKF error */
+#define I2C_ERROR_OVR 0x00000008U /* OVR error */
+#define I2C_ERROR_DMA 0x00000010U /* DMA transfer error */
+#define I2C_ERROR_TIMEOUT 0x00000020U /* Timeout error */
+#define I2C_ERROR_SIZE 0x00000040U /* Size Management error */
+
+struct i2c_handle_s {
+ uint32_t i2c_base_addr; /* Registers base address */
+
+ struct stm32_i2c_init_s i2c_init; /* Communication parameters */
+
+ uint8_t *p_buff; /* Pointer to transfer buffer */
+
+ uint16_t xfer_size; /* Transfer size */
+
+ uint16_t xfer_count; /* Transfer counter */
+
+ uint32_t prev_state; /* Communication previous
+ * state
+ */
+
+ uint8_t lock; /* Locking object */
+
+ enum i2c_state_e i2c_state; /* Communication state */
+
+ enum i2c_mode_e i2c_mode; /* Communication mode */
+
+ uint32_t i2c_err; /* Error code */
+};
+
+#define I2C_ADDRESSINGMODE_7BIT 0x00000001U
+#define I2C_ADDRESSINGMODE_10BIT 0x00000002U
+
+#define I2C_DUALADDRESS_DISABLE 0x00000000U
+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN
+
+#define I2C_GENERALCALL_DISABLE 0x00000000U
+#define I2C_GENERALCALL_ENABLE I2C_CR1_GCEN
+
+#define I2C_NOSTRETCH_DISABLE 0x00000000U
+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
+
+#define I2C_MEMADD_SIZE_8BIT 0x00000001U
+#define I2C_MEMADD_SIZE_16BIT 0x00000002U
+
+#define I2C_RELOAD_MODE I2C_CR2_RELOAD
+#define I2C_AUTOEND_MODE I2C_CR2_AUTOEND
+#define I2C_SOFTEND_MODE 0x00000000U
+
+#define I2C_NO_STARTSTOP 0x00000000U
+#define I2C_GENERATE_STOP (BIT(31) | I2C_CR2_STOP)
+#define I2C_GENERATE_START_READ (BIT(31) | I2C_CR2_START | \
+ I2C_CR2_RD_WRN)
+#define I2C_GENERATE_START_WRITE (BIT(31) | I2C_CR2_START)
+
+#define I2C_FLAG_TXE I2C_ISR_TXE
+#define I2C_FLAG_TXIS I2C_ISR_TXIS
+#define I2C_FLAG_RXNE I2C_ISR_RXNE
+#define I2C_FLAG_ADDR I2C_ISR_ADDR
+#define I2C_FLAG_AF I2C_ISR_NACKF
+#define I2C_FLAG_STOPF I2C_ISR_STOPF
+#define I2C_FLAG_TC I2C_ISR_TC
+#define I2C_FLAG_TCR I2C_ISR_TCR
+#define I2C_FLAG_BERR I2C_ISR_BERR
+#define I2C_FLAG_ARLO I2C_ISR_ARLO
+#define I2C_FLAG_OVR I2C_ISR_OVR
+#define I2C_FLAG_PECERR I2C_ISR_PECERR
+#define I2C_FLAG_TIMEOUT I2C_ISR_TIMEOUT
+#define I2C_FLAG_ALERT I2C_ISR_ALERT
+#define I2C_FLAG_BUSY I2C_ISR_BUSY
+#define I2C_FLAG_DIR I2C_ISR_DIR
+
+#define I2C_RESET_CR2 (I2C_CR2_SADD | I2C_CR2_HEAD10R | \
+ I2C_CR2_NBYTES | I2C_CR2_RELOAD | \
+ I2C_CR2_RD_WRN)
+
+#define I2C_ANALOGFILTER_ENABLE ((uint32_t)0x00000000U)
+#define I2C_ANALOGFILTER_DISABLE I2C_CR1_ANFOFF
+
+int stm32_i2c_init(struct i2c_handle_s *hi2c);
+
+int stm32_i2c_mem_write(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint8_t *p_data, uint16_t size, uint32_t timeout);
+int stm32_i2c_mem_read(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint16_t mem_addr, uint16_t mem_add_size,
+ uint8_t *p_data, uint16_t size, uint32_t timeout);
+int stm32_i2c_is_device_ready(struct i2c_handle_s *hi2c, uint16_t dev_addr,
+ uint32_t trials, uint32_t timeout);
+
+int stm32_i2c_config_analog_filter(struct i2c_handle_s *hi2c,
+ uint32_t analog_filter);
+
+#endif /* __STM32MP1_I2C_H */
diff --git a/include/drivers/st/stm32mp1_clk.h b/include/drivers/st/stm32mp1_clk.h
new file mode 100644
index 000000000..85a1eb8fd
--- /dev/null
+++ b/include/drivers/st/stm32mp1_clk.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CLK_H__
+#define __STM32MP1_CLK_H__
+
+#include <arch_helpers.h>
+#include <stdbool.h>
+
+int stm32mp1_clk_probe(void);
+int stm32mp1_clk_init(void);
+bool stm32mp1_clk_is_enabled(unsigned long id);
+int stm32mp1_clk_enable(unsigned long id);
+int stm32mp1_clk_disable(unsigned long id);
+unsigned long stm32mp1_clk_get_rate(unsigned long id);
+void stm32mp1_stgen_increment(unsigned long long offset_in_ms);
+
+static inline uint32_t get_timer(uint32_t base)
+{
+ if (base == 0U) {
+ return (uint32_t)(~read_cntpct_el0());
+ }
+
+ return base - (uint32_t)(~read_cntpct_el0());
+}
+
+#endif /* __STM32MP1_CLK_H__ */
diff --git a/include/drivers/st/stm32mp1_clkfunc.h b/include/drivers/st/stm32mp1_clkfunc.h
new file mode 100644
index 000000000..635a9cd4c
--- /dev/null
+++ b/include/drivers/st/stm32mp1_clkfunc.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CLKFUNC_H__
+#define __STM32MP1_CLKFUNC_H__
+
+#include <stdbool.h>
+
+enum stm32mp_osc_id {
+ _HSI,
+ _HSE,
+ _CSI,
+ _LSI,
+ _LSE,
+ _I2S_CKIN,
+ _USB_PHY_48,
+ NB_OSC,
+ _UNKNOWN_OSC_ID = 0xFF
+};
+
+extern const char *stm32mp_osc_node_label[NB_OSC];
+
+int fdt_osc_read_freq(const char *name, uint32_t *freq);
+bool fdt_osc_read_bool(enum stm32mp_osc_id osc_id, const char *prop_name);
+uint32_t fdt_osc_read_uint32_default(enum stm32mp_osc_id osc_id,
+ const char *prop_name,
+ uint32_t dflt_value);
+
+uint32_t fdt_rcc_read_addr(void);
+int fdt_rcc_read_uint32_array(const char *prop_name,
+ uint32_t *array, uint32_t count);
+int fdt_rcc_subnode_offset(const char *name);
+const uint32_t *fdt_rcc_read_prop(const char *prop_name, int *lenp);
+bool fdt_get_rcc_secure_status(void);
+
+uintptr_t fdt_get_stgen_base(void);
+int fdt_get_clock_id(int node);
+
+#endif /* __STM32MP1_CLKFUNC_H__ */
diff --git a/include/drivers/st/stm32mp1_ddr.h b/include/drivers/st/stm32mp1_ddr.h
new file mode 100644
index 000000000..076566484
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef _STM32MP1_DDR_H
+#define _STM32MP1_DDR_H
+
+#include <stdbool.h>
+
+#define DT_DDR_COMPAT "st,stm32mp1-ddr"
+
+struct stm32mp1_ddr_size {
+ uint64_t base;
+ uint64_t size;
+};
+
+/**
+ * struct ddr_info
+ *
+ * @dev: pointer for the device
+ * @info: UCLASS RAM information
+ * @ctl: DDR controleur base address
+ * @phy: DDR PHY base address
+ * @syscfg: syscfg base address
+ */
+struct ddr_info {
+ struct stm32mp1_ddr_size info;
+ struct stm32mp1_ddrctl *ctl;
+ struct stm32mp1_ddrphy *phy;
+ uintptr_t pwr;
+ uintptr_t rcc;
+};
+
+struct stm32mp1_ddrctrl_reg {
+ uint32_t mstr;
+ uint32_t mrctrl0;
+ uint32_t mrctrl1;
+ uint32_t derateen;
+ uint32_t derateint;
+ uint32_t pwrctl;
+ uint32_t pwrtmg;
+ uint32_t hwlpctl;
+ uint32_t rfshctl0;
+ uint32_t rfshctl3;
+ uint32_t crcparctl0;
+ uint32_t zqctl0;
+ uint32_t dfitmg0;
+ uint32_t dfitmg1;
+ uint32_t dfilpcfg0;
+ uint32_t dfiupd0;
+ uint32_t dfiupd1;
+ uint32_t dfiupd2;
+ uint32_t dfiphymstr;
+ uint32_t odtmap;
+ uint32_t dbg0;
+ uint32_t dbg1;
+ uint32_t dbgcmd;
+ uint32_t poisoncfg;
+ uint32_t pccfg;
+};
+
+struct stm32mp1_ddrctrl_timing {
+ uint32_t rfshtmg;
+ uint32_t dramtmg0;
+ uint32_t dramtmg1;
+ uint32_t dramtmg2;
+ uint32_t dramtmg3;
+ uint32_t dramtmg4;
+ uint32_t dramtmg5;
+ uint32_t dramtmg6;
+ uint32_t dramtmg7;
+ uint32_t dramtmg8;
+ uint32_t dramtmg14;
+ uint32_t odtcfg;
+};
+
+struct stm32mp1_ddrctrl_map {
+ uint32_t addrmap1;
+ uint32_t addrmap2;
+ uint32_t addrmap3;
+ uint32_t addrmap4;
+ uint32_t addrmap5;
+ uint32_t addrmap6;
+ uint32_t addrmap9;
+ uint32_t addrmap10;
+ uint32_t addrmap11;
+};
+
+struct stm32mp1_ddrctrl_perf {
+ uint32_t sched;
+ uint32_t sched1;
+ uint32_t perfhpr1;
+ uint32_t perflpr1;
+ uint32_t perfwr1;
+ uint32_t pcfgr_0;
+ uint32_t pcfgw_0;
+ uint32_t pcfgqos0_0;
+ uint32_t pcfgqos1_0;
+ uint32_t pcfgwqos0_0;
+ uint32_t pcfgwqos1_0;
+ uint32_t pcfgr_1;
+ uint32_t pcfgw_1;
+ uint32_t pcfgqos0_1;
+ uint32_t pcfgqos1_1;
+ uint32_t pcfgwqos0_1;
+ uint32_t pcfgwqos1_1;
+};
+
+struct stm32mp1_ddrphy_reg {
+ uint32_t pgcr;
+ uint32_t aciocr;
+ uint32_t dxccr;
+ uint32_t dsgcr;
+ uint32_t dcr;
+ uint32_t odtcr;
+ uint32_t zq0cr1;
+ uint32_t dx0gcr;
+ uint32_t dx1gcr;
+ uint32_t dx2gcr;
+ uint32_t dx3gcr;
+};
+
+struct stm32mp1_ddrphy_timing {
+ uint32_t ptr0;
+ uint32_t ptr1;
+ uint32_t ptr2;
+ uint32_t dtpr0;
+ uint32_t dtpr1;
+ uint32_t dtpr2;
+ uint32_t mr0;
+ uint32_t mr1;
+ uint32_t mr2;
+ uint32_t mr3;
+};
+
+struct stm32mp1_ddrphy_cal {
+ uint32_t dx0dllcr;
+ uint32_t dx0dqtr;
+ uint32_t dx0dqstr;
+ uint32_t dx1dllcr;
+ uint32_t dx1dqtr;
+ uint32_t dx1dqstr;
+ uint32_t dx2dllcr;
+ uint32_t dx2dqtr;
+ uint32_t dx2dqstr;
+ uint32_t dx3dllcr;
+ uint32_t dx3dqtr;
+ uint32_t dx3dqstr;
+};
+
+struct stm32mp1_ddr_info {
+ const char *name;
+ uint16_t speed; /* in MHZ */
+ uint32_t size; /* Memory size in byte = col * row * width */
+};
+
+struct stm32mp1_ddr_config {
+ struct stm32mp1_ddr_info info;
+ struct stm32mp1_ddrctrl_reg c_reg;
+ struct stm32mp1_ddrctrl_timing c_timing;
+ struct stm32mp1_ddrctrl_map c_map;
+ struct stm32mp1_ddrctrl_perf c_perf;
+ struct stm32mp1_ddrphy_reg p_reg;
+ struct stm32mp1_ddrphy_timing p_timing;
+ struct stm32mp1_ddrphy_cal p_cal;
+};
+
+int stm32mp1_ddr_clk_enable(struct ddr_info *priv, uint16_t mem_speed);
+void stm32mp1_ddr_init(struct ddr_info *priv,
+ struct stm32mp1_ddr_config *config);
+#endif /* _STM32MP1_DDR_H */
diff --git a/include/drivers/st/stm32mp1_ddr_helpers.h b/include/drivers/st/stm32mp1_ddr_helpers.h
new file mode 100644
index 000000000..298a08044
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr_helpers.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_DDR_HELPERS_H__
+#define __STM32MP1_DDR_HELPERS_H__
+
+void ddr_enable_clock(void);
+
+#endif /* __STM32MP1_DDR_HELPERS_H__ */
diff --git a/include/drivers/st/stm32mp1_ddr_regs.h b/include/drivers/st/stm32mp1_ddr_regs.h
new file mode 100644
index 000000000..64ad96554
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ddr_regs.h
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef _RAM_STM32MP1_DDR_REGS_H
+#define _RAM_STM32MP1_DDR_REGS_H
+
+#include <utils_def.h>
+
+/* DDR3/LPDDR2/LPDDR3 Controller (DDRCTRL) registers */
+struct stm32mp1_ddrctl {
+ uint32_t mstr ; /* 0x0 Master */
+ uint32_t stat; /* 0x4 Operating Mode Status */
+ uint8_t reserved008[0x10 - 0x8];
+ uint32_t mrctrl0; /* 0x10 Control 0 */
+ uint32_t mrctrl1; /* 0x14 Control 1 */
+ uint32_t mrstat; /* 0x18 Status */
+ uint32_t reserved01c; /* 0x1c */
+ uint32_t derateen; /* 0x20 Temperature Derate Enable */
+ uint32_t derateint; /* 0x24 Temperature Derate Interval */
+ uint8_t reserved028[0x30 - 0x28];
+ uint32_t pwrctl; /* 0x30 Low Power Control */
+ uint32_t pwrtmg; /* 0x34 Low Power Timing */
+ uint32_t hwlpctl; /* 0x38 Hardware Low Power Control */
+ uint8_t reserved03c[0x50 - 0x3C];
+ uint32_t rfshctl0; /* 0x50 Refresh Control 0 */
+ uint32_t reserved054; /* 0x54 Refresh Control 1 */
+ uint32_t reserved058; /* 0x58 Refresh Control 2 */
+ uint32_t reserved05C;
+ uint32_t rfshctl3; /* 0x60 Refresh Control 0 */
+ uint32_t rfshtmg; /* 0x64 Refresh Timing */
+ uint8_t reserved068[0xc0 - 0x68];
+ uint32_t crcparctl0; /* 0xc0 CRC Parity Control0 */
+ uint32_t reserved0c4; /* 0xc4 CRC Parity Control1 */
+ uint32_t reserved0c8; /* 0xc8 CRC Parity Control2 */
+ uint32_t crcparstat; /* 0xcc CRC Parity Status */
+ uint32_t init0; /* 0xd0 SDRAM Initialization 0 */
+ uint32_t init1; /* 0xd4 SDRAM Initialization 1 */
+ uint32_t init2; /* 0xd8 SDRAM Initialization 2 */
+ uint32_t init3; /* 0xdc SDRAM Initialization 3 */
+ uint32_t init4; /* 0xe0 SDRAM Initialization 4 */
+ uint32_t init5; /* 0xe4 SDRAM Initialization 5 */
+ uint32_t reserved0e8;
+ uint32_t reserved0ec;
+ uint32_t dimmctl; /* 0xf0 DIMM Control */
+ uint8_t reserved0f4[0x100 - 0xf4];
+ uint32_t dramtmg0; /* 0x100 SDRAM Timing 0 */
+ uint32_t dramtmg1; /* 0x104 SDRAM Timing 1 */
+ uint32_t dramtmg2; /* 0x108 SDRAM Timing 2 */
+ uint32_t dramtmg3; /* 0x10c SDRAM Timing 3 */
+ uint32_t dramtmg4; /* 0x110 SDRAM Timing 4 */
+ uint32_t dramtmg5; /* 0x114 SDRAM Timing 5 */
+ uint32_t dramtmg6; /* 0x118 SDRAM Timing 6 */
+ uint32_t dramtmg7; /* 0x11c SDRAM Timing 7 */
+ uint32_t dramtmg8; /* 0x120 SDRAM Timing 8 */
+ uint8_t reserved124[0x138 - 0x124];
+ uint32_t dramtmg14; /* 0x138 SDRAM Timing 14 */
+ uint32_t dramtmg15; /* 0x13C SDRAM Timing 15 */
+ uint8_t reserved140[0x180 - 0x140];
+ uint32_t zqctl0; /* 0x180 ZQ Control 0 */
+ uint32_t zqctl1; /* 0x184 ZQ Control 1 */
+ uint32_t zqctl2; /* 0x188 ZQ Control 2 */
+ uint32_t zqstat; /* 0x18c ZQ Status */
+ uint32_t dfitmg0; /* 0x190 DFI Timing 0 */
+ uint32_t dfitmg1; /* 0x194 DFI Timing 1 */
+ uint32_t dfilpcfg0; /* 0x198 DFI Low Power Configuration 0 */
+ uint32_t reserved19c;
+ uint32_t dfiupd0; /* 0x1a0 DFI Update 0 */
+ uint32_t dfiupd1; /* 0x1a4 DFI Update 1 */
+ uint32_t dfiupd2; /* 0x1a8 DFI Update 2 */
+ uint32_t reserved1ac;
+ uint32_t dfimisc; /* 0x1b0 DFI Miscellaneous Control */
+ uint8_t reserved1b4[0x1bc - 0x1b4];
+ uint32_t dfistat; /* 0x1bc DFI Miscellaneous Control */
+ uint8_t reserved1c0[0x1c4 - 0x1c0];
+ uint32_t dfiphymstr; /* 0x1c4 DFI PHY Master interface */
+ uint8_t reserved1c8[0x204 - 0x1c8];
+ uint32_t addrmap1; /* 0x204 Address Map 1 */
+ uint32_t addrmap2; /* 0x208 Address Map 2 */
+ uint32_t addrmap3; /* 0x20c Address Map 3 */
+ uint32_t addrmap4; /* 0x210 Address Map 4 */
+ uint32_t addrmap5; /* 0x214 Address Map 5 */
+ uint32_t addrmap6; /* 0x218 Address Map 6 */
+ uint8_t reserved21c[0x224 - 0x21c];
+ uint32_t addrmap9; /* 0x224 Address Map 9 */
+ uint32_t addrmap10; /* 0x228 Address Map 10 */
+ uint32_t addrmap11; /* 0x22C Address Map 11 */
+ uint8_t reserved230[0x240 - 0x230];
+ uint32_t odtcfg; /* 0x240 ODT Configuration */
+ uint32_t odtmap; /* 0x244 ODT/Rank Map */
+ uint8_t reserved248[0x250 - 0x248];
+ uint32_t sched; /* 0x250 Scheduler Control */
+ uint32_t sched1; /* 0x254 Scheduler Control 1 */
+ uint32_t reserved258;
+ uint32_t perfhpr1; /* 0x25c High Priority Read CAM 1 */
+ uint32_t reserved260;
+ uint32_t perflpr1; /* 0x264 Low Priority Read CAM 1 */
+ uint32_t reserved268;
+ uint32_t perfwr1; /* 0x26c Write CAM 1 */
+ uint8_t reserved27c[0x300 - 0x270];
+ uint32_t dbg0; /* 0x300 Debug 0 */
+ uint32_t dbg1; /* 0x304 Debug 1 */
+ uint32_t dbgcam; /* 0x308 CAM Debug */
+ uint32_t dbgcmd; /* 0x30c Command Debug */
+ uint32_t dbgstat; /* 0x310 Status Debug */
+ uint8_t reserved314[0x320 - 0x314];
+ uint32_t swctl; /* 0x320 Software Programming Control Enable */
+ uint32_t swstat; /* 0x324 Software Programming Control Status */
+ uint8_t reserved328[0x36c - 0x328];
+ uint32_t poisoncfg; /* 0x36c AXI Poison Configuration Register */
+ uint32_t poisonstat; /* 0x370 AXI Poison Status Register */
+ uint8_t reserved374[0x3fc - 0x374];
+
+ /* Multi Port registers */
+ uint32_t pstat; /* 0x3fc Port Status */
+ uint32_t pccfg; /* 0x400 Port Common Configuration */
+
+ /* PORT 0 */
+ uint32_t pcfgr_0; /* 0x404 Configuration Read */
+ uint32_t pcfgw_0; /* 0x408 Configuration Write */
+ uint8_t reserved40c[0x490 - 0x40c];
+ uint32_t pctrl_0; /* 0x490 Port Control Register */
+ uint32_t pcfgqos0_0; /* 0x494 Read QoS Configuration 0 */
+ uint32_t pcfgqos1_0; /* 0x498 Read QoS Configuration 1 */
+ uint32_t pcfgwqos0_0; /* 0x49c Write QoS Configuration 0 */
+ uint32_t pcfgwqos1_0; /* 0x4a0 Write QoS Configuration 1 */
+ uint8_t reserved4a4[0x4b4 - 0x4a4];
+
+ /* PORT 1 */
+ uint32_t pcfgr_1; /* 0x4b4 Configuration Read */
+ uint32_t pcfgw_1; /* 0x4b8 Configuration Write */
+ uint8_t reserved4bc[0x540 - 0x4bc];
+ uint32_t pctrl_1; /* 0x540 Port 2 Control Register */
+ uint32_t pcfgqos0_1; /* 0x544 Read QoS Configuration 0 */
+ uint32_t pcfgqos1_1; /* 0x548 Read QoS Configuration 1 */
+ uint32_t pcfgwqos0_1; /* 0x54c Write QoS Configuration 0 */
+ uint32_t pcfgwqos1_1; /* 0x550 Write QoS Configuration 1 */
+} __packed;
+
+/* DDR Physical Interface Control (DDRPHYC) registers*/
+struct stm32mp1_ddrphy {
+ uint32_t ridr; /* 0x00 R Revision Identification */
+ uint32_t pir; /* 0x04 R/W PHY Initialization */
+ uint32_t pgcr; /* 0x08 R/W PHY General Configuration */
+ uint32_t pgsr; /* 0x0C PHY General Status */
+ uint32_t dllgcr; /* 0x10 R/W DLL General Control */
+ uint32_t acdllcr; /* 0x14 R/W AC DLL Control */
+ uint32_t ptr0; /* 0x18 R/W PHY Timing 0 */
+ uint32_t ptr1; /* 0x1C R/W PHY Timing 1 */
+ uint32_t ptr2; /* 0x20 R/W PHY Timing 2 */
+ uint32_t aciocr; /* 0x24 AC I/O Configuration */
+ uint32_t dxccr; /* 0x28 DATX8 Common Configuration */
+ uint32_t dsgcr; /* 0x2C DDR System General Configuration */
+ uint32_t dcr; /* 0x30 DRAM Configuration */
+ uint32_t dtpr0; /* 0x34 DRAM Timing Parameters0 */
+ uint32_t dtpr1; /* 0x38 DRAM Timing Parameters1 */
+ uint32_t dtpr2; /* 0x3C DRAM Timing Parameters2 */
+ uint32_t mr0; /* 0x40 Mode 0 */
+ uint32_t mr1; /* 0x44 Mode 1 */
+ uint32_t mr2; /* 0x48 Mode 2 */
+ uint32_t mr3; /* 0x4C Mode 3 */
+ uint32_t odtcr; /* 0x50 ODT Configuration */
+ uint32_t dtar; /* 0x54 data training address */
+ uint32_t dtdr0; /* 0x58 */
+ uint32_t dtdr1; /* 0x5c */
+ uint8_t res1[0x0c0 - 0x060]; /* 0x60 */
+ uint32_t dcuar; /* 0xc0 Address */
+ uint32_t dcudr; /* 0xc4 DCU Data */
+ uint32_t dcurr; /* 0xc8 DCU Run */
+ uint32_t dculr; /* 0xcc DCU Loop */
+ uint32_t dcugcr; /* 0xd0 DCU General Configuration */
+ uint32_t dcutpr; /* 0xd4 DCU Timing Parameters */
+ uint32_t dcusr0; /* 0xd8 DCU Status 0 */
+ uint32_t dcusr1; /* 0xdc DCU Status 1 */
+ uint8_t res2[0x100 - 0xe0]; /* 0xe0 */
+ uint32_t bistrr; /* 0x100 BIST Run */
+ uint32_t bistmskr0; /* 0x104 BIST Mask 0 */
+ uint32_t bistmskr1; /* 0x108 BIST Mask 0 */
+ uint32_t bistwcr; /* 0x10c BIST Word Count */
+ uint32_t bistlsr; /* 0x110 BIST LFSR Seed */
+ uint32_t bistar0; /* 0x114 BIST Address 0 */
+ uint32_t bistar1; /* 0x118 BIST Address 1 */
+ uint32_t bistar2; /* 0x11c BIST Address 2 */
+ uint32_t bistupdr; /* 0x120 BIST User Data Pattern */
+ uint32_t bistgsr; /* 0x124 BIST General Status */
+ uint32_t bistwer; /* 0x128 BIST Word Error */
+ uint32_t bistber0; /* 0x12c BIST Bit Error 0 */
+ uint32_t bistber1; /* 0x130 BIST Bit Error 1 */
+ uint32_t bistber2; /* 0x134 BIST Bit Error 2 */
+ uint32_t bistwcsr; /* 0x138 BIST Word Count Status */
+ uint32_t bistfwr0; /* 0x13c BIST Fail Word 0 */
+ uint32_t bistfwr1; /* 0x140 BIST Fail Word 1 */
+ uint8_t res3[0x178 - 0x144]; /* 0x144 */
+ uint32_t gpr0; /* 0x178 General Purpose 0 (GPR0) */
+ uint32_t gpr1; /* 0x17C General Purpose 1 (GPR1) */
+ uint32_t zq0cr0; /* 0x180 zq 0 control 0 */
+ uint32_t zq0cr1; /* 0x184 zq 0 control 1 */
+ uint32_t zq0sr0; /* 0x188 zq 0 status 0 */
+ uint32_t zq0sr1; /* 0x18C zq 0 status 1 */
+ uint8_t res4[0x1C0 - 0x190]; /* 0x190 */
+ uint32_t dx0gcr; /* 0x1c0 Byte lane 0 General Configuration */
+ uint32_t dx0gsr0; /* 0x1c4 Byte lane 0 General Status 0 */
+ uint32_t dx0gsr1; /* 0x1c8 Byte lane 0 General Status 1 */
+ uint32_t dx0dllcr; /* 0x1cc Byte lane 0 DLL Control */
+ uint32_t dx0dqtr; /* 0x1d0 Byte lane 0 DQ Timing */
+ uint32_t dx0dqstr; /* 0x1d4 Byte lane 0 DQS Timing */
+ uint8_t res5[0x200 - 0x1d8]; /* 0x1d8 */
+ uint32_t dx1gcr; /* 0x200 Byte lane 1 General Configuration */
+ uint32_t dx1gsr0; /* 0x204 Byte lane 1 General Status 0 */
+ uint32_t dx1gsr1; /* 0x208 Byte lane 1 General Status 1 */
+ uint32_t dx1dllcr; /* 0x20c Byte lane 1 DLL Control */
+ uint32_t dx1dqtr; /* 0x210 Byte lane 1 DQ Timing */
+ uint32_t dx1dqstr; /* 0x214 Byte lane 1 QS Timing */
+ uint8_t res6[0x240 - 0x218]; /* 0x218 */
+ uint32_t dx2gcr; /* 0x240 Byte lane 2 General Configuration */
+ uint32_t dx2gsr0; /* 0x244 Byte lane 2 General Status 0 */
+ uint32_t dx2gsr1; /* 0x248 Byte lane 2 General Status 1 */
+ uint32_t dx2dllcr; /* 0x24c Byte lane 2 DLL Control */
+ uint32_t dx2dqtr; /* 0x250 Byte lane 2 DQ Timing */
+ uint32_t dx2dqstr; /* 0x254 Byte lane 2 QS Timing */
+ uint8_t res7[0x280 - 0x258]; /* 0x258 */
+ uint32_t dx3gcr; /* 0x280 Byte lane 3 General Configuration */
+ uint32_t dx3gsr0; /* 0x284 Byte lane 3 General Status 0 */
+ uint32_t dx3gsr1; /* 0x288 Byte lane 3 General Status 1 */
+ uint32_t dx3dllcr; /* 0x28c Byte lane 3 DLL Control */
+ uint32_t dx3dqtr; /* 0x290 Byte lane 3 DQ Timing */
+ uint32_t dx3dqstr; /* 0x294 Byte lane 3 QS Timing */
+} __packed;
+
+/* DDR Controller registers offsets */
+#define DDRCTRL_MSTR 0x000
+#define DDRCTRL_STAT 0x004
+#define DDRCTRL_MRCTRL0 0x010
+#define DDRCTRL_MRSTAT 0x018
+#define DDRCTRL_PWRCTL 0x030
+#define DDRCTRL_PWRTMG 0x034
+#define DDRCTRL_HWLPCTL 0x038
+#define DDRCTRL_RFSHCTL3 0x060
+#define DDRCTRL_RFSHTMG 0x064
+#define DDRCTRL_INIT0 0x0D0
+#define DDRCTRL_DFIMISC 0x1B0
+#define DDRCTRL_DBG1 0x304
+#define DDRCTRL_DBGCAM 0x308
+#define DDRCTRL_DBGCMD 0x30C
+#define DDRCTRL_DBGSTAT 0x310
+#define DDRCTRL_SWCTL 0x320
+#define DDRCTRL_SWSTAT 0x324
+#define DDRCTRL_PCTRL_0 0x490
+#define DDRCTRL_PCTRL_1 0x540
+
+/* DDR Controller Register fields */
+#define DDRCTRL_MSTR_DDR3 BIT(0)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_MASK GENMASK(13, 12)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_FULL 0
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_HALF BIT(12)
+#define DDRCTRL_MSTR_DATA_BUS_WIDTH_QUARTER BIT(13)
+#define DDRCTRL_MSTR_DLL_OFF_MODE BIT(15)
+
+#define DDRCTRL_STAT_OPERATING_MODE_MASK GENMASK(2, 0)
+#define DDRCTRL_STAT_OPERATING_MODE_NORMAL BIT(0)
+#define DDRCTRL_STAT_OPERATING_MODE_SR (BIT(0) | BIT(1))
+#define DDRCTRL_STAT_SELFREF_TYPE_MASK GENMASK(5, 4)
+#define DDRCTRL_STAT_SELFREF_TYPE_ASR (BIT(4) | BIT(5))
+#define DDRCTRL_STAT_SELFREF_TYPE_SR BIT(5)
+
+#define DDRCTRL_MRCTRL0_MR_TYPE_WRITE U(0)
+/* Only one rank supported */
+#define DDRCTRL_MRCTRL0_MR_RANK_SHIFT 4
+#define DDRCTRL_MRCTRL0_MR_RANK_ALL \
+ (0x1U << DDRCTRL_MRCTRL0_MR_RANK_SHIFT)
+#define DDRCTRL_MRCTRL0_MR_ADDR_SHIFT 12
+#define DDRCTRL_MRCTRL0_MR_ADDR_MASK GENMASK(15, 12)
+#define DDRCTRL_MRCTRL0_MR_WR BIT(31)
+
+#define DDRCTRL_MRSTAT_MR_WR_BUSY BIT(0)
+
+#define DDRCTRL_PWRCTL_SELFREF_EN BIT(0)
+#define DDRCTRL_PWRCTL_POWERDOWN_EN BIT(1)
+#define DDRCTRL_PWRCTL_EN_DFI_DRAM_CLK_DISABLE BIT(3)
+#define DDRCTRL_PWRCTL_SELFREF_SW BIT(5)
+
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_MASK GENMASK(19, 12)
+#define DDRCTRL_PWRTMG_SELFREF_TO_X32_0 BIT(16)
+
+#define DDRCTRL_RFSHCTL3_DIS_AUTO_REFRESH BIT(0)
+
+#define DDRCTRL_HWLPCTL_HW_LP_EN BIT(0)
+
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_MASK GENMASK(27, 16)
+#define DDRCTRL_RFSHTMG_T_RFC_NOM_X1_X32_SHIFT 16
+
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_MASK GENMASK(31, 30)
+#define DDRCTRL_INIT0_SKIP_DRAM_INIT_NORMAL BIT(30)
+
+#define DDRCTRL_DFIMISC_DFI_INIT_COMPLETE_EN BIT(0)
+
+#define DDRCTRL_DBG1_DIS_HIF BIT(1)
+
+#define DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY BIT(29)
+#define DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY BIT(28)
+#define DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY BIT(26)
+#define DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH GENMASK(12, 8)
+#define DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH GENMASK(4, 0)
+#define DDRCTRL_DBGCAM_DATA_PIPELINE_EMPTY \
+ (DDRCTRL_DBGCAM_WR_DATA_PIPELINE_EMPTY | \
+ DDRCTRL_DBGCAM_RD_DATA_PIPELINE_EMPTY)
+#define DDRCTRL_DBGCAM_DBG_Q_DEPTH \
+ (DDRCTRL_DBGCAM_DBG_WR_Q_EMPTY | \
+ DDRCTRL_DBGCAM_DBG_LPR_Q_DEPTH | \
+ DDRCTRL_DBGCAM_DBG_HPR_Q_DEPTH)
+
+#define DDRCTRL_DBGCMD_RANK0_REFRESH BIT(0)
+
+#define DDRCTRL_DBGSTAT_RANK0_REFRESH_BUSY BIT(0)
+
+#define DDRCTRL_SWCTL_SW_DONE BIT(0)
+
+#define DDRCTRL_SWSTAT_SW_DONE_ACK BIT(0)
+
+#define DDRCTRL_PCTRL_N_PORT_EN BIT(0)
+
+/* DDR PHY registers offsets */
+#define DDRPHYC_PIR 0x004
+#define DDRPHYC_PGCR 0x008
+#define DDRPHYC_PGSR 0x00C
+#define DDRPHYC_DLLGCR 0x010
+#define DDRPHYC_ACDLLCR 0x014
+#define DDRPHYC_PTR0 0x018
+#define DDRPHYC_ACIOCR 0x024
+#define DDRPHYC_DXCCR 0x028
+#define DDRPHYC_DSGCR 0x02C
+#define DDRPHYC_ZQ0CR0 0x180
+#define DDRPHYC_DX0GCR 0x1C0
+#define DDRPHYC_DX0DLLCR 0x1CC
+#define DDRPHYC_DX1GCR 0x200
+#define DDRPHYC_DX1DLLCR 0x20C
+#define DDRPHYC_DX2GCR 0x240
+#define DDRPHYC_DX2DLLCR 0x24C
+#define DDRPHYC_DX3GCR 0x280
+#define DDRPHYC_DX3DLLCR 0x28C
+
+/* DDR PHY Register fields */
+#define DDRPHYC_PIR_INIT BIT(0)
+#define DDRPHYC_PIR_DLLSRST BIT(1)
+#define DDRPHYC_PIR_DLLLOCK BIT(2)
+#define DDRPHYC_PIR_ZCAL BIT(3)
+#define DDRPHYC_PIR_ITMSRST BIT(4)
+#define DDRPHYC_PIR_DRAMRST BIT(5)
+#define DDRPHYC_PIR_DRAMINIT BIT(6)
+#define DDRPHYC_PIR_QSTRN BIT(7)
+#define DDRPHYC_PIR_ICPC BIT(16)
+#define DDRPHYC_PIR_ZCALBYP BIT(30)
+#define DDRPHYC_PIR_INITSTEPS_MASK GENMASK(31, 7)
+
+#define DDRPHYC_PGCR_DFTCMP BIT(2)
+#define DDRPHYC_PGCR_PDDISDX BIT(24)
+#define DDRPHYC_PGCR_RFSHDT_MASK GENMASK(28, 25)
+
+#define DDRPHYC_PGSR_IDONE BIT(0)
+#define DDRPHYC_PGSR_DTERR BIT(5)
+#define DDRPHYC_PGSR_DTIERR BIT(6)
+#define DDRPHYC_PGSR_DFTERR BIT(7)
+#define DDRPHYC_PGSR_RVERR BIT(8)
+#define DDRPHYC_PGSR_RVEIRR BIT(9)
+
+#define DDRPHYC_DLLGCR_BPS200 BIT(23)
+
+#define DDRPHYC_ACDLLCR_DLLDIS BIT(31)
+
+#define DDRPHYC_PTR0_TDLLSRST_OFFSET 0
+#define DDRPHYC_PTR0_TDLLSRST_MASK GENMASK(5, 0)
+#define DDRPHYC_PTR0_TDLLLOCK_OFFSET 6
+#define DDRPHYC_PTR0_TDLLLOCK_MASK GENMASK(17, 6)
+#define DDRPHYC_PTR0_TITMSRST_OFFSET 18
+#define DDRPHYC_PTR0_TITMSRST_MASK GENMASK(21, 18)
+
+#define DDRPHYC_ACIOCR_ACPDD BIT(3)
+#define DDRPHYC_ACIOCR_ACPDR BIT(4)
+#define DDRPHYC_ACIOCR_CKPDD_MASK GENMASK(10, 8)
+#define DDRPHYC_ACIOCR_CKPDD_0 BIT(8)
+#define DDRPHYC_ACIOCR_CKPDR_MASK GENMASK(13, 11)
+#define DDRPHYC_ACIOCR_CKPDR_0 BIT(11)
+#define DDRPHYC_ACIOCR_CSPDD_MASK GENMASK(21, 18)
+#define DDRPHYC_ACIOCR_CSPDD_0 BIT(18)
+#define DDRPHYC_ACIOCR_RSTPDD BIT(27)
+#define DDRPHYC_ACIOCR_RSTPDR BIT(28)
+
+#define DDRPHYC_DXCCR_DXPDD BIT(2)
+#define DDRPHYC_DXCCR_DXPDR BIT(3)
+
+#define DDRPHYC_DSGCR_CKEPDD_MASK GENMASK(19, 16)
+#define DDRPHYC_DSGCR_CKEPDD_0 BIT(16)
+#define DDRPHYC_DSGCR_ODTPDD_MASK GENMASK(23, 20)
+#define DDRPHYC_DSGCR_ODTPDD_0 BIT(20)
+#define DDRPHYC_DSGCR_NL2PD BIT(24)
+
+#define DDRPHYC_ZQ0CRN_ZDATA_MASK GENMASK(27, 0)
+#define DDRPHYC_ZQ0CRN_ZDATA_SHIFT 0
+#define DDRPHYC_ZQ0CRN_ZDEN BIT(28)
+#define DDRPHYC_ZQ0CRN_ZQPD BIT(31)
+
+#define DDRPHYC_DXNGCR_DXEN BIT(0)
+
+#define DDRPHYC_DXNDLLCR_DLLSRST BIT(30)
+#define DDRPHYC_DXNDLLCR_DLLDIS BIT(31)
+#define DDRPHYC_DXNDLLCR_SDPHASE_MASK GENMASK(17, 14)
+#define DDRPHYC_DXNDLLCR_SDPHASE_SHIFT 14
+
+void ddr_enable_clock(void);
+
+#endif /* _RAM_STM32MP1_DDR_REGS_H */
diff --git a/include/drivers/st/stm32mp1_pmic.h b/include/drivers/st/stm32mp1_pmic.h
new file mode 100644
index 000000000..5d94b404b
--- /dev/null
+++ b/include/drivers/st/stm32mp1_pmic.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PMIC_H__
+#define __STM32MP1_PMIC_H__
+
+#include <stdbool.h>
+
+bool dt_check_pmic(void);
+int dt_pmic_enable_boot_on_regulators(void);
+void initialize_pmic_i2c(void);
+void initialize_pmic(void);
+int pmic_ddr_power_init(enum ddr_type ddr_type);
+
+#endif /* __STM32MP1_PMIC_H__ */
diff --git a/include/drivers/st/stm32mp1_pwr.h b/include/drivers/st/stm32mp1_pwr.h
new file mode 100644
index 000000000..e56704295
--- /dev/null
+++ b/include/drivers/st/stm32mp1_pwr.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PWR_H__
+#define __STM32MP1_PWR_H__
+
+#include <utils_def.h>
+
+#define PWR_CR1 U(0x00)
+#define PWR_CR2 U(0x08)
+#define PWR_CR3 U(0x0C)
+#define PWR_MPUCR U(0x10)
+#define PWR_WKUPCR U(0x20)
+#define PWR_MPUWKUPENR U(0x28)
+
+#define PWR_CR1_LPDS BIT(0)
+#define PWR_CR1_LPCFG BIT(1)
+#define PWR_CR1_LVDS BIT(2)
+#define PWR_CR1_DBP BIT(8)
+
+#define PWR_CR3_DDRSREN BIT(10)
+#define PWR_CR3_DDRSRDIS BIT(11)
+#define PWR_CR3_DDRRETEN BIT(12)
+
+#define PWR_MPUCR_PDDS BIT(0)
+#define PWR_MPUCR_CSTDBYDIS BIT(3)
+#define PWR_MPUCR_CSSF BIT(9)
+
+#endif /* __STM32MP1_PWR_H__ */
diff --git a/include/drivers/st/stm32mp1_ram.h b/include/drivers/st/stm32mp1_ram.h
new file mode 100644
index 000000000..af9617779
--- /dev/null
+++ b/include/drivers/st/stm32mp1_ram.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _STM32MP1_RAM_H
+#define _STM32MP1_RAM_H
+
+int stm32mp1_ddr_probe(void);
+
+#endif /* _STM32MP1_RAM_H */
diff --git a/include/drivers/st/stm32mp1_rcc.h b/include/drivers/st/stm32mp1_rcc.h
new file mode 100644
index 000000000..e28ca979f
--- /dev/null
+++ b/include/drivers/st/stm32mp1_rcc.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 2015-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_RCC_H__
+#define __STM32MP1_RCC_H__
+
+#include <utils_def.h>
+
+#define RCC_TZCR U(0x00)
+#define RCC_OCENSETR U(0x0C)
+#define RCC_OCENCLRR U(0x10)
+#define RCC_HSICFGR U(0x18)
+#define RCC_CSICFGR U(0x1C)
+#define RCC_MPCKSELR U(0x20)
+#define RCC_ASSCKSELR U(0x24)
+#define RCC_RCK12SELR U(0x28)
+#define RCC_MPCKDIVR U(0x2C)
+#define RCC_AXIDIVR U(0x30)
+#define RCC_APB4DIVR U(0x3C)
+#define RCC_APB5DIVR U(0x40)
+#define RCC_RTCDIVR U(0x44)
+#define RCC_MSSCKSELR U(0x48)
+#define RCC_PLL1CR U(0x80)
+#define RCC_PLL1CFGR1 U(0x84)
+#define RCC_PLL1CFGR2 U(0x88)
+#define RCC_PLL1FRACR U(0x8C)
+#define RCC_PLL1CSGR U(0x90)
+#define RCC_PLL2CR U(0x94)
+#define RCC_PLL2CFGR1 U(0x98)
+#define RCC_PLL2CFGR2 U(0x9C)
+#define RCC_PLL2FRACR U(0xA0)
+#define RCC_PLL2CSGR U(0xA4)
+#define RCC_I2C46CKSELR U(0xC0)
+#define RCC_SPI6CKSELR U(0xC4)
+#define RCC_UART1CKSELR U(0xC8)
+#define RCC_RNG1CKSELR U(0xCC)
+#define RCC_CPERCKSELR U(0xD0)
+#define RCC_STGENCKSELR U(0xD4)
+#define RCC_DDRITFCR U(0xD8)
+#define RCC_MP_BOOTCR U(0x100)
+#define RCC_MP_SREQSETR U(0x104)
+#define RCC_MP_SREQCLRR U(0x108)
+#define RCC_MP_GCR U(0x10C)
+#define RCC_MP_APRSTCR U(0x110)
+#define RCC_MP_APRSTSR U(0x114)
+#define RCC_BDCR U(0x140)
+#define RCC_RDLSICR U(0x144)
+#define RCC_APB4RSTSETR U(0x180)
+#define RCC_APB4RSTCLRR U(0x184)
+#define RCC_APB5RSTSETR U(0x188)
+#define RCC_APB5RSTCLRR U(0x18C)
+#define RCC_AHB5RSTSETR U(0x190)
+#define RCC_AHB5RSTCLRR U(0x194)
+#define RCC_AHB6RSTSETR U(0x198)
+#define RCC_AHB6RSTCLRR U(0x19C)
+#define RCC_TZAHB6RSTSETR U(0x1A0)
+#define RCC_TZAHB6RSTCLRR U(0x1A4)
+#define RCC_MP_APB4ENSETR U(0x200)
+#define RCC_MP_APB4ENCLRR U(0x204)
+#define RCC_MP_APB5ENSETR U(0x208)
+#define RCC_MP_APB5ENCLRR U(0x20C)
+#define RCC_MP_AHB5ENSETR U(0x210)
+#define RCC_MP_AHB5ENCLRR U(0x214)
+#define RCC_MP_AHB6ENSETR U(0x218)
+#define RCC_MP_AHB6ENCLRR U(0x21C)
+#define RCC_MP_TZAHB6ENSETR U(0x220)
+#define RCC_MP_TZAHB6ENCLRR U(0x224)
+#define RCC_MP_APB4LPENSETR U(0x300)
+#define RCC_MP_APB4LPENCLRR U(0x304)
+#define RCC_MP_APB5LPENSETR U(0x308)
+#define RCC_MP_APB5LPENCLRR U(0x30C)
+#define RCC_MP_AHB5LPENSETR U(0x310)
+#define RCC_MP_AHB5LPENCLRR U(0x314)
+#define RCC_MP_AHB6LPENSETR U(0x318)
+#define RCC_MP_AHB6LPENCLRR U(0x31C)
+#define RCC_MP_TZAHB6LPENSETR U(0x320)
+#define RCC_MP_TZAHB6LPENCLRR U(0x324)
+#define RCC_BR_RSTSCLRR U(0x400)
+#define RCC_MP_GRSTCSETR U(0x404)
+#define RCC_MP_RSTSCLRR U(0x408)
+#define RCC_MP_IWDGFZSETR U(0x40C)
+#define RCC_MP_IWDGFZCLRR U(0x410)
+#define RCC_MP_CIER U(0x414)
+#define RCC_MP_CIFR U(0x418)
+#define RCC_PWRLPDLYCR U(0x41C)
+#define RCC_MP_RSTSSETR U(0x420)
+#define RCC_MCO1CFGR U(0x800)
+#define RCC_MCO2CFGR U(0x804)
+#define RCC_OCRDYR U(0x808)
+#define RCC_DBGCFGR U(0x80C)
+#define RCC_RCK3SELR U(0x820)
+#define RCC_RCK4SELR U(0x824)
+#define RCC_TIMG1PRER U(0x828)
+#define RCC_TIMG2PRER U(0x82C)
+#define RCC_APB1DIVR U(0x834)
+#define RCC_APB2DIVR U(0x838)
+#define RCC_APB3DIVR U(0x83C)
+#define RCC_PLL3CR U(0x880)
+#define RCC_PLL3CFGR1 U(0x884)
+#define RCC_PLL3CFGR2 U(0x888)
+#define RCC_PLL3FRACR U(0x88C)
+#define RCC_PLL3CSGR U(0x890)
+#define RCC_PLL4CR U(0x894)
+#define RCC_PLL4CFGR1 U(0x898)
+#define RCC_PLL4CFGR2 U(0x89C)
+#define RCC_PLL4FRACR U(0x8A0)
+#define RCC_PLL4CSGR U(0x8A4)
+#define RCC_I2C12CKSELR U(0x8C0)
+#define RCC_I2C35CKSELR U(0x8C4)
+#define RCC_SAI1CKSELR U(0x8C8)
+#define RCC_SAI2CKSELR U(0x8CC)
+#define RCC_SAI3CKSELR U(0x8D0)
+#define RCC_SAI4CKSELR U(0x8D4)
+#define RCC_SPI2S1CKSELR U(0x8D8)
+#define RCC_SPI2S23CKSELR U(0x8DC)
+#define RCC_SPI45CKSELR U(0x8E0)
+#define RCC_UART6CKSELR U(0x8E4)
+#define RCC_UART24CKSELR U(0x8E8)
+#define RCC_UART35CKSELR U(0x8EC)
+#define RCC_UART78CKSELR U(0x8F0)
+#define RCC_SDMMC12CKSELR U(0x8F4)
+#define RCC_SDMMC3CKSELR U(0x8F8)
+#define RCC_ETHCKSELR U(0x8FC)
+#define RCC_QSPICKSELR U(0x900)
+#define RCC_FMCCKSELR U(0x904)
+#define RCC_FDCANCKSELR U(0x90C)
+#define RCC_SPDIFCKSELR U(0x914)
+#define RCC_CECCKSELR U(0x918)
+#define RCC_USBCKSELR U(0x91C)
+#define RCC_RNG2CKSELR U(0x920)
+#define RCC_DSICKSELR U(0x924)
+#define RCC_ADCCKSELR U(0x928)
+#define RCC_LPTIM45CKSELR U(0x92C)
+#define RCC_LPTIM23CKSELR U(0x930)
+#define RCC_LPTIM1CKSELR U(0x934)
+#define RCC_APB1RSTSETR U(0x980)
+#define RCC_APB1RSTCLRR U(0x984)
+#define RCC_APB2RSTSETR U(0x988)
+#define RCC_APB2RSTCLRR U(0x98C)
+#define RCC_APB3RSTSETR U(0x990)
+#define RCC_APB3RSTCLRR U(0x994)
+#define RCC_AHB2RSTSETR U(0x998)
+#define RCC_AHB2RSTCLRR U(0x99C)
+#define RCC_AHB3RSTSETR U(0x9A0)
+#define RCC_AHB3RSTCLRR U(0x9A4)
+#define RCC_AHB4RSTSETR U(0x9A8)
+#define RCC_AHB4RSTCLRR U(0x9AC)
+#define RCC_MP_APB1ENSETR U(0xA00)
+#define RCC_MP_APB1ENCLRR U(0xA04)
+#define RCC_MP_APB2ENSETR U(0xA08)
+#define RCC_MP_APB2ENCLRR U(0xA0C)
+#define RCC_MP_APB3ENSETR U(0xA10)
+#define RCC_MP_APB3ENCLRR U(0xA14)
+#define RCC_MP_AHB2ENSETR U(0xA18)
+#define RCC_MP_AHB2ENCLRR U(0xA1C)
+#define RCC_MP_AHB3ENSETR U(0xA20)
+#define RCC_MP_AHB3ENCLRR U(0xA24)
+#define RCC_MP_AHB4ENSETR U(0xA28)
+#define RCC_MP_AHB4ENCLRR U(0xA2C)
+#define RCC_MP_MLAHBENSETR U(0xA38)
+#define RCC_MP_MLAHBENCLRR U(0xA3C)
+#define RCC_MP_APB1LPENSETR U(0xB00)
+#define RCC_MP_APB1LPENCLRR U(0xB04)
+#define RCC_MP_APB2LPENSETR U(0xB08)
+#define RCC_MP_APB2LPENCLRR U(0xB0C)
+#define RCC_MP_APB3LPENSETR U(0xB10)
+#define RCC_MP_APB3LPENCLRR U(0xB14)
+#define RCC_MP_AHB2LPENSETR U(0xB18)
+#define RCC_MP_AHB2LPENCLRR U(0xB1C)
+#define RCC_MP_AHB3LPENSETR U(0xB20)
+#define RCC_MP_AHB3LPENCLRR U(0xB24)
+#define RCC_MP_AHB4LPENSETR U(0xB28)
+#define RCC_MP_AHB4LPENCLRR U(0xB2C)
+#define RCC_MP_AXIMLPENSETR U(0xB30)
+#define RCC_MP_AXIMLPENCLRR U(0xB34)
+#define RCC_MP_MLAHBLPENSETR U(0xB38)
+#define RCC_MP_MLAHBLPENCLRR U(0xB3C)
+#define RCC_VERR U(0xFF4)
+#define RCC_IDR U(0xFF8)
+#define RCC_SIDR U(0xFFC)
+
+/* Values for RCC_TZCR register */
+#define RCC_TZCR_TZEN BIT(0)
+
+/* Used for most of RCC_<x>SELR registers */
+#define RCC_SELR_SRC_MASK GENMASK(2, 0)
+#define RCC_SELR_REFCLK_SRC_MASK GENMASK(1, 0)
+#define RCC_SELR_SRCRDY BIT(31)
+
+/* Values of RCC_MPCKSELR register */
+#define RCC_MPCKSELR_HSI 0x00000000
+#define RCC_MPCKSELR_HSE 0x00000001
+#define RCC_MPCKSELR_PLL 0x00000002
+#define RCC_MPCKSELR_PLL_MPUDIV 0x00000003
+
+/* Values of RCC_ASSCKSELR register */
+#define RCC_ASSCKSELR_HSI 0x00000000
+#define RCC_ASSCKSELR_HSE 0x00000001
+#define RCC_ASSCKSELR_PLL 0x00000002
+
+/* Values of RCC_MSSCKSELR register */
+#define RCC_MSSCKSELR_HSI 0x00000000
+#define RCC_MSSCKSELR_HSE 0x00000001
+#define RCC_MSSCKSELR_CSI 0x00000002
+#define RCC_MSSCKSELR_PLL 0x00000003
+
+/* Values of RCC_CPERCKSELR register */
+#define RCC_CPERCKSELR_HSI 0x00000000
+#define RCC_CPERCKSELR_CSI 0x00000001
+#define RCC_CPERCKSELR_HSE 0x00000002
+
+/* Used for most of DIVR register: max div for RTC */
+#define RCC_DIVR_DIV_MASK GENMASK(5, 0)
+#define RCC_DIVR_DIVRDY BIT(31)
+
+/* Masks for specific DIVR registers */
+#define RCC_APBXDIV_MASK GENMASK(2, 0)
+#define RCC_MPUDIV_MASK GENMASK(2, 0)
+#define RCC_AXIDIV_MASK GENMASK(2, 0)
+
+/* Offset between RCC_MP_xxxENSETR and RCC_MP_xxxENCLRR registers */
+#define RCC_MP_ENCLRR_OFFSET U(4)
+
+/* Fields of RCC_BDCR register */
+#define RCC_BDCR_LSEON BIT(0)
+#define RCC_BDCR_LSEBYP BIT(1)
+#define RCC_BDCR_LSERDY BIT(2)
+#define RCC_BDCR_LSEDRV_MASK GENMASK(5, 4)
+#define RCC_BDCR_LSEDRV_SHIFT 4
+#define RCC_BDCR_LSECSSON BIT(8)
+#define RCC_BDCR_RTCCKEN BIT(20)
+#define RCC_BDCR_RTCSRC_MASK GENMASK(17, 16)
+#define RCC_BDCR_RTCSRC_SHIFT 16
+#define RCC_BDCR_VSWRST BIT(31)
+
+/* Fields of RCC_RDLSICR register */
+#define RCC_RDLSICR_LSION BIT(0)
+#define RCC_RDLSICR_LSIRDY BIT(1)
+
+/* Used for all RCC_PLL<n>CR registers */
+#define RCC_PLLNCR_PLLON BIT(0)
+#define RCC_PLLNCR_PLLRDY BIT(1)
+#define RCC_PLLNCR_DIVPEN BIT(4)
+#define RCC_PLLNCR_DIVQEN BIT(5)
+#define RCC_PLLNCR_DIVREN BIT(6)
+#define RCC_PLLNCR_DIVEN_SHIFT 4
+
+/* Used for all RCC_PLL<n>CFGR1 registers */
+#define RCC_PLLNCFGR1_DIVM_SHIFT 16
+#define RCC_PLLNCFGR1_DIVM_MASK GENMASK(21, 16)
+#define RCC_PLLNCFGR1_DIVN_SHIFT 0
+#define RCC_PLLNCFGR1_DIVN_MASK GENMASK(8, 0)
+/* Only for PLL3 and PLL4 */
+#define RCC_PLLNCFGR1_IFRGE_SHIFT 24
+#define RCC_PLLNCFGR1_IFRGE_MASK GENMASK(25, 24)
+
+/* Used for all RCC_PLL<n>CFGR2 registers */
+#define RCC_PLLNCFGR2_DIVX_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVP_SHIFT 0
+#define RCC_PLLNCFGR2_DIVP_MASK GENMASK(6, 0)
+#define RCC_PLLNCFGR2_DIVQ_SHIFT 8
+#define RCC_PLLNCFGR2_DIVQ_MASK GENMASK(14, 8)
+#define RCC_PLLNCFGR2_DIVR_SHIFT 16
+#define RCC_PLLNCFGR2_DIVR_MASK GENMASK(22, 16)
+
+/* Used for all RCC_PLL<n>FRACR registers */
+#define RCC_PLLNFRACR_FRACV_SHIFT 3
+#define RCC_PLLNFRACR_FRACV_MASK GENMASK(15, 3)
+#define RCC_PLLNFRACR_FRACLE BIT(16)
+
+/* Used for all RCC_PLL<n>CSGR registers */
+#define RCC_PLLNCSGR_INC_STEP_SHIFT 16
+#define RCC_PLLNCSGR_INC_STEP_MASK GENMASK(30, 16)
+#define RCC_PLLNCSGR_MOD_PER_SHIFT 0
+#define RCC_PLLNCSGR_MOD_PER_MASK GENMASK(12, 0)
+#define RCC_PLLNCSGR_SSCG_MODE_SHIFT 15
+#define RCC_PLLNCSGR_SSCG_MODE_MASK BIT(15)
+
+/* Used for RCC_OCENSETR and RCC_OCENCLRR registers */
+#define RCC_OCENR_HSION BIT(0)
+#define RCC_OCENR_CSION BIT(4)
+#define RCC_OCENR_HSEON BIT(8)
+#define RCC_OCENR_HSEBYP BIT(10)
+#define RCC_OCENR_HSECSSON BIT(11)
+
+/* Fields of RCC_OCRDYR register */
+#define RCC_OCRDYR_HSIRDY BIT(0)
+#define RCC_OCRDYR_HSIDIVRDY BIT(2)
+#define RCC_OCRDYR_CSIRDY BIT(4)
+#define RCC_OCRDYR_HSERDY BIT(8)
+
+/* Fields of RCC_DDRITFCR register */
+#define RCC_DDRITFCR_DDRC1EN BIT(0)
+#define RCC_DDRITFCR_DDRC1LPEN BIT(1)
+#define RCC_DDRITFCR_DDRC2EN BIT(2)
+#define RCC_DDRITFCR_DDRC2LPEN BIT(3)
+#define RCC_DDRITFCR_DDRPHYCEN BIT(4)
+#define RCC_DDRITFCR_DDRPHYCLPEN BIT(5)
+#define RCC_DDRITFCR_DDRCAPBEN BIT(6)
+#define RCC_DDRITFCR_DDRCAPBLPEN BIT(7)
+#define RCC_DDRITFCR_AXIDCGEN BIT(8)
+#define RCC_DDRITFCR_DDRPHYCAPBEN BIT(9)
+#define RCC_DDRITFCR_DDRPHYCAPBLPEN BIT(10)
+#define RCC_DDRITFCR_DDRCAPBRST BIT(14)
+#define RCC_DDRITFCR_DDRCAXIRST BIT(15)
+#define RCC_DDRITFCR_DDRCORERST BIT(16)
+#define RCC_DDRITFCR_DPHYAPBRST BIT(17)
+#define RCC_DDRITFCR_DPHYRST BIT(18)
+#define RCC_DDRITFCR_DPHYCTLRST BIT(19)
+#define RCC_DDRITFCR_DDRCKMOD_MASK GENMASK(22, 20)
+#define RCC_DDRITFCR_DDRCKMOD_SHIFT 20
+#define RCC_DDRITFCR_DDRCKMOD_SSR 0
+#define RCC_DDRITFCR_DDRCKMOD_ASR1 BIT(20)
+#define RCC_DDRITFCR_DDRCKMOD_HSR1 BIT(21)
+#define RCC_DDRITFCR_GSKPCTRL BIT(24)
+
+/* Fields of RCC_HSICFGR register */
+#define RCC_HSICFGR_HSIDIV_MASK GENMASK(1, 0)
+
+/* Used for RCC_MCO related operations */
+#define RCC_MCOCFG_MCOON BIT(12)
+#define RCC_MCOCFG_MCODIV_MASK GENMASK(7, 4)
+#define RCC_MCOCFG_MCODIV_SHIFT 4
+#define RCC_MCOCFG_MCOSRC_MASK GENMASK(2, 0)
+
+/* Fields of RCC_DBGCFGR register */
+#define RCC_DBGCFGR_DBGCKEN BIT(8)
+
+/* RCC register fields for reset reasons */
+#define RCC_MP_RSTSCLRR_PORRSTF BIT(0)
+#define RCC_MP_RSTSCLRR_BORRSTF BIT(1)
+#define RCC_MP_RSTSCLRR_PADRSTF BIT(2)
+#define RCC_MP_RSTSCLRR_HCSSRSTF BIT(3)
+#define RCC_MP_RSTSCLRR_VCORERSTF BIT(4)
+#define RCC_MP_RSTSCLRR_MPSYSRSTF BIT(6)
+#define RCC_MP_RSTSCLRR_IWDG1RSTF BIT(8)
+#define RCC_MP_RSTSCLRR_IWDG2RSTF BIT(9)
+#define RCC_MP_RSTSCLRR_STDBYRSTF BIT(11)
+#define RCC_MP_RSTSCLRR_CSTDBYRSTF BIT(12)
+
+/* Global Reset Register */
+#define RCC_MP_GRSTCSETR_MPSYSRST BIT(0)
+
+/* Clock Source Interrupt Flag Register */
+#define RCC_MP_CIFR_MASK U(0x110F1F)
+#define RCC_MP_CIFR_WKUPF BIT(20)
+
+/* Stop Request Set Register */
+#define RCC_MP_SREQSETR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQSETR_STPREQ_P1 BIT(1)
+
+/* Stop Request Clear Register */
+#define RCC_MP_SREQCLRR_STPREQ_P0 BIT(0)
+#define RCC_MP_SREQCLRR_STPREQ_P1 BIT(1)
+
+/* Values of RCC_UART24CKSELR register */
+#define RCC_UART24CKSELR_HSI 0x00000002
+
+/* Values of RCC_MP_APB1ENSETR register */
+#define RCC_MP_APB1ENSETR_UART4EN BIT(16)
+
+/* Values of RCC_MP_AHB4ENSETR register */
+#define RCC_MP_AHB4ENSETR_GPIOGEN BIT(6)
+
+#endif /* __STM32MP1_RCC_H__ */
diff --git a/include/drivers/st/stm32mp1_reset.h b/include/drivers/st/stm32mp1_reset.h
new file mode 100644
index 000000000..76ee09d8d
--- /dev/null
+++ b/include/drivers/st/stm32mp1_reset.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_RESET_H__
+#define __STM32MP1_RESET_H__
+
+#include <stdint.h>
+
+void stm32mp1_reset_assert(uint32_t reset_id);
+void stm32mp1_reset_deassert(uint32_t reset_id);
+
+#endif /* __STM32MP1_RESET_H__ */
diff --git a/include/drivers/st/stpmu1.h b/include/drivers/st/stpmu1.h
new file mode 100644
index 000000000..1b93ab2c7
--- /dev/null
+++ b/include/drivers/st/stpmu1.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2016-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __STPMU1_H__
+#define __STPMU1_H__
+
+#include <stm32_i2c.h>
+#include <utils_def.h>
+
+#define TURN_ON_REG 0x1U
+#define TURN_OFF_REG 0x2U
+#define ICC_LDO_TURN_OFF_REG 0x3U
+#define ICC_BUCK_TURN_OFF_REG 0x4U
+#define RESET_STATUS_REG 0x5U
+#define VERSION_STATUS_REG 0x6U
+#define MAIN_CONTROL_REG 0x10U
+#define PADS_PULL_REG 0x11U
+#define BUCK_PULL_DOWN_REG 0x12U
+#define LDO14_PULL_DOWN_REG 0x13U
+#define LDO56_PULL_DOWN_REG 0x14U
+#define VIN_CONTROL_REG 0x15U
+#define PONKEY_TIMER_REG 0x16U
+#define MASK_RANK_BUCK_REG 0x17U
+#define MASK_RESET_BUCK_REG 0x18U
+#define MASK_RANK_LDO_REG 0x19U
+#define MASK_RESET_LDO_REG 0x1AU
+#define WATCHDOG_CONTROL_REG 0x1BU
+#define WATCHDOG_TIMER_REG 0x1CU
+#define BUCK_ICC_TURNOFF_REG 0x1DU
+#define LDO_ICC_TURNOFF_REG 0x1EU
+#define BUCK_APM_CONTROL_REG 0x1FU
+#define BUCK1_CONTROL_REG 0x20U
+#define BUCK2_CONTROL_REG 0x21U
+#define BUCK3_CONTROL_REG 0x22U
+#define BUCK4_CONTROL_REG 0x23U
+#define VREF_DDR_CONTROL_REG 0x24U
+#define LDO1_CONTROL_REG 0x25U
+#define LDO2_CONTROL_REG 0x26U
+#define LDO3_CONTROL_REG 0x27U
+#define LDO4_CONTROL_REG 0x28U
+#define LDO5_CONTROL_REG 0x29U
+#define LDO6_CONTROL_REG 0x2AU
+#define BUCK1_PWRCTRL_REG 0x30U
+#define BUCK2_PWRCTRL_REG 0x31U
+#define BUCK3_PWRCTRL_REG 0x32U
+#define BUCK4_PWRCTRL_REG 0x33U
+#define VREF_DDR_PWRCTRL_REG 0x34U
+#define LDO1_PWRCTRL_REG 0x35U
+#define LDO2_PWRCTRL_REG 0x36U
+#define LDO3_PWRCTRL_REG 0x37U
+#define LDO4_PWRCTRL_REG 0x38U
+#define LDO5_PWRCTRL_REG 0x39U
+#define LDO6_PWRCTRL_REG 0x3AU
+#define FREQUENCY_SPREADING_REG 0x3BU
+#define USB_CONTROL_REG 0x40U
+#define ITLATCH1_REG 0x50U
+#define ITLATCH2_REG 0x51U
+#define ITLATCH3_REG 0x52U
+#define ITLATCH4_REG 0x53U
+#define ITSETLATCH1_REG 0x60U
+#define ITSETLATCH2_REG 0x61U
+#define ITSETLATCH3_REG 0x62U
+#define ITSETLATCH4_REG 0x63U
+#define ITCLEARLATCH1_REG 0x70U
+#define ITCLEARLATCH2_REG 0x71U
+#define ITCLEARLATCH3_REG 0x72U
+#define ITCLEARLATCH4_REG 0x73U
+#define ITMASK1_REG 0x80U
+#define ITMASK2_REG 0x81U
+#define ITMASK3_REG 0x82U
+#define ITMASK4_REG 0x83U
+#define ITSETMASK1_REG 0x90U
+#define ITSETMASK2_REG 0x91U
+#define ITSETMASK3_REG 0x92U
+#define ITSETMASK4_REG 0x93U
+#define ITCLEARMASK1_REG 0xA0U
+#define ITCLEARMASK2_REG 0xA1U
+#define ITCLEARMASK3_REG 0xA2U
+#define ITCLEARMASK4_REG 0xA3U
+#define ITSOURCE1_REG 0xB0U
+#define ITSOURCE2_REG 0xB1U
+#define ITSOURCE3_REG 0xB2U
+#define ITSOURCE4_REG 0xB3U
+#define LDO_VOLTAGE_MASK 0x7CU
+#define BUCK_VOLTAGE_MASK 0xFCU
+#define LDO_BUCK_VOLTAGE_SHIFT 2
+#define LDO_ENABLE_MASK 0x01U
+#define BUCK_ENABLE_MASK 0x01U
+#define BUCK_HPLP_ENABLE_MASK 0x02U
+#define LDO_HPLP_ENABLE_MASK 0x02U
+#define LDO_BUCK_HPLP_SHIFT 1
+#define LDO_BUCK_RANK_MASK 0x01U
+#define LDO_BUCK_RESET_MASK 0x01U
+#define LDO_BUCK_PULL_DOWN_MASK 0x03U
+
+/* Main PMIC Control Register (MAIN_CONTROL_REG) */
+#define ICC_EVENT_ENABLED BIT(4)
+#define PWRCTRL_POLARITY_HIGH BIT(3)
+#define PWRCTRL_PIN_VALID BIT(2)
+#define RESTART_REQUEST_ENABLED BIT(1)
+#define SOFTWARE_SWITCH_OFF_ENABLED BIT(0)
+
+/* Main PMIC PADS Control Register (PADS_PULL_REG) */
+#define WAKEUP_DETECTOR_DISABLED BIT(4)
+#define PWRCTRL_PD_ACTIVE BIT(3)
+#define PWRCTRL_PU_ACTIVE BIT(2)
+#define WAKEUP_PD_ACTIVE BIT(1)
+#define PONKEY_PU_ACTIVE BIT(0)
+
+/* Main PMIC VINLOW Control Register (VIN_CONTROL_REGC DMSC) */
+#define SWIN_DETECTOR_ENABLED BIT(7)
+#define SWOUT_DETECTOR_ENABLED BIT(6)
+#define VINLOW_HYST_MASK 0x3
+#define VINLOW_HYST_SHIFT 4
+#define VINLOW_THRESHOLD_MASK 0x7
+#define VINLOW_THRESHOLD_SHIFT 1
+#define VINLOW_ENABLED 0x01
+#define VINLOW_CTRL_REG_MASK 0xFF
+
+/* USB Control Register */
+#define BOOST_OVP_DISABLED BIT(7)
+#define VBUS_OTG_DETECTION_DISABLED BIT(6)
+#define OCP_LIMIT_HIGH BIT(3)
+#define SWIN_SWOUT_ENABLED BIT(2)
+#define USBSW_OTG_SWITCH_ENABLED BIT(1)
+
+int stpmu1_switch_off(void);
+int stpmu1_register_read(uint8_t register_id, uint8_t *value);
+int stpmu1_register_write(uint8_t register_id, uint8_t value);
+int stpmu1_register_update(uint8_t register_id, uint8_t value, uint8_t mask);
+int stpmu1_regulator_enable(const char *name);
+int stpmu1_regulator_disable(const char *name);
+uint8_t stpmu1_is_regulator_enabled(const char *name);
+int stpmu1_regulator_voltage_set(const char *name, uint16_t millivolts);
+void stpmu1_bind_i2c(struct i2c_handle_s *i2c_handle, uint16_t i2c_addr);
+
+#endif /* __STPMU1_H__ */
diff --git a/include/drivers/synopsys/dw_mmc.h b/include/drivers/synopsys/dw_mmc.h
index 4e6b348ac..1ec8d1da8 100644
--- a/include/drivers/synopsys/dw_mmc.h
+++ b/include/drivers/synopsys/dw_mmc.h
@@ -7,6 +7,8 @@
#ifndef __DW_MMC_H__
#define __DW_MMC_H__
+#include <mmc.h>
+
typedef struct dw_mmc_params {
uintptr_t reg_base;
uintptr_t desc_base;
@@ -16,6 +18,6 @@ typedef struct dw_mmc_params {
unsigned int flags;
} dw_mmc_params_t;
-void dw_mmc_init(dw_mmc_params_t *params);
+void dw_mmc_init(dw_mmc_params_t *params, struct mmc_device_info *info);
#endif /* __DW_MMC_H__ */
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index b00f66421..9ee2a336f 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -75,7 +75,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct {
console_t console;
diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
new file mode 100644
index 000000000..18bdb57f3
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -0,0 +1,251 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
+#define _DT_BINDINGS_STM32MP1_CLKS_H_
+
+/* OSCILLATOR clocks */
+#define CK_HSE 0
+#define CK_CSI 1
+#define CK_LSI 2
+#define CK_LSE 3
+#define CK_HSI 4
+#define CK_HSE_DIV2 5
+
+/* Bus clocks */
+#define TIM2 6
+#define TIM3 7
+#define TIM4 8
+#define TIM5 9
+#define TIM6 10
+#define TIM7 11
+#define TIM12 12
+#define TIM13 13
+#define TIM14 14
+#define LPTIM1 15
+#define SPI2 16
+#define SPI3 17
+#define USART2 18
+#define USART3 19
+#define UART4 20
+#define UART5 21
+#define UART7 22
+#define UART8 23
+#define I2C1 24
+#define I2C2 25
+#define I2C3 26
+#define I2C5 27
+#define SPDIF 28
+#define CEC 29
+#define DAC12 30
+#define MDIO 31
+#define TIM1 32
+#define TIM8 33
+#define TIM15 34
+#define TIM16 35
+#define TIM17 36
+#define SPI1 37
+#define SPI4 38
+#define SPI5 39
+#define USART6 40
+#define SAI1 41
+#define SAI2 42
+#define SAI3 43
+#define DFSDM 44
+#define FDCAN 45
+#define LPTIM2 46
+#define LPTIM3 47
+#define LPTIM4 48
+#define LPTIM5 49
+#define SAI4 50
+#define SYSCFG 51
+#define VREF 52
+#define TMPSENS 53
+#define PMBCTRL 54
+#define HDP 55
+#define LTDC 56
+#define DSI 57
+#define IWDG2 58
+#define USBPHY 59
+#define STGENRO 60
+#define SPI6 61
+#define I2C4 62
+#define I2C6 63
+#define USART1 64
+#define RTCAPB 65
+#define TZC1 66
+#define TZPC 67
+#define IWDG1 68
+#define BSEC 69
+#define STGEN 70
+#define DMA1 71
+#define DMA2 72
+#define DMAMUX 73
+#define ADC12 74
+#define USBO 75
+#define SDMMC3 76
+#define DCMI 77
+#define CRYP2 78
+#define HASH2 79
+#define RNG2 80
+#define CRC2 81
+#define HSEM 82
+#define IPCC 83
+#define GPIOA 84
+#define GPIOB 85
+#define GPIOC 86
+#define GPIOD 87
+#define GPIOE 88
+#define GPIOF 89
+#define GPIOG 90
+#define GPIOH 91
+#define GPIOI 92
+#define GPIOJ 93
+#define GPIOK 94
+#define GPIOZ 95
+#define CRYP1 96
+#define HASH1 97
+#define RNG1 98
+#define BKPSRAM 99
+#define MDMA 100
+#define GPU 101
+#define ETHCK 102
+#define ETHTX 103
+#define ETHRX 104
+#define ETHMAC 105
+#define FMC 106
+#define QSPI 107
+#define SDMMC1 108
+#define SDMMC2 109
+#define CRC1 110
+#define USBH 111
+#define ETHSTP 112
+#define TZC2 113
+
+/* Kernel clocks */
+#define SDMMC1_K 118
+#define SDMMC2_K 119
+#define SDMMC3_K 120
+#define FMC_K 121
+#define QSPI_K 122
+#define ETHCK_K 123
+#define RNG1_K 124
+#define RNG2_K 125
+#define GPU_K 126
+#define USBPHY_K 127
+#define STGEN_K 128
+#define SPDIF_K 129
+#define SPI1_K 130
+#define SPI2_K 131
+#define SPI3_K 132
+#define SPI4_K 133
+#define SPI5_K 134
+#define SPI6_K 135
+#define CEC_K 136
+#define I2C1_K 137
+#define I2C2_K 138
+#define I2C3_K 139
+#define I2C4_K 140
+#define I2C5_K 141
+#define I2C6_K 142
+#define LPTIM1_K 143
+#define LPTIM2_K 144
+#define LPTIM3_K 145
+#define LPTIM4_K 146
+#define LPTIM5_K 147
+#define USART1_K 148
+#define USART2_K 149
+#define USART3_K 150
+#define UART4_K 151
+#define UART5_K 152
+#define USART6_K 153
+#define UART7_K 154
+#define UART8_K 155
+#define DFSDM_K 156
+#define FDCAN_K 157
+#define SAI1_K 158
+#define SAI2_K 159
+#define SAI3_K 160
+#define SAI4_K 161
+#define ADC12_K 162
+#define DSI_K 163
+#define DSI_PX 164
+#define ADFSDM_K 165
+#define USBO_K 166
+#define LTDC_PX 167
+#define DAC12_K 168
+#define ETHPTP_K 169
+
+/* PLL */
+#define PLL1 176
+#define PLL2 177
+#define PLL3 178
+#define PLL4 179
+
+/* ODF */
+#define PLL1_P 180
+#define PLL1_Q 181
+#define PLL1_R 182
+#define PLL2_P 183
+#define PLL2_Q 184
+#define PLL2_R 185
+#define PLL3_P 186
+#define PLL3_Q 187
+#define PLL3_R 188
+#define PLL4_P 189
+#define PLL4_Q 190
+#define PLL4_R 191
+
+/* AUX */
+#define RTC 192
+
+/* MCLK */
+#define CK_PER 193
+#define CK_MPU 194
+#define CK_AXI 195
+#define CK_MCU 196
+
+/* Time base */
+#define TIM2_K 197
+#define TIM3_K 198
+#define TIM4_K 199
+#define TIM5_K 200
+#define TIM6_K 201
+#define TIM7_K 202
+#define TIM12_K 203
+#define TIM13_K 204
+#define TIM14_K 205
+#define TIM1_K 206
+#define TIM8_K 207
+#define TIM15_K 208
+#define TIM16_K 209
+#define TIM17_K 210
+
+/* MCO clocks */
+#define CK_MCO1 211
+#define CK_MCO2 212
+
+/* TRACE & DEBUG clocks */
+#define CK_DBG 214
+#define CK_TRACE 215
+
+/* DDR */
+#define DDRC1 220
+#define DDRC1LP 221
+#define DDRC2 222
+#define DDRC2LP 223
+#define DDRPHYC 224
+#define DDRPHYCLP 225
+#define DDRCAPB 226
+#define DDRCAPBLP 227
+#define AXIDCG 228
+#define DDRPHYCAPB 229
+#define DDRPHYCAPBLP 230
+#define DDRPERFM 231
+
+#define STM32MP1_LAST_CLK 232
+
+#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
diff --git a/include/dt-bindings/clock/stm32mp1-clksrc.h b/include/dt-bindings/clock/stm32mp1-clksrc.h
new file mode 100644
index 000000000..818f4b768
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clksrc.h
@@ -0,0 +1,283 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2017, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
+#define _DT_BINDINGS_CLOCK_STM32MP1_CLKSRC_H_
+
+/* PLL output is enable when x=1, with x=p,q or r */
+#define PQR(p, q, r) (((p) & 1) | (((q) & 1) << 1) | (((r) & 1) << 2))
+
+/* st,clksrc: mandatory clock source */
+
+#define CLK_MPU_HSI 0x00000200
+#define CLK_MPU_HSE 0x00000201
+#define CLK_MPU_PLL1P 0x00000202
+#define CLK_MPU_PLL1P_DIV 0x00000203
+
+#define CLK_AXI_HSI 0x00000240
+#define CLK_AXI_HSE 0x00000241
+#define CLK_AXI_PLL2P 0x00000242
+
+#define CLK_MCU_HSI 0x00000480
+#define CLK_MCU_HSE 0x00000481
+#define CLK_MCU_CSI 0x00000482
+#define CLK_MCU_PLL3P 0x00000483
+
+#define CLK_PLL12_HSI 0x00000280
+#define CLK_PLL12_HSE 0x00000281
+
+#define CLK_PLL3_HSI 0x00008200
+#define CLK_PLL3_HSE 0x00008201
+#define CLK_PLL3_CSI 0x00008202
+
+#define CLK_PLL4_HSI 0x00008240
+#define CLK_PLL4_HSE 0x00008241
+#define CLK_PLL4_CSI 0x00008242
+#define CLK_PLL4_I2SCKIN 0x00008243
+
+#define CLK_RTC_DISABLED 0x00001400
+#define CLK_RTC_LSE 0x00001401
+#define CLK_RTC_LSI 0x00001402
+#define CLK_RTC_HSE 0x00001403
+
+#define CLK_MCO1_HSI 0x00008000
+#define CLK_MCO1_HSE 0x00008001
+#define CLK_MCO1_CSI 0x00008002
+#define CLK_MCO1_LSI 0x00008003
+#define CLK_MCO1_LSE 0x00008004
+#define CLK_MCO1_DISABLED 0x0000800F
+
+#define CLK_MCO2_MPU 0x00008040
+#define CLK_MCO2_AXI 0x00008041
+#define CLK_MCO2_MCU 0x00008042
+#define CLK_MCO2_PLL4P 0x00008043
+#define CLK_MCO2_HSE 0x00008044
+#define CLK_MCO2_HSI 0x00008045
+#define CLK_MCO2_DISABLED 0x0000804F
+
+/* st,pkcs: peripheral kernel clock source */
+
+#define CLK_I2C12_PCLK1 0x00008C00
+#define CLK_I2C12_PLL4R 0x00008C01
+#define CLK_I2C12_HSI 0x00008C02
+#define CLK_I2C12_CSI 0x00008C03
+#define CLK_I2C12_DISABLED 0x00008C07
+
+#define CLK_I2C35_PCLK1 0x00008C40
+#define CLK_I2C35_PLL4R 0x00008C41
+#define CLK_I2C35_HSI 0x00008C42
+#define CLK_I2C35_CSI 0x00008C43
+#define CLK_I2C35_DISABLED 0x00008C47
+
+#define CLK_I2C46_PCLK5 0x00000C00
+#define CLK_I2C46_PLL3Q 0x00000C01
+#define CLK_I2C46_HSI 0x00000C02
+#define CLK_I2C46_CSI 0x00000C03
+#define CLK_I2C46_DISABLED 0x00000C07
+
+#define CLK_SAI1_PLL4Q 0x00008C80
+#define CLK_SAI1_PLL3Q 0x00008C81
+#define CLK_SAI1_I2SCKIN 0x00008C82
+#define CLK_SAI1_CKPER 0x00008C83
+#define CLK_SAI1_PLL3R 0x00008C84
+#define CLK_SAI1_DISABLED 0x00008C87
+
+#define CLK_SAI2_PLL4Q 0x00008CC0
+#define CLK_SAI2_PLL3Q 0x00008CC1
+#define CLK_SAI2_I2SCKIN 0x00008CC2
+#define CLK_SAI2_CKPER 0x00008CC3
+#define CLK_SAI2_SPDIF 0x00008CC4
+#define CLK_SAI2_PLL3R 0x00008CC5
+#define CLK_SAI2_DISABLED 0x00008CC7
+
+#define CLK_SAI3_PLL4Q 0x00008D00
+#define CLK_SAI3_PLL3Q 0x00008D01
+#define CLK_SAI3_I2SCKIN 0x00008D02
+#define CLK_SAI3_CKPER 0x00008D03
+#define CLK_SAI3_PLL3R 0x00008D04
+#define CLK_SAI3_DISABLED 0x00008D07
+
+#define CLK_SAI4_PLL4Q 0x00008D40
+#define CLK_SAI4_PLL3Q 0x00008D41
+#define CLK_SAI4_I2SCKIN 0x00008D42
+#define CLK_SAI4_CKPER 0x00008D43
+#define CLK_SAI4_PLL3R 0x00008D44
+#define CLK_SAI4_DISABLED 0x00008D47
+
+#define CLK_SPI2S1_PLL4P 0x00008D80
+#define CLK_SPI2S1_PLL3Q 0x00008D81
+#define CLK_SPI2S1_I2SCKIN 0x00008D82
+#define CLK_SPI2S1_CKPER 0x00008D83
+#define CLK_SPI2S1_PLL3R 0x00008D84
+#define CLK_SPI2S1_DISABLED 0x00008D87
+
+#define CLK_SPI2S23_PLL4P 0x00008DC0
+#define CLK_SPI2S23_PLL3Q 0x00008DC1
+#define CLK_SPI2S23_I2SCKIN 0x00008DC2
+#define CLK_SPI2S23_CKPER 0x00008DC3
+#define CLK_SPI2S23_PLL3R 0x00008DC4
+#define CLK_SPI2S23_DISABLED 0x00008DC7
+
+#define CLK_SPI45_PCLK2 0x00008E00
+#define CLK_SPI45_PLL4Q 0x00008E01
+#define CLK_SPI45_HSI 0x00008E02
+#define CLK_SPI45_CSI 0x00008E03
+#define CLK_SPI45_HSE 0x00008E04
+#define CLK_SPI45_DISABLED 0x00008E07
+
+#define CLK_SPI6_PCLK5 0x00000C40
+#define CLK_SPI6_PLL4Q 0x00000C41
+#define CLK_SPI6_HSI 0x00000C42
+#define CLK_SPI6_CSI 0x00000C43
+#define CLK_SPI6_HSE 0x00000C44
+#define CLK_SPI6_PLL3Q 0x00000C45
+#define CLK_SPI6_DISABLED 0x00000C47
+
+#define CLK_UART6_PCLK2 0x00008E40
+#define CLK_UART6_PLL4Q 0x00008E41
+#define CLK_UART6_HSI 0x00008E42
+#define CLK_UART6_CSI 0x00008E43
+#define CLK_UART6_HSE 0x00008E44
+#define CLK_UART6_DISABLED 0x00008E47
+
+#define CLK_UART24_PCLK1 0x00008E80
+#define CLK_UART24_PLL4Q 0x00008E81
+#define CLK_UART24_HSI 0x00008E82
+#define CLK_UART24_CSI 0x00008E83
+#define CLK_UART24_HSE 0x00008E84
+#define CLK_UART24_DISABLED 0x00008E87
+
+#define CLK_UART35_PCLK1 0x00008EC0
+#define CLK_UART35_PLL4Q 0x00008EC1
+#define CLK_UART35_HSI 0x00008EC2
+#define CLK_UART35_CSI 0x00008EC3
+#define CLK_UART35_HSE 0x00008EC4
+#define CLK_UART35_DISABLED 0x00008EC7
+
+#define CLK_UART78_PCLK1 0x00008F00
+#define CLK_UART78_PLL4Q 0x00008F01
+#define CLK_UART78_HSI 0x00008F02
+#define CLK_UART78_CSI 0x00008F03
+#define CLK_UART78_HSE 0x00008F04
+#define CLK_UART78_DISABLED 0x00008F07
+
+#define CLK_UART1_PCLK5 0x00000C80
+#define CLK_UART1_PLL3Q 0x00000C81
+#define CLK_UART1_HSI 0x00000C82
+#define CLK_UART1_CSI 0x00000C83
+#define CLK_UART1_PLL4Q 0x00000C84
+#define CLK_UART1_HSE 0x00000C85
+#define CLK_UART1_DISABLED 0x00000C87
+
+#define CLK_SDMMC12_HCLK6 0x00008F40
+#define CLK_SDMMC12_PLL3R 0x00008F41
+#define CLK_SDMMC12_PLL4P 0x00008F42
+#define CLK_SDMMC12_HSI 0x00008F43
+#define CLK_SDMMC12_DISABLED 0x00008F47
+
+#define CLK_SDMMC3_HCLK2 0x00008F80
+#define CLK_SDMMC3_PLL3R 0x00008F81
+#define CLK_SDMMC3_PLL4P 0x00008F82
+#define CLK_SDMMC3_HSI 0x00008F83
+#define CLK_SDMMC3_DISABLED 0x00008F87
+
+#define CLK_ETH_PLL4P 0x00008FC0
+#define CLK_ETH_PLL3Q 0x00008FC1
+#define CLK_ETH_DISABLED 0x00008FC3
+
+#define CLK_QSPI_ACLK 0x00009000
+#define CLK_QSPI_PLL3R 0x00009001
+#define CLK_QSPI_PLL4P 0x00009002
+#define CLK_QSPI_CKPER 0x00009003
+
+#define CLK_FMC_ACLK 0x00009040
+#define CLK_FMC_PLL3R 0x00009041
+#define CLK_FMC_PLL4P 0x00009042
+#define CLK_FMC_CKPER 0x00009043
+
+#define CLK_FDCAN_HSE 0x000090C0
+#define CLK_FDCAN_PLL3Q 0x000090C1
+#define CLK_FDCAN_PLL4Q 0x000090C2
+#define CLK_FDCAN_PLL4R 0x000090C3
+
+#define CLK_SPDIF_PLL4P 0x00009140
+#define CLK_SPDIF_PLL3Q 0x00009141
+#define CLK_SPDIF_HSI 0x00009142
+#define CLK_SPDIF_DISABLED 0x00009143
+
+#define CLK_CEC_LSE 0x00009180
+#define CLK_CEC_LSI 0x00009181
+#define CLK_CEC_CSI_DIV122 0x00009182
+#define CLK_CEC_DISABLED 0x00009183
+
+#define CLK_USBPHY_HSE 0x000091C0
+#define CLK_USBPHY_PLL4R 0x000091C1
+#define CLK_USBPHY_HSE_DIV2 0x000091C2
+#define CLK_USBPHY_DISABLED 0x000091C3
+
+#define CLK_USBO_PLL4R 0x800091C0
+#define CLK_USBO_USBPHY 0x800091C1
+
+#define CLK_RNG1_CSI 0x00000CC0
+#define CLK_RNG1_PLL4R 0x00000CC1
+#define CLK_RNG1_LSE 0x00000CC2
+#define CLK_RNG1_LSI 0x00000CC3
+
+#define CLK_RNG2_CSI 0x00009200
+#define CLK_RNG2_PLL4R 0x00009201
+#define CLK_RNG2_LSE 0x00009202
+#define CLK_RNG2_LSI 0x00009203
+
+#define CLK_CKPER_HSI 0x00000D00
+#define CLK_CKPER_CSI 0x00000D01
+#define CLK_CKPER_HSE 0x00000D02
+#define CLK_CKPER_DISABLED 0x00000D03
+
+#define CLK_STGEN_HSI 0x00000D40
+#define CLK_STGEN_HSE 0x00000D41
+#define CLK_STGEN_DISABLED 0x00000D43
+
+#define CLK_DSI_DSIPLL 0x00009240
+#define CLK_DSI_PLL4P 0x00009241
+
+#define CLK_ADC_PLL4R 0x00009280
+#define CLK_ADC_CKPER 0x00009281
+#define CLK_ADC_PLL3Q 0x00009282
+#define CLK_ADC_DISABLED 0x00009283
+
+#define CLK_LPTIM45_PCLK3 0x000092C0
+#define CLK_LPTIM45_PLL4P 0x000092C1
+#define CLK_LPTIM45_PLL3Q 0x000092C2
+#define CLK_LPTIM45_LSE 0x000092C3
+#define CLK_LPTIM45_LSI 0x000092C4
+#define CLK_LPTIM45_CKPER 0x000092C5
+#define CLK_LPTIM45_DISABLED 0x000092C7
+
+#define CLK_LPTIM23_PCLK3 0x00009300
+#define CLK_LPTIM23_PLL4Q 0x00009301
+#define CLK_LPTIM23_CKPER 0x00009302
+#define CLK_LPTIM23_LSE 0x00009303
+#define CLK_LPTIM23_LSI 0x00009304
+#define CLK_LPTIM23_DISABLED 0x00009307
+
+#define CLK_LPTIM1_PCLK1 0x00009340
+#define CLK_LPTIM1_PLL4P 0x00009341
+#define CLK_LPTIM1_PLL3Q 0x00009342
+#define CLK_LPTIM1_LSE 0x00009343
+#define CLK_LPTIM1_LSI 0x00009344
+#define CLK_LPTIM1_CKPER 0x00009345
+#define CLK_LPTIM1_DISABLED 0x00009347
+
+/* define for st,pll /csg */
+#define SSCG_MODE_CENTER_SPREAD 0
+#define SSCG_MODE_DOWN_SPREAD 1
+
+/* define for st,drive */
+#define LSEDRV_LOWEST 0
+#define LSEDRV_MEDIUM_LOW 1
+#define LSEDRV_MEDIUM_HIGH 2
+#define LSEDRV_HIGHEST 3
+
+#endif
diff --git a/include/dt-bindings/pinctrl/stm32-pinfunc.h b/include/dt-bindings/pinctrl/stm32-pinfunc.h
new file mode 100644
index 000000000..e2f1f1b44
--- /dev/null
+++ b/include/dt-bindings/pinctrl/stm32-pinfunc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) */
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Torgue Alexandre <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32_PINFUNC_H
+#define _DT_BINDINGS_STM32_PINFUNC_H
+
+/* define PIN modes */
+#define GPIO 0x0
+#define AF0 0x1
+#define AF1 0x2
+#define AF2 0x3
+#define AF3 0x4
+#define AF4 0x5
+#define AF5 0x6
+#define AF6 0x7
+#define AF7 0x8
+#define AF8 0x9
+#define AF9 0xa
+#define AF10 0xb
+#define AF11 0xc
+#define AF12 0xd
+#define AF13 0xe
+#define AF14 0xf
+#define AF15 0x10
+#define ANALOG 0x11
+
+/* define Pins number*/
+#define PIN_NO(port, line) (((port) - 'A') * 0x10 + (line))
+
+#define STM32_PINMUX(port, line, mode) (((PIN_NO(port, line)) << 8) | (mode))
+
+#endif /* _DT_BINDINGS_STM32_PINFUNC_H */
diff --git a/include/dt-bindings/reset/stm32mp1-resets.h b/include/dt-bindings/reset/stm32mp1-resets.h
new file mode 100644
index 000000000..f0c3aaef6
--- /dev/null
+++ b/include/dt-bindings/reset/stm32mp1-resets.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_RESET_H_
+#define _DT_BINDINGS_STM32MP1_RESET_H_
+
+#define LTDC_R 3072
+#define DSI_R 3076
+#define DDRPERFM_R 3080
+#define USBPHY_R 3088
+#define SPI6_R 3136
+#define I2C4_R 3138
+#define I2C6_R 3139
+#define USART1_R 3140
+#define STGEN_R 3156
+#define GPIOZ_R 3200
+#define CRYP1_R 3204
+#define HASH1_R 3205
+#define RNG1_R 3206
+#define AXIM_R 3216
+#define GPU_R 3269
+#define ETHMAC_R 3274
+#define FMC_R 3276
+#define QSPI_R 3278
+#define SDMMC1_R 3280
+#define SDMMC2_R 3281
+#define CRC1_R 3284
+#define USBH_R 3288
+#define MDMA_R 3328
+#define MCU_R 8225
+#define TIM2_R 19456
+#define TIM3_R 19457
+#define TIM4_R 19458
+#define TIM5_R 19459
+#define TIM6_R 19460
+#define TIM7_R 19461
+#define TIM12_R 16462
+#define TIM13_R 16463
+#define TIM14_R 16464
+#define LPTIM1_R 19465
+#define SPI2_R 19467
+#define SPI3_R 19468
+#define USART2_R 19470
+#define USART3_R 19471
+#define UART4_R 19472
+#define UART5_R 19473
+#define UART7_R 19474
+#define UART8_R 19475
+#define I2C1_R 19477
+#define I2C2_R 19478
+#define I2C3_R 19479
+#define I2C5_R 19480
+#define SPDIF_R 19482
+#define CEC_R 19483
+#define DAC12_R 19485
+#define MDIO_R 19847
+#define TIM1_R 19520
+#define TIM8_R 19521
+#define TIM15_R 19522
+#define TIM16_R 19523
+#define TIM17_R 19524
+#define SPI1_R 19528
+#define SPI4_R 19529
+#define SPI5_R 19530
+#define USART6_R 19533
+#define SAI1_R 19536
+#define SAI2_R 19537
+#define SAI3_R 19538
+#define DFSDM_R 19540
+#define FDCAN_R 19544
+#define LPTIM2_R 19584
+#define LPTIM3_R 19585
+#define LPTIM4_R 19586
+#define LPTIM5_R 19587
+#define SAI4_R 19592
+#define SYSCFG_R 19595
+#define VREF_R 19597
+#define TMPSENS_R 19600
+#define PMBCTRL_R 19601
+#define DMA1_R 19648
+#define DMA2_R 19649
+#define DMAMUX_R 19650
+#define ADC12_R 19653
+#define USBO_R 19656
+#define SDMMC3_R 19664
+#define CAMITF_R 19712
+#define CRYP2_R 19716
+#define HASH2_R 19717
+#define RNG2_R 19718
+#define CRC2_R 19719
+#define HSEM_R 19723
+#define MBOX_R 19724
+#define GPIOA_R 19776
+#define GPIOB_R 19777
+#define GPIOC_R 19778
+#define GPIOD_R 19779
+#define GPIOE_R 19780
+#define GPIOF_R 19781
+#define GPIOG_R 19782
+#define GPIOH_R 19783
+#define GPIOI_R 19784
+#define GPIOJ_R 19785
+#define GPIOK_R 19786
+
+#endif /* _DT_BINDINGS_STM32MP1_RESET_H_ */
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index a940b63b5..f9ed56e29 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -12,31 +12,31 @@
/*******************************************************************************
* MIDR bit definitions
******************************************************************************/
-#define MIDR_IMPL_MASK 0xff
-#define MIDR_IMPL_SHIFT 24
-#define MIDR_VAR_SHIFT 20
-#define MIDR_VAR_BITS 4
-#define MIDR_REV_SHIFT 0
-#define MIDR_REV_BITS 4
-#define MIDR_PN_MASK 0xfff
-#define MIDR_PN_SHIFT 4
+#define MIDR_IMPL_MASK U(0xff)
+#define MIDR_IMPL_SHIFT U(24)
+#define MIDR_VAR_SHIFT U(20)
+#define MIDR_VAR_BITS U(4)
+#define MIDR_REV_SHIFT U(0)
+#define MIDR_REV_BITS U(4)
+#define MIDR_PN_MASK U(0xfff)
+#define MIDR_PN_SHIFT U(4)
/*******************************************************************************
* MPIDR macros
******************************************************************************/
-#define MPIDR_MT_MASK (1 << 24)
+#define MPIDR_MT_MASK (U(1) << 24)
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
-#define MPIDR_AFFINITY_BITS 8
-#define MPIDR_AFFLVL_MASK 0xff
-#define MPIDR_AFFLVL_SHIFT 3
-#define MPIDR_AFF0_SHIFT 0
-#define MPIDR_AFF1_SHIFT 8
-#define MPIDR_AFF2_SHIFT 16
-#define MPIDR_AFFINITY_MASK 0x00ffffff
-#define MPIDR_AFFLVL0 0
-#define MPIDR_AFFLVL1 1
-#define MPIDR_AFFLVL2 2
+#define MPIDR_AFFINITY_BITS U(8)
+#define MPIDR_AFFLVL_MASK U(0xff)
+#define MPIDR_AFFLVL_SHIFT U(3)
+#define MPIDR_AFF0_SHIFT U(0)
+#define MPIDR_AFF1_SHIFT U(8)
+#define MPIDR_AFF2_SHIFT U(16)
+#define MPIDR_AFFINITY_MASK U(0x00ffffff)
+#define MPIDR_AFFLVL0 U(0)
+#define MPIDR_AFFLVL1 U(1)
+#define MPIDR_AFFLVL2 U(2)
#define MPIDR_AFFLVL0_VAL(mpidr) \
(((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
@@ -44,39 +44,39 @@
(((mpidr) >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK)
#define MPIDR_AFFLVL2_VAL(mpidr) \
(((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
-#define MPIDR_AFFLVL3_VAL(mpidr) 0
+#define MPIDR_AFFLVL3_VAL(mpidr) U(0)
/*
* The MPIDR_MAX_AFFLVL count starts from 0. Take care to
* add one while using this macro to define array sizes.
*/
-#define MPIDR_MAX_AFFLVL 2
+#define MPIDR_MAX_AFFLVL U(2)
/* Data Cache set/way op type defines */
-#define DC_OP_ISW 0x0
-#define DC_OP_CISW 0x1
-#define DC_OP_CSW 0x2
+#define DC_OP_ISW U(0x0)
+#define DC_OP_CISW U(0x1)
+#define DC_OP_CSW U(0x2)
/*******************************************************************************
* Generic timer memory mapped registers & offsets
******************************************************************************/
-#define CNTCR_OFF 0x000
-#define CNTFID_OFF 0x020
+#define CNTCR_OFF U(0x000)
+#define CNTFID_OFF U(0x020)
-#define CNTCR_EN (1 << 0)
-#define CNTCR_HDBG (1 << 1)
+#define CNTCR_EN (U(1) << 0)
+#define CNTCR_HDBG (U(1) << 1)
#define CNTCR_FCREQ(x) ((x) << 8)
/*******************************************************************************
* System register bit definitions
******************************************************************************/
/* CLIDR definitions */
-#define LOUIS_SHIFT 21
-#define LOC_SHIFT 24
-#define CLIDR_FIELD_WIDTH 3
+#define LOUIS_SHIFT U(21)
+#define LOC_SHIFT U(24)
+#define CLIDR_FIELD_WIDTH U(3)
/* CSSELR definitions */
-#define LEVEL_SHIFT 1
+#define LEVEL_SHIFT U(1)
/* ID_PFR0 definitions */
#define ID_PFR0_AMU_SHIFT U(20)
@@ -84,184 +84,185 @@
#define ID_PFR0_AMU_MASK U(0xf)
/* ID_PFR1 definitions */
-#define ID_PFR1_VIRTEXT_SHIFT 12
-#define ID_PFR1_VIRTEXT_MASK 0xf
+#define ID_PFR1_VIRTEXT_SHIFT U(12)
+#define ID_PFR1_VIRTEXT_MASK U(0xf)
#define GET_VIRT_EXT(id) (((id) >> ID_PFR1_VIRTEXT_SHIFT) \
& ID_PFR1_VIRTEXT_MASK)
-#define ID_PFR1_GIC_SHIFT 28
-#define ID_PFR1_GIC_MASK 0xf
+#define ID_PFR1_GIC_SHIFT U(28)
+#define ID_PFR1_GIC_MASK U(0xf)
/* SCTLR definitions */
-#define SCTLR_RES1_DEF ((1 << 23) | (1 << 22) | (1 << 4) | (1 << 3))
+#define SCTLR_RES1_DEF ((U(1) << 23) | (U(1) << 22) | (U(1) << 4) | \
+ (U(1) << 3))
#if ARM_ARCH_MAJOR == 7
#define SCTLR_RES1 SCTLR_RES1_DEF
#else
-#define SCTLR_RES1 (SCTLR_RES1_DEF | (1 << 11))
+#define SCTLR_RES1 (SCTLR_RES1_DEF | (U(1) << 11))
#endif
-#define SCTLR_M_BIT (1 << 0)
-#define SCTLR_A_BIT (1 << 1)
-#define SCTLR_C_BIT (1 << 2)
-#define SCTLR_CP15BEN_BIT (1 << 5)
-#define SCTLR_ITD_BIT (1 << 7)
-#define SCTLR_Z_BIT (1 << 11)
-#define SCTLR_I_BIT (1 << 12)
-#define SCTLR_V_BIT (1 << 13)
-#define SCTLR_RR_BIT (1 << 14)
-#define SCTLR_NTWI_BIT (1 << 16)
-#define SCTLR_NTWE_BIT (1 << 18)
-#define SCTLR_WXN_BIT (1 << 19)
-#define SCTLR_UWXN_BIT (1 << 20)
-#define SCTLR_EE_BIT (1 << 25)
-#define SCTLR_TRE_BIT (1 << 28)
-#define SCTLR_AFE_BIT (1 << 29)
-#define SCTLR_TE_BIT (1 << 30)
+#define SCTLR_M_BIT (U(1) << 0)
+#define SCTLR_A_BIT (U(1) << 1)
+#define SCTLR_C_BIT (U(1) << 2)
+#define SCTLR_CP15BEN_BIT (U(1) << 5)
+#define SCTLR_ITD_BIT (U(1) << 7)
+#define SCTLR_Z_BIT (U(1) << 11)
+#define SCTLR_I_BIT (U(1) << 12)
+#define SCTLR_V_BIT (U(1) << 13)
+#define SCTLR_RR_BIT (U(1) << 14)
+#define SCTLR_NTWI_BIT (U(1) << 16)
+#define SCTLR_NTWE_BIT (U(1) << 18)
+#define SCTLR_WXN_BIT (U(1) << 19)
+#define SCTLR_UWXN_BIT (U(1) << 20)
+#define SCTLR_EE_BIT (U(1) << 25)
+#define SCTLR_TRE_BIT (U(1) << 28)
+#define SCTLR_AFE_BIT (U(1) << 29)
+#define SCTLR_TE_BIT (U(1) << 30)
#define SCTLR_RESET_VAL (SCTLR_RES1 | SCTLR_NTWE_BIT | \
SCTLR_NTWI_BIT | SCTLR_CP15BEN_BIT)
/* SDCR definitions */
#define SDCR_SPD(x) ((x) << 14)
-#define SDCR_SPD_LEGACY 0x0
-#define SDCR_SPD_DISABLE 0x2
-#define SDCR_SPD_ENABLE 0x3
-#define SDCR_RESET_VAL 0x0
+#define SDCR_SPD_LEGACY U(0x0)
+#define SDCR_SPD_DISABLE U(0x2)
+#define SDCR_SPD_ENABLE U(0x3)
+#define SDCR_RESET_VAL U(0x0)
#if !ERROR_DEPRECATED
#define SDCR_DEF_VAL SDCR_SPD(SDCR_SPD_DISABLE)
#endif
/* HSCTLR definitions */
-#define HSCTLR_RES1 ((1 << 29) | (1 << 28) | (1 << 23) | (1 << 22) \
- | (1 << 18) | (1 << 16) | (1 << 11) | (1 << 4) \
- | (1 << 3))
-#define HSCTLR_M_BIT (1 << 0)
-#define HSCTLR_A_BIT (1 << 1)
-#define HSCTLR_C_BIT (1 << 2)
-#define HSCTLR_CP15BEN_BIT (1 << 5)
-#define HSCTLR_ITD_BIT (1 << 7)
-#define HSCTLR_SED_BIT (1 << 8)
-#define HSCTLR_I_BIT (1 << 12)
-#define HSCTLR_WXN_BIT (1 << 19)
-#define HSCTLR_EE_BIT (1 << 25)
-#define HSCTLR_TE_BIT (1 << 30)
+#define HSCTLR_RES1 ((U(1) << 29) | (U(1) << 28) | (U(1) << 23) | \
+ (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
+ (U(1) << 11) | (U(1) << 4) | (U(1) << 3))
+
+#define HSCTLR_M_BIT (U(1) << 0)
+#define HSCTLR_A_BIT (U(1) << 1)
+#define HSCTLR_C_BIT (U(1) << 2)
+#define HSCTLR_CP15BEN_BIT (U(1) << 5)
+#define HSCTLR_ITD_BIT (U(1) << 7)
+#define HSCTLR_SED_BIT (U(1) << 8)
+#define HSCTLR_I_BIT (U(1) << 12)
+#define HSCTLR_WXN_BIT (U(1) << 19)
+#define HSCTLR_EE_BIT (U(1) << 25)
+#define HSCTLR_TE_BIT (U(1) << 30)
/* CPACR definitions */
-#define CPACR_FPEN(x) ((x) << 20)
-#define CPACR_FP_TRAP_PL0 0x1
-#define CPACR_FP_TRAP_ALL 0x2
-#define CPACR_FP_TRAP_NONE 0x3
+#define CPACR_FPEN(x) ((x) << 20)
+#define CPACR_FP_TRAP_PL0 U(0x1)
+#define CPACR_FP_TRAP_ALL U(0x2)
+#define CPACR_FP_TRAP_NONE U(0x3)
/* SCR definitions */
-#define SCR_TWE_BIT (1 << 13)
-#define SCR_TWI_BIT (1 << 12)
-#define SCR_SIF_BIT (1 << 9)
-#define SCR_HCE_BIT (1 << 8)
-#define SCR_SCD_BIT (1 << 7)
-#define SCR_NET_BIT (1 << 6)
-#define SCR_AW_BIT (1 << 5)
-#define SCR_FW_BIT (1 << 4)
-#define SCR_EA_BIT (1 << 3)
-#define SCR_FIQ_BIT (1 << 2)
-#define SCR_IRQ_BIT (1 << 1)
-#define SCR_NS_BIT (1 << 0)
-#define SCR_VALID_BIT_MASK 0x33ff
-#define SCR_RESET_VAL 0x0
+#define SCR_TWE_BIT (U(1) << 13)
+#define SCR_TWI_BIT (U(1) << 12)
+#define SCR_SIF_BIT (U(1) << 9)
+#define SCR_HCE_BIT (U(1) << 8)
+#define SCR_SCD_BIT (U(1) << 7)
+#define SCR_NET_BIT (U(1) << 6)
+#define SCR_AW_BIT (U(1) << 5)
+#define SCR_FW_BIT (U(1) << 4)
+#define SCR_EA_BIT (U(1) << 3)
+#define SCR_FIQ_BIT (U(1) << 2)
+#define SCR_IRQ_BIT (U(1) << 1)
+#define SCR_NS_BIT (U(1) << 0)
+#define SCR_VALID_BIT_MASK U(0x33ff)
+#define SCR_RESET_VAL U(0x0)
#define GET_NS_BIT(scr) ((scr) & SCR_NS_BIT)
/* HCR definitions */
-#define HCR_AMO_BIT (1 << 5)
-#define HCR_IMO_BIT (1 << 4)
-#define HCR_FMO_BIT (1 << 3)
-#define HCR_RESET_VAL 0x0
+#define HCR_AMO_BIT (U(1) << 5)
+#define HCR_IMO_BIT (U(1) << 4)
+#define HCR_FMO_BIT (U(1) << 3)
+#define HCR_RESET_VAL U(0x0)
/* CNTHCTL definitions */
-#define CNTHCTL_RESET_VAL 0x0
-#define PL1PCEN_BIT (1 << 1)
-#define PL1PCTEN_BIT (1 << 0)
+#define CNTHCTL_RESET_VAL U(0x0)
+#define PL1PCEN_BIT (U(1) << 1)
+#define PL1PCTEN_BIT (U(1) << 0)
/* CNTKCTL definitions */
-#define PL0PTEN_BIT (1 << 9)
-#define PL0VTEN_BIT (1 << 8)
-#define PL0PCTEN_BIT (1 << 0)
-#define PL0VCTEN_BIT (1 << 1)
-#define EVNTEN_BIT (1 << 2)
-#define EVNTDIR_BIT (1 << 3)
-#define EVNTI_SHIFT 4
-#define EVNTI_MASK 0xf
+#define PL0PTEN_BIT (U(1) << 9)
+#define PL0VTEN_BIT (U(1) << 8)
+#define PL0PCTEN_BIT (U(1) << 0)
+#define PL0VCTEN_BIT (U(1) << 1)
+#define EVNTEN_BIT (U(1) << 2)
+#define EVNTDIR_BIT (U(1) << 3)
+#define EVNTI_SHIFT U(4)
+#define EVNTI_MASK U(0xf)
/* HCPTR definitions */
-#define HCPTR_RES1 ((1 << 13) | (1<<12) | 0x3ff)
-#define TCPAC_BIT (1 << 31)
-#define TAM_BIT (1 << 30)
-#define TTA_BIT (1 << 20)
-#define TCP11_BIT (1 << 10)
-#define TCP10_BIT (1 << 10)
+#define HCPTR_RES1 ((U(1) << 13) | (U(1) << 12) | U(0x3ff))
+#define TCPAC_BIT (U(1) << 31)
+#define TAM_BIT (U(1) << 30)
+#define TTA_BIT (U(1) << 20)
+#define TCP11_BIT (U(1) << 11)
+#define TCP10_BIT (U(1) << 10)
#define HCPTR_RESET_VAL HCPTR_RES1
/* VTTBR defintions */
#define VTTBR_RESET_VAL ULL(0x0)
#define VTTBR_VMID_MASK ULL(0xff)
-#define VTTBR_VMID_SHIFT 48
-#define VTTBR_BADDR_MASK 0xffffffffffff
-#define VTTBR_BADDR_SHIFT 0
+#define VTTBR_VMID_SHIFT U(48)
+#define VTTBR_BADDR_MASK ULL(0xffffffffffff)
+#define VTTBR_BADDR_SHIFT U(0)
/* HDCR definitions */
-#define HDCR_RESET_VAL 0x0
+#define HDCR_RESET_VAL U(0x0)
/* HSTR definitions */
-#define HSTR_RESET_VAL 0x0
+#define HSTR_RESET_VAL U(0x0)
/* CNTHP_CTL definitions */
-#define CNTHP_CTL_RESET_VAL 0x0
+#define CNTHP_CTL_RESET_VAL U(0x0)
/* NASCR definitions */
-#define NSASEDIS_BIT (1 << 15)
-#define NSTRCDIS_BIT (1 << 20)
+#define NSASEDIS_BIT (U(1) << 15)
+#define NSTRCDIS_BIT (U(1) << 20)
/* NOTE: correct typo in the definitions */
#if !ERROR_DEPRECATED
-#define NASCR_CP11_BIT (1 << 11)
-#define NASCR_CP10_BIT (1 << 10)
+#define NASCR_CP11_BIT (U(1) << 11)
+#define NASCR_CP10_BIT (U(1) << 10)
#endif
-#define NSACR_CP11_BIT (1 << 11)
-#define NSACR_CP10_BIT (1 << 10)
-#define NSACR_IMP_DEF_MASK (0x7 << 16)
+#define NSACR_CP11_BIT (U(1) << 11)
+#define NSACR_CP10_BIT (U(1) << 10)
+#define NSACR_IMP_DEF_MASK (U(0x7) << 16)
#define NSACR_ENABLE_FP_ACCESS (NSACR_CP11_BIT | NSACR_CP10_BIT)
-#define NSACR_RESET_VAL 0x0
+#define NSACR_RESET_VAL U(0x0)
/* CPACR definitions */
-#define ASEDIS_BIT (1 << 31)
-#define TRCDIS_BIT (1 << 28)
-#define CPACR_CP11_SHIFT 22
-#define CPACR_CP10_SHIFT 20
-#define CPACR_ENABLE_FP_ACCESS (0x3 << CPACR_CP11_SHIFT |\
- 0x3 << CPACR_CP10_SHIFT)
-#define CPACR_RESET_VAL 0x0
+#define ASEDIS_BIT (U(1) << 31)
+#define TRCDIS_BIT (U(1) << 28)
+#define CPACR_CP11_SHIFT U(22)
+#define CPACR_CP10_SHIFT U(20)
+#define CPACR_ENABLE_FP_ACCESS ((U(0x3) << CPACR_CP11_SHIFT) |\
+ (U(0x3) << CPACR_CP10_SHIFT))
+#define CPACR_RESET_VAL U(0x0)
/* FPEXC definitions */
-#define FPEXC_RES1 ((1 << 10) | (1 << 9) | (1 << 8))
-#define FPEXC_EN_BIT (1 << 30)
+#define FPEXC_RES1 ((U(1) << 10) | (U(1) << 9) | (U(1) << 8))
+#define FPEXC_EN_BIT (U(1) << 30)
#define FPEXC_RESET_VAL FPEXC_RES1
/* SPSR/CPSR definitions */
-#define SPSR_FIQ_BIT (1 << 0)
-#define SPSR_IRQ_BIT (1 << 1)
-#define SPSR_ABT_BIT (1 << 2)
-#define SPSR_AIF_SHIFT 6
-#define SPSR_AIF_MASK 0x7
+#define SPSR_FIQ_BIT (U(1) << 0)
+#define SPSR_IRQ_BIT (U(1) << 1)
+#define SPSR_ABT_BIT (U(1) << 2)
+#define SPSR_AIF_SHIFT U(6)
+#define SPSR_AIF_MASK U(0x7)
-#define SPSR_E_SHIFT 9
-#define SPSR_E_MASK 0x1
-#define SPSR_E_LITTLE 0
-#define SPSR_E_BIG 1
+#define SPSR_E_SHIFT U(9)
+#define SPSR_E_MASK U(0x1)
+#define SPSR_E_LITTLE U(0)
+#define SPSR_E_BIG U(1)
-#define SPSR_T_SHIFT 5
-#define SPSR_T_MASK 0x1
-#define SPSR_T_ARM 0
-#define SPSR_T_THUMB 1
-
-#define SPSR_MODE_SHIFT 0
-#define SPSR_MODE_MASK 0x7
+#define SPSR_T_SHIFT U(5)
+#define SPSR_T_MASK U(0x1)
+#define SPSR_T_ARM U(0)
+#define SPSR_T_THUMB U(1)
+#define SPSR_MODE_SHIFT U(0)
+#define SPSR_MODE_MASK U(0x7)
#define DISABLE_ALL_EXCEPTIONS \
(SPSR_FIQ_BIT | SPSR_IRQ_BIT | SPSR_ABT_BIT)
@@ -270,63 +271,85 @@
* TTBCR definitions
*/
/* The ARM Trusted Firmware uses the long descriptor format */
-#define TTBCR_EAE_BIT (1 << 31)
-
-#define TTBCR_SH1_NON_SHAREABLE (0x0 << 28)
-#define TTBCR_SH1_OUTER_SHAREABLE (0x2 << 28)
-#define TTBCR_SH1_INNER_SHAREABLE (0x3 << 28)
-
-#define TTBCR_RGN1_OUTER_NC (0x0 << 26)
-#define TTBCR_RGN1_OUTER_WBA (0x1 << 26)
-#define TTBCR_RGN1_OUTER_WT (0x2 << 26)
-#define TTBCR_RGN1_OUTER_WBNA (0x3 << 26)
-
-#define TTBCR_RGN1_INNER_NC (0x0 << 24)
-#define TTBCR_RGN1_INNER_WBA (0x1 << 24)
-#define TTBCR_RGN1_INNER_WT (0x2 << 24)
-#define TTBCR_RGN1_INNER_WBNA (0x3 << 24)
-
-#define TTBCR_EPD1_BIT (1 << 23)
-#define TTBCR_A1_BIT (1 << 22)
-
-#define TTBCR_T1SZ_SHIFT 16
-#define TTBCR_T1SZ_MASK (0x7)
-#define TTBCR_TxSZ_MIN 0
-#define TTBCR_TxSZ_MAX 7
-
-#define TTBCR_SH0_NON_SHAREABLE (0x0 << 12)
-#define TTBCR_SH0_OUTER_SHAREABLE (0x2 << 12)
-#define TTBCR_SH0_INNER_SHAREABLE (0x3 << 12)
-
-#define TTBCR_RGN0_OUTER_NC (0x0 << 10)
-#define TTBCR_RGN0_OUTER_WBA (0x1 << 10)
-#define TTBCR_RGN0_OUTER_WT (0x2 << 10)
-#define TTBCR_RGN0_OUTER_WBNA (0x3 << 10)
-
-#define TTBCR_RGN0_INNER_NC (0x0 << 8)
-#define TTBCR_RGN0_INNER_WBA (0x1 << 8)
-#define TTBCR_RGN0_INNER_WT (0x2 << 8)
-#define TTBCR_RGN0_INNER_WBNA (0x3 << 8)
-
-#define TTBCR_EPD0_BIT (1 << 7)
-#define TTBCR_T0SZ_SHIFT 0
-#define TTBCR_T0SZ_MASK (0x7)
-
-#define MODE_RW_SHIFT 0x4
-#define MODE_RW_MASK 0x1
-#define MODE_RW_32 0x1
-
-#define MODE32_SHIFT 0
-#define MODE32_MASK 0x1f
-#define MODE32_usr 0x10
-#define MODE32_fiq 0x11
-#define MODE32_irq 0x12
-#define MODE32_svc 0x13
-#define MODE32_mon 0x16
-#define MODE32_abt 0x17
-#define MODE32_hyp 0x1a
-#define MODE32_und 0x1b
-#define MODE32_sys 0x1f
+#define TTBCR_EAE_BIT (U(1) << 31)
+
+#define TTBCR_SH1_NON_SHAREABLE (U(0x0) << 28)
+#define TTBCR_SH1_OUTER_SHAREABLE (U(0x2) << 28)
+#define TTBCR_SH1_INNER_SHAREABLE (U(0x3) << 28)
+
+#define TTBCR_RGN1_OUTER_NC (U(0x0) << 26)
+#define TTBCR_RGN1_OUTER_WBA (U(0x1) << 26)
+#define TTBCR_RGN1_OUTER_WT (U(0x2) << 26)
+#define TTBCR_RGN1_OUTER_WBNA (U(0x3) << 26)
+
+#define TTBCR_RGN1_INNER_NC (U(0x0) << 24)
+#define TTBCR_RGN1_INNER_WBA (U(0x1) << 24)
+#define TTBCR_RGN1_INNER_WT (U(0x2) << 24)
+#define TTBCR_RGN1_INNER_WBNA (U(0x3) << 24)
+
+#define TTBCR_EPD1_BIT (U(1) << 23)
+#define TTBCR_A1_BIT (U(1) << 22)
+
+#define TTBCR_T1SZ_SHIFT U(16)
+#define TTBCR_T1SZ_MASK U(0x7)
+#define TTBCR_TxSZ_MIN U(0)
+#define TTBCR_TxSZ_MAX U(7)
+
+#define TTBCR_SH0_NON_SHAREABLE (U(0x0) << 12)
+#define TTBCR_SH0_OUTER_SHAREABLE (U(0x2) << 12)
+#define TTBCR_SH0_INNER_SHAREABLE (U(0x3) << 12)
+
+#define TTBCR_RGN0_OUTER_NC (U(0x0) << 10)
+#define TTBCR_RGN0_OUTER_WBA (U(0x1) << 10)
+#define TTBCR_RGN0_OUTER_WT (U(0x2) << 10)
+#define TTBCR_RGN0_OUTER_WBNA (U(0x3) << 10)
+
+#define TTBCR_RGN0_INNER_NC (U(0x0) << 8)
+#define TTBCR_RGN0_INNER_WBA (U(0x1) << 8)
+#define TTBCR_RGN0_INNER_WT (U(0x2) << 8)
+#define TTBCR_RGN0_INNER_WBNA (U(0x3) << 8)
+
+#define TTBCR_EPD0_BIT (U(1) << 7)
+#define TTBCR_T0SZ_SHIFT U(0)
+#define TTBCR_T0SZ_MASK U(0x7)
+
+/*
+ * HTCR definitions
+ */
+#define HTCR_RES1 ((U(1) << 31) | (U(1) << 23))
+
+#define HTCR_SH0_NON_SHAREABLE (U(0x0) << 12)
+#define HTCR_SH0_OUTER_SHAREABLE (U(0x2) << 12)
+#define HTCR_SH0_INNER_SHAREABLE (U(0x3) << 12)
+
+#define HTCR_RGN0_OUTER_NC (U(0x0) << 10)
+#define HTCR_RGN0_OUTER_WBA (U(0x1) << 10)
+#define HTCR_RGN0_OUTER_WT (U(0x2) << 10)
+#define HTCR_RGN0_OUTER_WBNA (U(0x3) << 10)
+
+#define HTCR_RGN0_INNER_NC (U(0x0) << 8)
+#define HTCR_RGN0_INNER_WBA (U(0x1) << 8)
+#define HTCR_RGN0_INNER_WT (U(0x2) << 8)
+#define HTCR_RGN0_INNER_WBNA (U(0x3) << 8)
+
+#define HTCR_T0SZ_SHIFT U(0)
+#define HTCR_T0SZ_MASK U(0x7)
+
+#define MODE_RW_SHIFT U(0x4)
+#define MODE_RW_MASK U(0x1)
+#define MODE_RW_32 U(0x1)
+
+#define MODE32_SHIFT U(0)
+#define MODE32_MASK U(0x1f)
+#define MODE32_usr U(0x10)
+#define MODE32_fiq U(0x11)
+#define MODE32_irq U(0x12)
+#define MODE32_svc U(0x13)
+#define MODE32_mon U(0x16)
+#define MODE32_abt U(0x17)
+#define MODE32_hyp U(0x1a)
+#define MODE32_und U(0x1b)
+#define MODE32_sys U(0x1f)
#define GET_M32(mode) (((mode) >> MODE32_SHIFT) & MODE32_MASK)
@@ -340,39 +363,39 @@
/*
* TTBR definitions
*/
-#define TTBR_CNP_BIT U(0x1)
+#define TTBR_CNP_BIT ULL(0x1)
/*
* CTR definitions
*/
-#define CTR_CWG_SHIFT 24
-#define CTR_CWG_MASK 0xf
-#define CTR_ERG_SHIFT 20
-#define CTR_ERG_MASK 0xf
-#define CTR_DMINLINE_SHIFT 16
-#define CTR_DMINLINE_WIDTH 4
-#define CTR_DMINLINE_MASK ((1 << 4) - 1)
-#define CTR_L1IP_SHIFT 14
-#define CTR_L1IP_MASK 0x3
-#define CTR_IMINLINE_SHIFT 0
-#define CTR_IMINLINE_MASK 0xf
-
-#define MAX_CACHE_LINE_SIZE 0x800 /* 2KB */
+#define CTR_CWG_SHIFT U(24)
+#define CTR_CWG_MASK U(0xf)
+#define CTR_ERG_SHIFT U(20)
+#define CTR_ERG_MASK U(0xf)
+#define CTR_DMINLINE_SHIFT U(16)
+#define CTR_DMINLINE_WIDTH U(4)
+#define CTR_DMINLINE_MASK ((U(1) << 4) - U(1))
+#define CTR_L1IP_SHIFT U(14)
+#define CTR_L1IP_MASK U(0x3)
+#define CTR_IMINLINE_SHIFT U(0)
+#define CTR_IMINLINE_MASK U(0xf)
+
+#define MAX_CACHE_LINE_SIZE U(0x800) /* 2KB */
/* PMCR definitions */
-#define PMCR_N_SHIFT 11
-#define PMCR_N_MASK 0x1f
+#define PMCR_N_SHIFT U(11)
+#define PMCR_N_MASK U(0x1f)
#define PMCR_N_BITS (PMCR_N_MASK << PMCR_N_SHIFT)
-#define PMCR_LC_BIT (1 << 6)
-#define PMCR_DP_BIT (1 << 5)
+#define PMCR_LC_BIT (U(1) << 6)
+#define PMCR_DP_BIT (U(1) << 5)
/*******************************************************************************
* Definitions of register offsets, fields and macros for CPU system
* instructions.
******************************************************************************/
-#define TLBI_ADDR_SHIFT 0
-#define TLBI_ADDR_MASK 0xFFFFF000
+#define TLBI_ADDR_SHIFT U(0)
+#define TLBI_ADDR_MASK U(0xFFFFF000)
#define TLBI_ADDR(x) (((x) >> TLBI_ADDR_SHIFT) & TLBI_ADDR_MASK)
/*******************************************************************************
@@ -380,16 +403,16 @@
* system level implementation of the Generic Timer.
******************************************************************************/
#define CNTCTLBASE_CNTFRQ U(0x0)
-#define CNTNSAR 0x4
+#define CNTNSAR U(0x4)
#define CNTNSAR_NS_SHIFT(x) (x)
-#define CNTACR_BASE(x) (0x40 + ((x) << 2))
-#define CNTACR_RPCT_SHIFT 0x0
-#define CNTACR_RVCT_SHIFT 0x1
-#define CNTACR_RFRQ_SHIFT 0x2
-#define CNTACR_RVOFF_SHIFT 0x3
-#define CNTACR_RWVT_SHIFT 0x4
-#define CNTACR_RWPT_SHIFT 0x5
+#define CNTACR_BASE(x) (U(0x40) + ((x) << 2))
+#define CNTACR_RPCT_SHIFT U(0x0)
+#define CNTACR_RVCT_SHIFT U(0x1)
+#define CNTACR_RFRQ_SHIFT U(0x2)
+#define CNTACR_RVOFF_SHIFT U(0x3)
+#define CNTACR_RWVT_SHIFT U(0x4)
+#define CNTACR_RWPT_SHIFT U(0x5)
/*******************************************************************************
* Definitions of register offsets in the CNTBaseN Frame of the
@@ -399,7 +422,7 @@
/* MAIR macros */
#define MAIR0_ATTR_SET(attr, index) ((attr) << ((index) << 3))
-#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - 3) << 3))
+#define MAIR1_ATTR_SET(attr, index) ((attr) << (((index) - U(3)) << 3))
/* System register defines The format is: coproc, opt1, CRn, CRm, opt2 */
#define SCR p15, 0, c1, c1, 0
@@ -432,6 +455,7 @@
#define TLBIMVA p15, 0, c8, c7, 1
#define TLBIMVAA p15, 0, c8, c7, 3
#define TLBIMVAAIS p15, 0, c8, c3, 3
+#define TLBIMVAHIS p15, 4, c8, c3, 1
#define BPIALLIS p15, 0, c7, c1, 6
#define BPIALL p15, 0, c7, c5, 6
#define ICIALLU p15, 0, c7, c5, 0
@@ -447,6 +471,10 @@
#define CLIDR p15, 1, c0, c0, 1
#define CSSELR p15, 2, c0, c0, 0
#define CCSIDR p15, 1, c0, c0, 0
+#define HTCR p15, 4, c2, c0, 2
+#define HMAIR0 p15, 4, c10, c2, 0
+#define ATS1CPR p15, 0, c7, c8, 0
+#define ATS1HR p15, 4, c7, c8, 0
#define DBGOSDLR p14, 0, c1, c3, 4
/* Debug register defines. The format is: coproc, opt1, CRn, CRm, opt2 */
@@ -486,6 +514,8 @@
#define CNTVOFF_64 p15, 4, c14
#define VTTBR_64 p15, 6, c2
#define CNTPCT_64 p15, 0, c14
+#define HTTBR_64 p15, 4, c2
+#define PAR_64 p15, 0, c7
/* 64 bit GICv3 CPU Interface system register defines. The format is: coproc, opt1, CRm */
#define ICC_SGI1R_EL1_64 p15, 0, c12
@@ -537,9 +567,16 @@
#define MAIR_NORM_WB_NTR_RA U(0xe)
#define MAIR_NORM_WB_NTR_RWA U(0xf)
-#define MAIR_NORM_OUTER_SHIFT 4
+#define MAIR_NORM_OUTER_SHIFT U(4)
+
+#define MAKE_MAIR_NORMAL_MEMORY(inner, outer) \
+ ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
-#define MAKE_MAIR_NORMAL_MEMORY(inner, outer) ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
+/* PAR fields */
+#define PAR_F_SHIFT U(0)
+#define PAR_F_MASK ULL(0x1)
+#define PAR_ADDR_SHIFT U(12)
+#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */
/*******************************************************************************
* Definitions for system register interface to AMU for ARMv8.4 onwards
diff --git a/include/lib/aarch32/arch_helpers.h b/include/lib/aarch32/arch_helpers.h
index beae5d065..6369a5d78 100644
--- a/include/lib/aarch32/arch_helpers.h
+++ b/include/lib/aarch32/arch_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,8 +8,9 @@
#define __ARCH_HELPERS_H__
#include <arch.h> /* for additional register definitions */
+#include <cdefs.h>
#include <stdint.h>
-#include <sys/types.h>
+#include <string.h>
/**********************************************************************
* Macros which create inline functions to read or write CPU system
@@ -275,6 +276,10 @@ DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
+DEFINE_COPROCR_RW_FUNCS(ats1cpr, ATS1CPR)
+DEFINE_COPROCR_RW_FUNCS(ats1hr, ATS1HR)
+DEFINE_COPROCR_RW_FUNCS_64(par, PAR_64)
+
DEFINE_COPROCR_RW_FUNCS(nsacr, NSACR)
/* AArch32 coproc registers for 32bit MMU descriptor support */
@@ -300,6 +305,7 @@ DEFINE_TLBIOP_FUNC(allis, TLBIALLIS)
DEFINE_TLBIOP_PARAM_FUNC(mva, TLBIMVA)
DEFINE_TLBIOP_PARAM_FUNC(mvaa, TLBIMVAA)
DEFINE_TLBIOP_PARAM_FUNC(mvaais, TLBIMVAAIS)
+DEFINE_TLBIOP_PARAM_FUNC(mvahis, TLBIMVAHIS)
/*
* BPI operation prototypes.
@@ -320,6 +326,10 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
#define IS_IN_SECURE() \
(GET_NS_BIT(read_scr()) == 0)
+#define IS_IN_HYP() (GET_M32(read_cpsr()) == MODE32_hyp)
+#define IS_IN_SVC() (GET_M32(read_cpsr()) == MODE32_svc)
+#define IS_IN_MON() (GET_M32(read_cpsr()) == MODE32_mon)
+#define IS_IN_EL2() IS_IN_HYP()
/*
* If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3
*/
@@ -327,6 +337,17 @@ DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
((GET_M32(read_cpsr()) == MODE32_mon) || \
(IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr)))
+static inline unsigned int get_current_el(void)
+{
+ if (IS_IN_EL3()) {
+ return 3U;
+ } else if (IS_IN_EL2()) {
+ return 2U;
+ } else {
+ return 1U;
+ }
+}
+
/* Macros for compatibility with AArch64 system registers */
#define read_mpidr_el1() read_mpidr()
diff --git a/include/lib/aarch32/smccc_helpers.h b/include/lib/aarch32/smccc_helpers.h
index 731c26fbf..d6e525fd4 100644
--- a/include/lib/aarch32/smccc_helpers.h
+++ b/include/lib/aarch32/smccc_helpers.h
@@ -26,7 +26,7 @@
#ifndef __ASSEMBLY__
#include <cassert.h>
-#include <types.h>
+#include <stdint.h>
/*
* The generic structure to save arguments and callee saved registers during
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 7cc4b2377..fed594457 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __ARCH_H__
-#define __ARCH_H__
+#ifndef ARCH_H
+#define ARCH_H
#include <utils_def.h>
@@ -26,29 +26,29 @@
/*******************************************************************************
* MPIDR macros
******************************************************************************/
-#define MPIDR_MT_MASK (U(1) << 24)
+#define MPIDR_MT_MASK (ULL(1) << 24)
#define MPIDR_CPU_MASK MPIDR_AFFLVL_MASK
#define MPIDR_CLUSTER_MASK (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
#define MPIDR_AFFINITY_BITS U(8)
-#define MPIDR_AFFLVL_MASK U(0xff)
+#define MPIDR_AFFLVL_MASK ULL(0xff)
#define MPIDR_AFF0_SHIFT U(0)
#define MPIDR_AFF1_SHIFT U(8)
#define MPIDR_AFF2_SHIFT U(16)
#define MPIDR_AFF3_SHIFT U(32)
-#define MPIDR_AFFINITY_MASK U(0xff00ffffff)
+#define MPIDR_AFFINITY_MASK ULL(0xff00ffffff)
#define MPIDR_AFFLVL_SHIFT U(3)
-#define MPIDR_AFFLVL0 U(0)
-#define MPIDR_AFFLVL1 U(1)
-#define MPIDR_AFFLVL2 U(2)
-#define MPIDR_AFFLVL3 U(3)
+#define MPIDR_AFFLVL0 U(0x0)
+#define MPIDR_AFFLVL1 U(0x1)
+#define MPIDR_AFFLVL2 U(0x2)
+#define MPIDR_AFFLVL3 U(0x3)
#define MPIDR_AFFLVL0_VAL(mpidr) \
- ((mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
+ (((mpidr) >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK)
#define MPIDR_AFFLVL1_VAL(mpidr) \
- ((mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK)
+ (((mpidr) >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK)
#define MPIDR_AFFLVL2_VAL(mpidr) \
- ((mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
+ (((mpidr) >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK)
#define MPIDR_AFFLVL3_VAL(mpidr) \
- ((mpidr >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK)
+ (((mpidr) >> MPIDR_AFF3_SHIFT) & MPIDR_AFFLVL_MASK)
/*
* The MPIDR_MAX_AFFLVL count starts from 0. Take care to
* add one while using this macro to define array sizes.
@@ -57,7 +57,7 @@
#define MPIDR_MAX_AFFLVL U(2)
/* Constant to highlight the assumption that MPIDR allocation starts from 0 */
-#define FIRST_MPIDR U(0)
+#define FIRST_MPIDR ULL(0)
/*******************************************************************************
* Definitions for CPU system register interface to GICv3
@@ -100,7 +100,7 @@
/* CSSELR definitions */
#define LEVEL_SHIFT U(1)
-/* D$ set/way op type defines */
+/* Data cache set/way op type defines */
#define DCISW U(0x0)
#define DCCISW U(0x1)
#define DCCSW U(0x2)
@@ -112,31 +112,33 @@
#define ID_AA64PFR0_EL3_SHIFT U(12)
#define ID_AA64PFR0_AMU_SHIFT U(44)
#define ID_AA64PFR0_AMU_LENGTH U(4)
-#define ID_AA64PFR0_AMU_MASK U(0xf)
-#define ID_AA64PFR0_ELX_MASK U(0xf)
+#define ID_AA64PFR0_AMU_MASK ULL(0xf)
+#define ID_AA64PFR0_ELX_MASK ULL(0xf)
#define ID_AA64PFR0_SVE_SHIFT U(32)
-#define ID_AA64PFR0_SVE_MASK U(0xf)
+#define ID_AA64PFR0_SVE_MASK ULL(0xf)
#define ID_AA64PFR0_SVE_LENGTH U(4)
+#define ID_AA64PFR0_MPAM_SHIFT U(40)
+#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_SHIFT U(56)
-#define ID_AA64PFR0_CSV2_MASK U(0xf)
+#define ID_AA64PFR0_CSV2_MASK ULL(0xf)
#define ID_AA64PFR0_CSV2_LENGTH U(4)
/* ID_AA64DFR0_EL1.PMS definitions (for ARMv8.2+) */
#define ID_AA64DFR0_PMS_SHIFT U(32)
#define ID_AA64DFR0_PMS_LENGTH U(4)
-#define ID_AA64DFR0_PMS_MASK U(0xf)
+#define ID_AA64DFR0_PMS_MASK ULL(0xf)
-#define EL_IMPL_NONE U(0)
-#define EL_IMPL_A64ONLY U(1)
-#define EL_IMPL_A64_A32 U(2)
+#define EL_IMPL_NONE ULL(0)
+#define EL_IMPL_A64ONLY ULL(1)
+#define EL_IMPL_A64_A32 ULL(2)
#define ID_AA64PFR0_GIC_SHIFT U(24)
#define ID_AA64PFR0_GIC_WIDTH U(4)
-#define ID_AA64PFR0_GIC_MASK ((U(1) << ID_AA64PFR0_GIC_WIDTH) - 1)
+#define ID_AA64PFR0_GIC_MASK ((ULL(1) << ID_AA64PFR0_GIC_WIDTH) - ULL(1))
/* ID_AA64MMFR0_EL1 definitions */
#define ID_AA64MMFR0_EL1_PARANGE_SHIFT U(0)
-#define ID_AA64MMFR0_EL1_PARANGE_MASK U(0xf)
+#define ID_AA64MMFR0_EL1_PARANGE_MASK ULL(0xf)
#define PARANGE_0000 U(32)
#define PARANGE_0001 U(36)
@@ -147,24 +149,24 @@
#define PARANGE_0110 U(52)
#define ID_AA64MMFR0_EL1_TGRAN4_SHIFT U(28)
-#define ID_AA64MMFR0_EL1_TGRAN4_MASK U(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED U(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED U(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN4_MASK ULL(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN4_NOT_SUPPORTED ULL(0xf)
#define ID_AA64MMFR0_EL1_TGRAN64_SHIFT U(24)
-#define ID_AA64MMFR0_EL1_TGRAN64_MASK U(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED U(0x0)
-#define ID_AA64MMFR0_EL1_TGRAN64_NOT_SUPPORTED U(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN64_MASK ULL(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED ULL(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN64_NOT_SUPPORTED ULL(0xf)
#define ID_AA64MMFR0_EL1_TGRAN16_SHIFT U(20)
-#define ID_AA64MMFR0_EL1_TGRAN16_MASK U(0xf)
-#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED U(0x1)
-#define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED U(0x0)
+#define ID_AA64MMFR0_EL1_TGRAN16_MASK ULL(0xf)
+#define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED ULL(0x1)
+#define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0)
/* ID_PFR1_EL1 definitions */
#define ID_PFR1_VIRTEXT_SHIFT U(12)
#define ID_PFR1_VIRTEXT_MASK U(0xf)
-#define GET_VIRT_EXT(id) ((id >> ID_PFR1_VIRTEXT_SHIFT) \
+#define GET_VIRT_EXT(id) (((id) >> ID_PFR1_VIRTEXT_SHIFT) \
& ID_PFR1_VIRTEXT_MASK)
/* SCTLR definitions */
@@ -278,9 +280,9 @@
/* HCR definitions */
#define HCR_RW_SHIFT U(31)
#define HCR_RW_BIT (ULL(1) << HCR_RW_SHIFT)
-#define HCR_AMO_BIT (U(1) << 5)
-#define HCR_IMO_BIT (U(1) << 4)
-#define HCR_FMO_BIT (U(1) << 3)
+#define HCR_AMO_BIT (ULL(1) << 5)
+#define HCR_IMO_BIT (ULL(1) << 4)
+#define HCR_FMO_BIT (ULL(1) << 3)
/* ISR definitions */
#define ISR_A_SHIFT U(8)
@@ -364,19 +366,21 @@
* TCR defintions
*/
#define TCR_EL3_RES1 ((U(1) << 31) | (U(1) << 23))
+#define TCR_EL2_RES1 ((ULL(1) << 31) | (ULL(1) << 23))
#define TCR_EL1_IPS_SHIFT U(32)
+#define TCR_EL2_PS_SHIFT U(16)
#define TCR_EL3_PS_SHIFT U(16)
-#define TCR_TxSZ_MIN U(16)
-#define TCR_TxSZ_MAX U(39)
+#define TCR_TxSZ_MIN ULL(16)
+#define TCR_TxSZ_MAX ULL(39)
/* (internal) physical address size bits in EL3/EL1 */
-#define TCR_PS_BITS_4GB U(0x0)
-#define TCR_PS_BITS_64GB U(0x1)
-#define TCR_PS_BITS_1TB U(0x2)
-#define TCR_PS_BITS_4TB U(0x3)
-#define TCR_PS_BITS_16TB U(0x4)
-#define TCR_PS_BITS_256TB U(0x5)
+#define TCR_PS_BITS_4GB ULL(0x0)
+#define TCR_PS_BITS_64GB ULL(0x1)
+#define TCR_PS_BITS_1TB ULL(0x2)
+#define TCR_PS_BITS_4TB ULL(0x3)
+#define TCR_PS_BITS_16TB ULL(0x4)
+#define TCR_PS_BITS_256TB ULL(0x5)
#define ADDR_MASK_48_TO_63 ULL(0xFFFF000000000000)
#define ADDR_MASK_44_TO_47 ULL(0x0000F00000000000)
@@ -385,28 +389,28 @@
#define ADDR_MASK_36_TO_39 ULL(0x000000F000000000)
#define ADDR_MASK_32_TO_35 ULL(0x0000000F00000000)
-#define TCR_RGN_INNER_NC (U(0x0) << 8)
-#define TCR_RGN_INNER_WBA (U(0x1) << 8)
-#define TCR_RGN_INNER_WT (U(0x2) << 8)
-#define TCR_RGN_INNER_WBNA (U(0x3) << 8)
+#define TCR_RGN_INNER_NC (ULL(0x0) << 8)
+#define TCR_RGN_INNER_WBA (ULL(0x1) << 8)
+#define TCR_RGN_INNER_WT (ULL(0x2) << 8)
+#define TCR_RGN_INNER_WBNA (ULL(0x3) << 8)
-#define TCR_RGN_OUTER_NC (U(0x0) << 10)
-#define TCR_RGN_OUTER_WBA (U(0x1) << 10)
-#define TCR_RGN_OUTER_WT (U(0x2) << 10)
-#define TCR_RGN_OUTER_WBNA (U(0x3) << 10)
+#define TCR_RGN_OUTER_NC (ULL(0x0) << 10)
+#define TCR_RGN_OUTER_WBA (ULL(0x1) << 10)
+#define TCR_RGN_OUTER_WT (ULL(0x2) << 10)
+#define TCR_RGN_OUTER_WBNA (ULL(0x3) << 10)
-#define TCR_SH_NON_SHAREABLE (U(0x0) << 12)
-#define TCR_SH_OUTER_SHAREABLE (U(0x2) << 12)
-#define TCR_SH_INNER_SHAREABLE (U(0x3) << 12)
+#define TCR_SH_NON_SHAREABLE (ULL(0x0) << 12)
+#define TCR_SH_OUTER_SHAREABLE (ULL(0x2) << 12)
+#define TCR_SH_INNER_SHAREABLE (ULL(0x3) << 12)
#define TCR_TG0_SHIFT U(14)
-#define TCR_TG0_MASK U(3)
+#define TCR_TG0_MASK ULL(3)
#define TCR_TG0_4K (ULL(0) << TCR_TG0_SHIFT)
#define TCR_TG0_64K (ULL(1) << TCR_TG0_SHIFT)
#define TCR_TG0_16K (ULL(2) << TCR_TG0_SHIFT)
-#define TCR_EPD0_BIT (U(1) << 7)
-#define TCR_EPD1_BIT (U(1) << 23)
+#define TCR_EPD0_BIT (ULL(1) << 7)
+#define TCR_EPD1_BIT (ULL(1) << 23)
#define MODE_SP_SHIFT U(0x0)
#define MODE_SP_MASK U(0x1)
@@ -458,7 +462,7 @@
/*
* TTBR Definitions
*/
-#define TTBR_CNP_BIT 0x1
+#define TTBR_CNP_BIT ULL(0x1)
/*
* CTR_EL0 definitions
@@ -639,15 +643,16 @@
#define MAIR_NORM_WB_NTR_RA ULL(0xe)
#define MAIR_NORM_WB_NTR_RWA ULL(0xf)
-#define MAIR_NORM_OUTER_SHIFT 4
+#define MAIR_NORM_OUTER_SHIFT U(4)
-#define MAKE_MAIR_NORMAL_MEMORY(inner, outer) ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
+#define MAKE_MAIR_NORMAL_MEMORY(inner, outer) \
+ ((inner) | ((outer) << MAIR_NORM_OUTER_SHIFT))
/* PAR_EL1 fields */
-#define PAR_F_SHIFT 0
-#define PAR_F_MASK 1
-#define PAR_ADDR_SHIFT 12
-#define PAR_ADDR_MASK (BIT(40) - 1) /* 40-bits-wide page address */
+#define PAR_F_SHIFT U(0)
+#define PAR_F_MASK ULL(0x1)
+#define PAR_ADDR_SHIFT U(12)
+#define PAR_ADDR_MASK (BIT(40) - ULL(1)) /* 40-bits-wide page address */
/*******************************************************************************
* Definitions for system register interface to SPE
@@ -655,6 +660,14 @@
#define PMBLIMITR_EL1 S3_0_C9_C10_0
/*******************************************************************************
+ * Definitions for system register interface to MPAM
+ ******************************************************************************/
+#define MPAMIDR_EL1 S3_0_C10_C4_4
+#define MPAM2_EL2 S3_4_C10_C5_0
+#define MPAMHCR_EL2 S3_4_C10_C4_0
+#define MPAM3_EL3 S3_6_C10_C5_0
+
+/*******************************************************************************
* Definitions for system register interface to AMU for ARMv8.4 onwards
******************************************************************************/
#define AMCR_EL0 S3_3_C13_C2_0
@@ -719,14 +732,19 @@
#define AMCGCR_EL0_CG1NC_LENGTH U(8)
#define AMCGCR_EL0_CG1NC_MASK U(0xff)
+/* MPAM register definitions */
+#define MPAM3_EL3_MPAMEN_BIT (ULL(1) << 63)
+
+#define MPAMIDR_HAS_HCR_BIT (ULL(1) << 17)
+
/*******************************************************************************
* RAS system registers
*******************************************************************************/
#define DISR_EL1 S3_0_C12_C1_1
-#define DISR_A_BIT 31
+#define DISR_A_BIT U(31)
#define ERRIDR_EL1 S3_0_C5_C3_0
-#define ERRIDR_MASK 0xffff
+#define ERRIDR_MASK U(0xffff)
#define ERRSELR_EL1 S3_0_C5_C3_1
@@ -735,7 +753,7 @@
#define ERXCTLR_EL1 S3_0_C5_C4_1
#define ERXSTATUS_EL1 S3_0_C5_C4_2
#define ERXADDR_EL1 S3_0_C5_C4_3
-#define ERXMISC0_EL1 S3_0_C5_C4_4
-#define ERXMISC1_EL1 S3_0_C5_C4_5
+#define ERXMISC0_EL1 S3_0_C5_C5_0
+#define ERXMISC1_EL1 S3_0_C5_C5_1
-#endif /* __ARCH_H__ */
+#endif /* ARCH_H */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 58ec943a2..d90061f27 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -10,7 +10,7 @@
#include <arch.h> /* for additional register definitions */
#include <cdefs.h> /* For __dead2 */
#include <stdint.h>
-#include <sys/types.h>
+#include <string.h>
/**********************************************************************
* Macros which create inline functions to read or write CPU system
@@ -155,7 +155,9 @@ DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e1w)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s12e0w)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e1r)
DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e2r)
+DEFINE_SYSOP_TYPE_PARAM_FUNC(at, s1e3r)
void flush_dcache_range(uintptr_t addr, size_t size);
void clean_dcache_range(uintptr_t addr, size_t size);
@@ -328,6 +330,11 @@ DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset0_el0, AMCNTENSET0_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenclr1_el0, AMCNTENCLR1_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcntenset1_el0, AMCNTENSET1_EL0)
+DEFINE_RENAME_SYSREG_READ_FUNC(mpamidr_el1, MPAMIDR_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
+DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
+
DEFINE_RENAME_SYSREG_RW_FUNCS(pmblimitr_el1, PMBLIMITR_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(zcr_el3, ZCR_EL3)
@@ -348,6 +355,12 @@ DEFINE_RENAME_SYSREG_READ_FUNC(erxmisc1_el1, ERXMISC1_EL1)
#define IS_IN_EL1() IS_IN_EL(1)
#define IS_IN_EL3() IS_IN_EL(3)
+#define IS_IN_EL3() IS_IN_EL(3)
+
+static inline unsigned int get_current_el(void)
+{
+ return GET_EL(read_CurrentEl());
+}
/*
* Check if an EL is implemented from AA64PFR0 register fields. 'el' argument
diff --git a/include/lib/bakery_lock.h b/include/lib/bakery_lock.h
index d4645c36e..c80082e9b 100644
--- a/include/lib/bakery_lock.h
+++ b/include/lib/bakery_lock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,7 @@
#define BAKERY_LOCK_MAX_CPUS PLATFORM_CORE_COUNT
#ifndef __ASSEMBLY__
+#include <cdefs.h>
#include <stdint.h>
/*****************************************************************************
diff --git a/include/lib/cassert.h b/include/lib/cassert.h
index 40cb483a8..3119e1f80 100644
--- a/include/lib/cassert.h
+++ b/include/lib/cassert.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,8 @@
#ifndef __CASSERT_H__
#define __CASSERT_H__
+#include <cdefs.h>
+
/*******************************************************************************
* Macro to flag a compile time assertion. It uses the preprocessor to generate
* an invalid C construct if 'cond' evaluates to false.
diff --git a/include/lib/coreboot.h b/include/lib/coreboot.h
index 4b1f200a2..f8fbd93d5 100644
--- a/include/lib/coreboot.h
+++ b/include/lib/coreboot.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef __COREBOOT_H__
#define __COREBOOT_H__
-#include <types.h>
+#include <stdint.h>
typedef struct {
uint32_t type; /* always 2 (memory-mapped) on ARM */
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index 9f1847061..f5ca2ee7a 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -38,6 +38,13 @@
#define CORTEX_A72_CPUACTLR_EL1_DIS_INSTR_PREFETCH (ULL(1) << 32)
/*******************************************************************************
+ * L2 Auxiliary Control register specific definitions.
+ ******************************************************************************/
+#define CORTEX_A72_L2ACTLR_EL1 S3_1_C15_C0_0
+
+#define CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN (ULL(1) << 14)
+
+/*******************************************************************************
* L2 Control register specific definitions.
******************************************************************************/
#define CORTEX_A72_L2CTLR_EL1 S3_1_C11_C0_2
diff --git a/include/lib/cpus/aarch64/dsu_def.h b/include/lib/cpus/aarch64/dsu_def.h
new file mode 100644
index 000000000..0e2d93a8c
--- /dev/null
+++ b/include/lib/cpus/aarch64/dsu_def.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DSU_DEF_H
+#define DSU_DEF_H
+
+#include <utils_def.h>
+
+/********************************************************************
+ * DSU control registers definitions *
+ ********************************************************************/
+#define CLUSTERCFR_EL1 S3_0_C15_C3_0
+#define CLUSTERIDR_EL1 S3_0_C15_C3_1
+#define CLUSTERACTLR_EL1 S3_0_C15_C3_3
+
+/********************************************************************
+ * DSU control registers bit fields *
+ ********************************************************************/
+#define CLUSTERIDR_REV_SHIFT U(0)
+#define CLUSTERIDR_REV_BITS U(4)
+#define CLUSTERIDR_VAR_SHIFT U(4)
+#define CLUSTERIDR_VAR_BITS U(4)
+#define CLUSTERCFR_ACP_SHIFT U(11)
+
+/********************************************************************
+ * Masks applied for DSU errata workarounds *
+ ********************************************************************/
+#define DSU_ERRATA_936184_MASK (ULL(0x3) << 15)
+
+#endif /* DSU_DEF_H */
diff --git a/include/lib/el3_runtime/aarch64/context.h b/include/lib/el3_runtime/aarch64/context.h
index a2ce9f828..b990674c7 100644
--- a/include/lib/el3_runtime/aarch64/context.h
+++ b/include/lib/el3_runtime/aarch64/context.h
@@ -241,9 +241,9 @@ DEFINE_REG_STRUCT(cve_2018_3639, CTX_CVE_2018_3639_ALL);
* Macros to access members of any of the above structures using their
* offsets
*/
-#define read_ctx_reg(ctx, offset) ((ctx)->_regs[offset >> DWORD_SHIFT])
-#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[offset >> DWORD_SHIFT]) \
- = val)
+#define read_ctx_reg(ctx, offset) ((ctx)->_regs[(offset) >> DWORD_SHIFT])
+#define write_ctx_reg(ctx, offset, val) (((ctx)->_regs[(offset) >> DWORD_SHIFT]) \
+ = (uint64_t) (val))
/*
* Top-level context structure which is used by EL3 firmware to
diff --git a/include/lib/extensions/amu.h b/include/lib/extensions/amu.h
index 559c8f134..46d5e1593 100644
--- a/include/lib/extensions/amu.h
+++ b/include/lib/extensions/amu.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,6 @@
#include <cassert.h>
#include <platform_def.h>
#include <stdint.h>
-#include <sys/cdefs.h> /* for CASSERT() */
/* All group 0 counters */
#define AMU_GROUP0_COUNTERS_MASK 0xf
diff --git a/include/lib/extensions/mpam.h b/include/lib/extensions/mpam.h
new file mode 100644
index 000000000..571b96b65
--- /dev/null
+++ b/include/lib/extensions/mpam.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MPAM_H
+#define MPAM_H
+
+#include <stdbool.h>
+
+bool mpam_supported(void);
+void mpam_enable(int el2_unused);
+
+#endif /* MPAM_H */
diff --git a/include/lib/extensions/ras.h b/include/lib/extensions/ras.h
index f57fc3afd..400de5925 100644
--- a/include/lib/extensions/ras.h
+++ b/include/lib/extensions/ras.h
@@ -4,10 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __RAS_COMMON__
-#define __RAS_COMMON__
+#ifndef RAS_COMMON
+#define RAS_COMMON
-#define ERR_HANDLER_VERSION 1
+#define ERR_HANDLER_VERSION 1U
/* Error record access mechanism */
#define ERR_ACCESS_SYSREG 0
@@ -20,18 +20,18 @@
* are declared. Only then would ARRAY_SIZE() yield a meaningful value.
*/
#define REGISTER_ERR_RECORD_INFO(_records) \
- const struct err_record_mapping err_record_mapping = { \
- .err_records = _records, \
+ const struct err_record_mapping err_record_mappings = { \
+ .err_records = (_records), \
.num_err_records = ARRAY_SIZE(_records), \
}
/* Error record info iterator */
#define for_each_err_record_info(_i, _info) \
- for (_i = 0, _info = err_record_mapping.err_records; \
- _i < err_record_mapping.num_err_records; \
- _i++, _info++)
+ for ((_i) = 0, (_info) = err_record_mappings.err_records; \
+ (_i) < err_record_mappings.num_err_records; \
+ (_i)++, (_info)++)
-#define _ERR_RECORD_COMMON(_probe, _handler, _aux) \
+#define ERR_RECORD_COMMON_(_probe, _handler, _aux) \
.probe = _probe, \
.handler = _handler, \
.aux_data = _aux,
@@ -42,7 +42,7 @@
.sysreg.idx_start = _idx_start, \
.sysreg.num_idx = _num_idx, \
.access = ERR_ACCESS_SYSREG, \
- _ERR_RECORD_COMMON(_probe, _handler, _aux) \
+ ERR_RECORD_COMMON_(_probe, _handler, _aux) \
}
#define ERR_RECORD_MEMMAP_V1(_base_addr, _size_num_k, _probe, _handler, _aux) \
@@ -51,7 +51,7 @@
.memmap.base_addr = _base_addr, \
.memmap.size_num_k = _size_num_k, \
.access = ERR_ACCESS_MEMMAP, \
- _ERR_RECORD_COMMON(_probe, _handler, _aux) \
+ ERR_RECORD_COMMON_(_probe, _handler, _aux) \
}
/*
@@ -63,8 +63,8 @@
* array is expected to be sorted in the increasing order of interrupt number.
*/
#define REGISTER_RAS_INTERRUPTS(_array) \
- const struct ras_interrupt_mapping ras_interrupt_mapping = { \
- .intrs = _array, \
+ const struct ras_interrupt_mapping ras_interrupt_mappings = { \
+ .intrs = (_array), \
.num_intrs = ARRAY_SIZE(_array), \
}
@@ -165,8 +165,8 @@ struct ras_interrupt_mapping {
size_t num_intrs;
};
-extern const struct err_record_mapping err_record_mapping;
-extern const struct ras_interrupt_mapping ras_interrupt_mapping;
+extern const struct err_record_mapping err_record_mappings;
+extern const struct ras_interrupt_mapping ras_interrupt_mappings;
/*
@@ -196,4 +196,4 @@ int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void ras_init(void);
#endif /* __ASSEMBLY__ */
-#endif /* __RAS_COMMON__ */
+#endif /* RAS_COMMON */
diff --git a/include/lib/extensions/ras_arch.h b/include/lib/extensions/ras_arch.h
index 7d210531b..e6cd736ae 100644
--- a/include/lib/extensions/ras_arch.h
+++ b/include/lib/extensions/ras_arch.h
@@ -4,42 +4,35 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __RAS_H__
-#define __RAS_H__
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <context.h>
-#include <mmio.h>
-#include <stdint.h>
+#ifndef RAS_ARCH_H
+#define RAS_ARCH_H
/*
* Size of nodes implementing Standard Error Records - currently only 4k is
* supported.
*/
-#define STD_ERR_NODE_SIZE_NUM_K 4
+#define STD_ERR_NODE_SIZE_NUM_K 4U
/*
* Individual register offsets within an error record in Standard Error Record
* format when error records are accessed through memory-mapped registers.
*/
-#define ERR_FR(n) (0x0 + (64 * (n)))
-#define ERR_CTLR(n) (0x8 + (64 * (n)))
-#define ERR_STATUS(n) (0x10 + (64 * (n)))
-#define ERR_ADDR(n) (0x18 + (64 * (n)))
-#define ERR_MISC0(n) (0x20 + (64 * (n)))
-#define ERR_MISC1(n) (0x28 + (64 * (n)))
+#define ERR_FR(n) (0x0ULL + (64ULL * (n)))
+#define ERR_CTLR(n) (0x8ULL + (64ULL * (n)))
+#define ERR_STATUS(n) (0x10ULL + (64ULL * (n)))
+#define ERR_ADDR(n) (0x18ULL + (64ULL * (n)))
+#define ERR_MISC0(n) (0x20ULL + (64ULL * (n)))
+#define ERR_MISC1(n) (0x28ULL + (64ULL * (n)))
/* Group Status Register (ERR_STATUS) offset */
#define ERR_GSR(base, size_num_k, n) \
- ((base) + (0x380 * (size_num_k)) + (8 * (n)))
+ ((base) + (0x380ULL * (size_num_k)) + (8ULL * (n)))
/* Management register offsets */
#define ERR_DEVID(base, size_num_k) \
- ((base) + ((0x400 * (size_num_k)) - 0x100) + 0xc8)
+ ((base) + ((0x400ULL * (size_num_k)) - 0x100ULL) + 0xc8ULL)
-#define ERR_DEVID_MASK 0xffff
+#define ERR_DEVID_MASK 0xffffUL
/* Standard Error Record status register fields */
#define ERR_STATUS_AV_SHIFT 31
@@ -146,12 +139,53 @@
#define ERR_CTLR_ENABLE_FIELD(_ctlr, _field) \
ERR_CTLR_SET_FIELD(_ctlr, _field, ERR_CTLR_ ##_field ##_MASK)
-/* Uncorrected error types */
+/* Uncorrected error types for Asynchronous exceptions */
#define ERROR_STATUS_UET_UC 0x0 /* Uncontainable */
#define ERROR_STATUS_UET_UEU 0x1 /* Unrecoverable */
#define ERROR_STATUS_UET_UEO 0x2 /* Restable */
#define ERROR_STATUS_UET_UER 0x3 /* Recoverable */
+/* Error types for Synchronous exceptions */
+#define ERROR_STATUS_SET_UER 0x0 /* Recoverable */
+#define ERROR_STATUS_SET_UEO 0x1 /* Restable */
+#define ERROR_STATUS_SET_UC 0x2 /* Uncontainable */
+#define ERROR_STATUS_SET_CE 0x3 /* Corrected */
+
+/* Implementation Defined Syndrome bit in ESR */
+#define SERROR_IDS_BIT U(24)
+
+/*
+ * Asynchronous Error Type in exception syndrome. The field has same values in
+ * both DISR_EL1 and ESR_EL3 for SError.
+ */
+#define EABORT_AET_SHIFT U(10)
+#define EABORT_AET_WIDTH U(3)
+#define EABORT_AET_MASK U(0x7)
+
+/* DFSC field in Asynchronous exception syndrome */
+#define EABORT_DFSC_SHIFT U(0)
+#define EABORT_DFSC_WIDTH U(6)
+#define EABORT_DFSC_MASK U(0x3f)
+
+/* Synchronous Error Type in exception syndrome. */
+#define EABORT_SET_SHIFT U(11)
+#define EABORT_SET_WIDTH U(2)
+#define EABORT_SET_MASK U(0x3)
+
+/* DFSC code for SErrors */
+#define DFSC_SERROR 0x11
+
+/* I/DFSC code for synchronous external abort */
+#define SYNC_EA_FSC 0x10
+
+#ifndef __ASSEMBLY__
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <context.h>
+#include <mmio.h>
+#include <stdint.h>
/*
* Standard Error Record accessors for memory-mapped registers.
@@ -210,7 +244,8 @@ static inline uint64_t ser_get_misc1(uintptr_t base, unsigned int idx)
*/
static inline void ser_sys_select_record(unsigned int idx)
{
- unsigned int max_idx __unused = read_erridr_el1() & ERRIDR_MASK;
+ unsigned int max_idx __unused =
+ (unsigned int) read_erridr_el1() & ERRIDR_MASK;
assert(idx < max_idx);
@@ -221,5 +256,6 @@ static inline void ser_sys_select_record(unsigned int idx)
/* Library functions to probe Standard Error Record */
int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data);
int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data);
+#endif /* __ASSEMBLY__ */
-#endif /* __RAS_H__ */
+#endif /* RAS_ARCH_H */
diff --git a/include/lib/libc/aarch32/endian_.h b/include/lib/libc/aarch32/endian_.h
new file mode 100644
index 000000000..83a26b723
--- /dev/null
+++ b/include/lib/libc/aarch32/endian_.h
@@ -0,0 +1,146 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2001 David E. O'Brien
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
+ *
+ * @(#)endian.h 8.1 (Berkeley) 6/10/93
+ * $NetBSD: endian.h,v 1.7 1999/08/21 05:53:51 simonb Exp $
+ * $FreeBSD$
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef AARCH32_ENDIAN_H
+#define AARCH32_ENDIAN_H
+
+#include <stdint.h>
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define _LITTLE_ENDIAN 1234 /* LSB first: i386, vax */
+#define _BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net */
+#define _PDP_ENDIAN 3412 /* LSB first in word, MSW first in long */
+
+#ifdef __ARMEB__
+#define _BYTE_ORDER _BIG_ENDIAN
+#else
+#define _BYTE_ORDER _LITTLE_ENDIAN
+#endif /* __ARMEB__ */
+
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN _LITTLE_ENDIAN
+#define BIG_ENDIAN _BIG_ENDIAN
+#define PDP_ENDIAN _PDP_ENDIAN
+#define BYTE_ORDER _BYTE_ORDER
+#endif
+
+#ifdef __ARMEB__
+#define _QUAD_HIGHWORD 0
+#define _QUAD_LOWWORD 1
+#define __ntohl(x) ((uint32_t)(x))
+#define __ntohs(x) ((uint16_t)(x))
+#define __htonl(x) ((uint32_t)(x))
+#define __htons(x) ((uint16_t)(x))
+#else
+#define _QUAD_HIGHWORD 1
+#define _QUAD_LOWWORD 0
+#define __ntohl(x) (__bswap32(x))
+#define __ntohs(x) (__bswap16(x))
+#define __htonl(x) (__bswap32(x))
+#define __htons(x) (__bswap16(x))
+#endif /* __ARMEB__ */
+
+static __inline uint64_t
+__bswap64(uint64_t _x)
+{
+
+ return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
+ ((_x >> 8) & 0xff000000) | ((_x << 8) & ((uint64_t)0xff << 32)) |
+ ((_x << 24) & ((uint64_t)0xff << 40)) |
+ ((_x << 40) & ((uint64_t)0xff << 48)) | ((_x << 56)));
+}
+
+static __inline uint32_t
+__bswap32_var(uint32_t v)
+{
+ uint32_t t1;
+
+ __asm __volatile("eor %1, %0, %0, ror #16\n"
+ "bic %1, %1, #0x00ff0000\n"
+ "mov %0, %0, ror #8\n"
+ "eor %0, %0, %1, lsr #8\n"
+ : "+r" (v), "=r" (t1));
+
+ return (v);
+}
+
+static __inline uint16_t
+__bswap16_var(uint16_t v)
+{
+ uint32_t ret = v & 0xffff;
+
+ __asm __volatile(
+ "mov %0, %0, ror #8\n"
+ "orr %0, %0, %0, lsr #16\n"
+ "bic %0, %0, %0, lsl #16"
+ : "+r" (ret));
+
+ return ((uint16_t)ret);
+}
+
+#ifdef __OPTIMIZE__
+
+#define __bswap32_constant(x) \
+ ((((x) & 0xff000000U) >> 24) | \
+ (((x) & 0x00ff0000U) >> 8) | \
+ (((x) & 0x0000ff00U) << 8) | \
+ (((x) & 0x000000ffU) << 24))
+
+#define __bswap16_constant(x) \
+ ((((x) & 0xff00) >> 8) | \
+ (((x) & 0x00ff) << 8))
+
+#define __bswap16(x) \
+ ((uint16_t)(__builtin_constant_p(x) ? \
+ __bswap16_constant(x) : \
+ __bswap16_var(x)))
+
+#define __bswap32(x) \
+ ((uint32_t)(__builtin_constant_p(x) ? \
+ __bswap32_constant(x) : \
+ __bswap32_var(x)))
+
+#else
+#define __bswap16(x) __bswap16_var(x)
+#define __bswap32(x) __bswap32_var(x)
+
+#endif /* __OPTIMIZE__ */
+#endif /* AARCH32_ENDIAN_H */
diff --git a/include/lib/libc/aarch32/limits_.h b/include/lib/libc/aarch32/limits_.h
new file mode 100644
index 000000000..26cec1723
--- /dev/null
+++ b/include/lib/libc/aarch32/limits_.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define SCHAR_MAX 0x7F
+#define SCHAR_MIN (-SCHAR_MIN - 1)
+#define CHAR_MAX 0x7F
+#define CHAR_MIN (-CHAR_MAX - 1)
+#define UCHAR_MAX 0xFFU
+#define SHRT_MAX 0x7FFF
+#define SHRT_MIN (-SHRT_MAX - 1)
+#define USHRT_MAX 0xFFFFU
+#define INT_MAX 0x7FFFFFFF
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX 0xFFFFFFFFU
+#define LONG_MAX 0x7FFFFFFFL
+#define LONG_MIN (-LONG_MAX - 1L)
+#define ULONG_MAX 0xFFFFFFFFUL
+#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
+#define LLONG_MIN (-LLONG_MAX - 1LL)
+#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define __LONG_BIT 32
+#define __WORD_BIT 32
diff --git a/include/lib/libc/aarch32/stddef_.h b/include/lib/libc/aarch32/stddef_.h
new file mode 100644
index 000000000..928481ce9
--- /dev/null
+++ b/include/lib/libc/aarch32/stddef_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
+
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h
new file mode 100644
index 000000000..4f494859f
--- /dev/null
+++ b/include/lib/libc/aarch32/stdint_.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define INT8_MAX 0x7F
+#define INT8_MIN (-INT8_MAX - 1)
+#define UINT8_MAX 0xFFU
+
+#define INT16_MAX 0x7FFF
+#define INT16_MIN (-INT16_MAX - 1)
+#define UINT16_MAX 0xFFFFU
+
+#define INT32_MAX 0x7FFFFFFF
+#define INT32_MIN (-INT32_MAX - 1)
+#define UINT32_MAX 0xFFFFFFFFU
+
+#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
+#define INT64_MIN (-INT64_MAX - 1LL)
+#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN INT32_MIN
+#define INT_FAST8_MAX INT32_MAX
+#define UINT_FAST8_MAX UINT32_MAX
+
+#define INT_FAST16_MIN INT32_MIN
+#define INT_FAST16_MAX INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTPTR_MIN INT32_MIN
+#define INTPTR_MAX INT32_MAX
+#define UINTPTR_MAX UINT32_MAX
+
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#define PTRDIFF_MIN INT32_MIN
+#define PTRDIFF_MAX INT32_MAX
+
+#define SIZE_MAX UINT32_MAX
+
+#define INT8_C(x) x
+#define INT16_C(x) x
+#define INT32_C(x) x
+#define INT64_C(x) x ## LL
+
+#define UINT8_C(x) x
+#define UINT16_C(x) x
+#define UINT32_C(x) x ## U
+#define UINT64_C(x) x ## ULL
+
+#define INTMAX_C(x) x ## LL
+#define UINTMAX_C(x) x ## ULL
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_least_t;
+typedef short int16_least_t;
+typedef int int32_least_t;
+typedef long long int64_least_t;
+
+typedef unsigned char uint8_least_t;
+typedef unsigned short uint16_least_t;
+typedef unsigned int uint32_least_t;
+typedef unsigned long long uint64_least_t;
+
+typedef int int8_fast_t;
+typedef int int16_fast_t;
+typedef int int32_fast_t;
+typedef long long int64_fast_t;
+
+typedef unsigned int uint8_fast_t;
+typedef unsigned int uint16_fast_t;
+typedef unsigned int uint32_fast_t;
+typedef unsigned long long uint64_fast_t;
+
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef long register_t;
+typedef unsigned long u_register_t;
diff --git a/include/lib/libc/aarch32/stdio_.h b/include/lib/libc/aarch32/stdio_.h
new file mode 100644
index 000000000..98304bc3c
--- /dev/null
+++ b/include/lib/libc/aarch32/stdio_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
+
+#ifndef SSIZET_
+typedef int ssize_t;
+#define SSIZET_
+#endif
diff --git a/include/lib/libc/aarch32/stdlib_.h b/include/lib/libc/aarch32/stdlib_.h
new file mode 100644
index 000000000..af96d0162
--- /dev/null
+++ b/include/lib/libc/aarch32/stdlib_.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
diff --git a/include/lib/libc/aarch32/string_.h b/include/lib/libc/aarch32/string_.h
new file mode 100644
index 000000000..b3ad602ff
--- /dev/null
+++ b/include/lib/libc/aarch32/string_.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
diff --git a/include/lib/libc/aarch32/time_.h b/include/lib/libc/aarch32/time_.h
new file mode 100644
index 000000000..4fc629d6d
--- /dev/null
+++ b/include/lib/libc/aarch32/time_.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
+
+typedef long int time_t;
diff --git a/include/lib/stdlib/machine/endian.h b/include/lib/libc/aarch64/endian_.h
index 57e33b172..c60b4752b 100644
--- a/include/lib/stdlib/machine/endian.h
+++ b/include/lib/libc/aarch64/endian_.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 2001 David E. O'Brien
*
* Redistribution and use in source and binary forms, with or without
@@ -30,14 +32,14 @@
* $FreeBSD$
*/
/*
- * Portions copyright (c) 2017, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
* All rights reserved.
*/
-#ifndef _MACHINE_ENDIAN_H_
-#define _MACHINE_ENDIAN_H_
+#ifndef AARCH64_ENDIAN_H
+#define AARCH64_ENDIAN_H
-#include <sys/_types.h>
+#include <stdint.h>
/*
* Definitions for byte order, according to byte significance from low
@@ -63,80 +65,38 @@
#define __htonl(x) (__bswap32(x))
#define __htons(x) (__bswap16(x))
-#ifdef AARCH32
-static __inline __uint64_t
-__bswap64(__uint64_t _x)
-{
-
- return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
- ((_x >> 8) & 0xff000000) | ((_x << 8) & ((__uint64_t)0xff << 32)) |
- ((_x << 24) & ((__uint64_t)0xff << 40)) |
- ((_x << 40) & ((__uint64_t)0xff << 48)) | ((_x << 56)));
-}
-
-static __inline __uint32_t
-__bswap32_var(__uint32_t v)
-{
- __uint32_t t1;
-
- __asm __volatile("eor %1, %0, %0, ror #16\n"
- "bic %1, %1, #0x00ff0000\n"
- "mov %0, %0, ror #8\n"
- "eor %0, %0, %1, lsr #8\n"
- : "+r" (v), "=r" (t1));
-
- return (v);
-}
-
-static __inline __uint16_t
-__bswap16_var(__uint16_t v)
-{
- __uint32_t ret = v & 0xffff;
-
- __asm __volatile(
- "mov %0, %0, ror #8\n"
- "orr %0, %0, %0, lsr #16\n"
- "bic %0, %0, %0, lsl #16"
- : "+r" (ret));
-
- return ((__uint16_t)ret);
-}
-#elif defined AARCH64
-static __inline __uint64_t
-__bswap64(__uint64_t x)
+static __inline uint64_t
+__bswap64(uint64_t x)
{
- __uint64_t ret;
+ uint64_t ret;
__asm __volatile("rev %0, %1\n"
: "=&r" (ret), "+r" (x));
-
+
return (ret);
}
-static __inline __uint32_t
-__bswap32_var(__uint32_t v)
+static __inline uint32_t
+__bswap32_var(uint32_t v)
{
- __uint32_t ret;
+ uint32_t ret;
__asm __volatile("rev32 %x0, %x1\n"
: "=&r" (ret), "+r" (v));
-
+
return (ret);
}
-static __inline __uint16_t
-__bswap16_var(__uint16_t v)
+static __inline uint16_t
+__bswap16_var(uint16_t v)
{
- __uint32_t ret;
+ uint32_t ret;
__asm __volatile("rev16 %w0, %w1\n"
: "=&r" (ret), "+r" (v));
- return ((__uint16_t)ret);
-}
-#else
-#error "Only AArch32 or AArch64 supported"
-#endif /* AARCH32 */
+ return ((uint16_t)ret);
+}
#ifdef __OPTIMIZE__
@@ -151,13 +111,13 @@ __bswap16_var(__uint16_t v)
(((x) & 0x00ff) << 8))
#define __bswap16(x) \
- ((__uint16_t)(__builtin_constant_p(x) ? \
- __bswap16_constant(x) : \
+ ((uint16_t)(__builtin_constant_p(x) ? \
+ __bswap16_constant((uint16_t)(x)) : \
__bswap16_var(x)))
#define __bswap32(x) \
- ((__uint32_t)(__builtin_constant_p(x) ? \
- __bswap32_constant(x) : \
+ ((uint32_t)(__builtin_constant_p(x) ? \
+ __bswap32_constant((uint32_t)(x)) : \
__bswap32_var(x)))
#else
@@ -165,4 +125,4 @@ __bswap16_var(__uint16_t v)
#define __bswap32(x) __bswap32_var(x)
#endif /* __OPTIMIZE__ */
-#endif /* !_MACHINE_ENDIAN_H_ */
+#endif /* AARCH64_ENDIAN_H */
diff --git a/include/lib/libc/aarch64/limits_.h b/include/lib/libc/aarch64/limits_.h
new file mode 100644
index 000000000..e36cfe7dc
--- /dev/null
+++ b/include/lib/libc/aarch64/limits_.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define SCHAR_MAX 0x7F
+#define SCHAR_MIN (-SCHAR_MIN - 1)
+#define CHAR_MAX 0x7F
+#define CHAR_MIN (-CHAR_MAX - 1)
+#define UCHAR_MAX 0xFFU
+#define SHRT_MAX 0x7FFF
+#define SHRT_MIN (-SHRT_MAX - 1)
+#define USHRT_MAX 0xFFFFU
+#define INT_MAX 0x7FFFFFFF
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX 0xFFFFFFFFU
+#define LONG_MAX 0x7FFFFFFFFFFFFFFFL
+#define LONG_MIN (-LONG_MAX - 1L)
+#define ULONG_MAX 0xFFFFFFFFFFFFFFFFUL
+#define LLONG_MAX 0x7FFFFFFFFFFFFFFFLL
+#define LLONG_MIN (-LLONG_MAX - 1LL)
+#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define __LONG_BIT 64
+#define __WORD_BIT 32
diff --git a/include/lib/libc/aarch64/stddef_.h b/include/lib/libc/aarch64/stddef_.h
new file mode 100644
index 000000000..3e5883ece
--- /dev/null
+++ b/include/lib/libc/aarch64/stddef_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h
new file mode 100644
index 000000000..b99be304d
--- /dev/null
+++ b/include/lib/libc/aarch64/stdint_.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define INT8_MAX 0x7F
+#define INT8_MIN (-INT8_MAX - 1)
+#define UINT8_MAX 0xFFU
+
+#define INT16_MAX 0x7FFF
+#define INT16_MIN (-INT16_MAX - 1)
+#define UINT16_MAX 0xFFFFU
+
+#define INT32_MAX 0x7FFFFFFF
+#define INT32_MIN (-INT32_MAX - 1)
+#define UINT32_MAX 0xFFFFFFFFU
+
+#define INT64_MAX 0x7FFFFFFFFFFFFFFFLL
+#define INT64_MIN (-INT64_MAX - 1LL)
+#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define INT_LEAST8_MIN INT8_MIN
+#define INT_LEAST8_MAX INT8_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+
+#define INT_LEAST16_MIN INT16_MIN
+#define INT_LEAST16_MAX INT16_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+
+#define INT_LEAST32_MIN INT32_MIN
+#define INT_LEAST32_MAX INT32_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+
+#define INT_LEAST64_MIN INT64_MIN
+#define INT_LEAST64_MAX INT64_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN INT32_MIN
+#define INT_FAST8_MAX INT32_MAX
+#define UINT_FAST8_MAX UINT32_MAX
+
+#define INT_FAST16_MIN INT32_MIN
+#define INT_FAST16_MAX INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+
+#define INT_FAST32_MIN INT32_MIN
+#define INT_FAST32_MAX INT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INT_FAST64_MIN INT64_MIN
+#define INT_FAST64_MAX INT64_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+
+#define INTMAX_MIN INT64_MIN
+#define INTMAX_MAX INT64_MAX
+#define UINTMAX_MAX UINT64_MAX
+
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+
+#define SIZE_MAX UINT64_MAX
+
+#define INT8_C(x) x
+#define INT16_C(x) x
+#define INT32_C(x) x
+#define INT64_C(x) x ## LL
+
+#define UINT8_C(x) x
+#define UINT16_C(x) x
+#define UINT32_C(x) x ## U
+#define UINT64_C(x) x ## ULL
+
+#define INTMAX_C(x) x ## L
+#define UINTMAX_C(x) x ## ULL
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+typedef long long int64_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+typedef signed char int8_least_t;
+typedef short int16_least_t;
+typedef int int32_least_t;
+typedef long long int64_least_t;
+
+typedef unsigned char uint8_least_t;
+typedef unsigned short uint16_least_t;
+typedef unsigned int uint32_least_t;
+typedef unsigned long long uint64_least_t;
+
+typedef int int8_fast_t;
+typedef int int16_fast_t;
+typedef int int32_fast_t;
+typedef long long int64_fast_t;
+
+typedef unsigned int uint8_fast_t;
+typedef unsigned int uint16_fast_t;
+typedef unsigned int uint32_fast_t;
+typedef unsigned long long uint64_fast_t;
+
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+
+typedef long intmax_t;
+typedef unsigned long uintmax_t;
+
+typedef long register_t;
+typedef unsigned long u_register_t;
diff --git a/include/lib/libc/aarch64/stdio_.h b/include/lib/libc/aarch64/stdio_.h
new file mode 100644
index 000000000..ad0b20063
--- /dev/null
+++ b/include/lib/libc/aarch64/stdio_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+#ifndef SSIZET_
+typedef long ssize_t;
+#define SSIZET_
+#endif
diff --git a/include/lib/libc/aarch64/stdlib_.h b/include/lib/libc/aarch64/stdlib_.h
new file mode 100644
index 000000000..3612c9902
--- /dev/null
+++ b/include/lib/libc/aarch64/stdlib_.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
diff --git a/include/lib/libc/aarch64/string_.h b/include/lib/libc/aarch64/string_.h
new file mode 100644
index 000000000..a88a751a4
--- /dev/null
+++ b/include/lib/libc/aarch64/string_.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
diff --git a/include/lib/libc/aarch64/time_.h b/include/lib/libc/aarch64/time_.h
new file mode 100644
index 000000000..cbc34e76a
--- /dev/null
+++ b/include/lib/libc/aarch64/time_.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+typedef long int time_t;
diff --git a/include/lib/libc/assert.h b/include/lib/libc/assert.h
new file mode 100644
index 000000000..2cca6a0b2
--- /dev/null
+++ b/include/lib/libc/assert.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+#include <cdefs.h>
+#include <debug.h>
+#include <platform_def.h>
+
+#ifndef PLAT_LOG_LEVEL_ASSERT
+#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL
+#endif
+
+#if ENABLE_ASSERTIONS
+# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
+# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
+# elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__))
+# else
+# define assert(e) ((e) ? (void)0 : __assert())
+# endif
+#else
+#define assert(e) ((void)0)
+#endif /* ENABLE_ASSERTIONS */
+
+#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
+__dead2 void __assert(const char *file, unsigned int line,
+ const char *assertion);
+#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
+__dead2 void __assert(const char *file, unsigned int line);
+#else
+__dead2 void __assert(void);
+#endif
+
+#endif /* ASSERT_H */
diff --git a/include/lib/libc/cdefs.h b/include/lib/libc/cdefs.h
new file mode 100644
index 000000000..b1d10ccce
--- /dev/null
+++ b/include/lib/libc/cdefs.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDEFS_H
+#define CDEFS_H
+
+#define __dead2 __attribute__((__noreturn__))
+#define __deprecated __attribute__((__deprecated__))
+#define __packed __attribute__((__packed__))
+#define __used __attribute__((__used__))
+#define __unused __attribute__((__unused__))
+#define __aligned(x) __attribute__((__aligned__(x)))
+#define __section(x) __attribute__((__section__(x)))
+
+#define __printflike(fmtarg, firstvararg) \
+ __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+
+#define __weak_reference(sym, alias) \
+ __asm__(".weak alias"); \
+ __asm__(".equ alias, sym")
+
+#define __STRING(x) #x
+#define __XSTRING(x) __STRING(x)
+
+#endif /* CDEFS_H */
diff --git a/include/lib/stdlib/sys/endian.h b/include/lib/libc/endian.h
index d50110cab..2cc4c5fc0 100644
--- a/include/lib/stdlib/sys/endian.h
+++ b/include/lib/libc/endian.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
* All rights reserved.
*
@@ -25,34 +27,18 @@
*
* $FreeBSD$
*/
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef ENDIAN_H
+#define ENDIAN_H
+
+#include <cdefs.h>
+#include <stdint.h>
+#include <endian_.h>
-#ifndef _SYS_ENDIAN_H_
-#define _SYS_ENDIAN_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-#include <machine/endian.h>
-
-#ifndef _UINT8_T_DECLARED
-typedef __uint8_t uint8_t;
-#define _UINT8_T_DECLARED
-#endif
-
-#ifndef _UINT16_T_DECLARED
-typedef __uint16_t uint16_t;
-#define _UINT16_T_DECLARED
-#endif
-
-#ifndef _UINT32_T_DECLARED
-typedef __uint32_t uint32_t;
-#define _UINT32_T_DECLARED
-#endif
-
-#ifndef _UINT64_T_DECLARED
-typedef __uint64_t uint64_t;
-#define _UINT64_T_DECLARED
-#endif
-
/*
* General byte order swapping functions.
*/
@@ -202,4 +188,4 @@ le64enc(void *pp, uint64_t u)
le32enc(p + 4, (uint32_t)(u >> 32));
}
-#endif /* _SYS_ENDIAN_H_ */
+#endif /* SYS_ENDIAN_H */
diff --git a/include/lib/stdlib/sys/errno.h b/include/lib/libc/errno.h
index f59551451..029912f61 100644
--- a/include/lib/stdlib/sys/errno.h
+++ b/include/lib/libc/errno.h
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
@@ -15,7 +17,7 @@
* 2. 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.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -34,17 +36,13 @@
* @(#)errno.h 8.5 (Berkeley) 1/21/94
* $FreeBSD$
*/
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
-#ifndef _SYS_ERRNO_H_
-#define _SYS_ERRNO_H_
-
-#ifndef _KERNEL
-#include <sys/cdefs.h>
-__BEGIN_DECLS
-int * __error(void);
-__END_DECLS
-#define errno (* __error())
-#endif
+#ifndef ERRNO_H
+#define ERRNO_H
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
@@ -61,9 +59,7 @@ __END_DECLS
#define ENOMEM 12 /* Cannot allocate memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
-#ifndef _POSIX_SOURCE
#define ENOTBLK 15 /* Block device required */
-#endif
#define EBUSY 16 /* Device busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
@@ -74,9 +70,7 @@ __END_DECLS
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate ioctl for device */
-#ifndef _POSIX_SOURCE
#define ETXTBSY 26 /* Text file busy */
-#endif
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
@@ -90,7 +84,6 @@ __END_DECLS
/* non-blocking and interrupt i/o */
#define EAGAIN 35 /* Resource temporarily unavailable */
-#ifndef _POSIX_SOURCE
#define EWOULDBLOCK EAGAIN /* Operation would block */
#define EINPROGRESS 36 /* Operation now in progress */
#define EALREADY 37 /* Operation already in progress */
@@ -125,18 +118,14 @@ __END_DECLS
#define ECONNREFUSED 61 /* Connection refused */
#define ELOOP 62 /* Too many levels of symbolic links */
-#endif /* _POSIX_SOURCE */
#define ENAMETOOLONG 63 /* File name too long */
/* should be rearranged */
-#ifndef _POSIX_SOURCE
#define EHOSTDOWN 64 /* Host is down */
#define EHOSTUNREACH 65 /* No route to host */
-#endif /* _POSIX_SOURCE */
#define ENOTEMPTY 66 /* Directory not empty */
/* quotas & mush */
-#ifndef _POSIX_SOURCE
#define EPROCLIM 67 /* Too many processes */
#define EUSERS 68 /* Too many users */
#define EDQUOT 69 /* Disc quota exceeded */
@@ -149,12 +138,10 @@ __END_DECLS
#define EPROGUNAVAIL 74 /* RPC prog. not avail */
#define EPROGMISMATCH 75 /* Program version wrong */
#define EPROCUNAVAIL 76 /* Bad procedure for program */
-#endif /* _POSIX_SOURCE */
#define ENOLCK 77 /* No locks available */
#define ENOSYS 78 /* Function not implemented */
-#ifndef _POSIX_SOURCE
#define EFTYPE 79 /* Inappropriate file type or format */
#define EAUTH 80 /* Authentication error */
#define ENEEDAUTH 81 /* Need authenticator */
@@ -166,28 +153,17 @@ __END_DECLS
#define ENOATTR 87 /* Attribute not found */
#define EDOOFUS 88 /* Programming error */
-#endif /* _POSIX_SOURCE */
#define EBADMSG 89 /* Bad message */
#define EMULTIHOP 90 /* Multihop attempted */
#define ENOLINK 91 /* Link has been severed */
#define EPROTO 92 /* Protocol error */
-#ifndef _POSIX_SOURCE
#define ENOTCAPABLE 93 /* Capabilities insufficient */
#define ECAPMODE 94 /* Not permitted in capability mode */
-#endif /* _POSIX_SOURCE */
-
-#ifndef _POSIX_SOURCE
-#define ELAST 94 /* Must be equal largest errno */
-#endif /* _POSIX_SOURCE */
+#define ENOTRECOVERABLE 95 /* State not recoverable */
+#define EOWNERDEAD 96 /* Previous owner died */
-#ifdef _KERNEL
-/* pseudo-errors returned inside kernel to modify return to process */
-#define ERESTART (-1) /* restart syscall */
-#define EJUSTRETURN (-2) /* don't modify regs, just return */
-#define ENOIOCTL (-3) /* ioctl not handled by this layer */
-#define EDIRIOCTL (-4) /* do direct ioctl in GEOM */
-#endif
+#define ELAST 96 /* Must be equal largest errno */
-#endif
+#endif /* ERRNO_H */
diff --git a/include/lib/libc/limits.h b/include/lib/libc/limits.h
new file mode 100644
index 000000000..41bb65848
--- /dev/null
+++ b/include/lib/libc/limits.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef LIMITS_H
+#define LIMITS_H
+
+#include <limits_.h>
+
+#define CHAR_BIT 8
+#define MB_LEN_MAX 1
+
+#endif /* LIMITS_H */
diff --git a/include/lib/libc/stdarg.h b/include/lib/libc/stdarg.h
new file mode 100644
index 000000000..e260b9b50
--- /dev/null
+++ b/include/lib/libc/stdarg.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDARG_H
+#define STDARG_H
+
+#define va_list __builtin_va_list
+#define va_start(ap, last) __builtin_va_start(ap, last)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_copy(to, from) __builtin_va_copy(to, from)
+#define va_arg(to, type) __builtin_va_arg(to, type)
+
+#endif /* STDARG_H */
diff --git a/include/lib/libc/stdbool.h b/include/lib/libc/stdbool.h
new file mode 100644
index 000000000..e39aef7d3
--- /dev/null
+++ b/include/lib/libc/stdbool.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDBOOL_H
+#define STDBOOL_H
+
+#define bool _Bool
+
+#define true 1
+#define false 0
+
+#define __bool_true_false_are_defined 1
+
+#endif /* STDBOOL_H */
diff --git a/include/lib/libc/stddef.h b/include/lib/libc/stddef.h
new file mode 100644
index 000000000..c9957bdb1
--- /dev/null
+++ b/include/lib/libc/stddef.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDDEF_H
+#define STDDEF_H
+
+#include <stddef_.h>
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define offsetof(st, m) __builtin_offsetof(st, m)
+
+#endif /* STDDEF_H */
diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h
new file mode 100644
index 000000000..d44a973f1
--- /dev/null
+++ b/include/lib/libc/stdint.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT_H
+#define STDINT_H
+
+#include <stdint_.h>
+
+#endif /* STDINT_H */
diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h
new file mode 100644
index 000000000..3d9323efa
--- /dev/null
+++ b/include/lib/libc/stdio.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDIO_H
+#define STDIO_H
+
+#include <cdefs.h>
+#include <stdio_.h>
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define EOF -1
+
+int printf(const char *fmt, ...) __printflike(1, 2);
+int snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4);
+
+#ifdef STDARG_H
+int vprintf(const char *fmt, va_list args);
+#endif
+
+int putchar(int c);
+int puts(const char *s);
+
+#endif /* STDIO_H */
diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h
new file mode 100644
index 000000000..edd6265f5
--- /dev/null
+++ b/include/lib/libc/stdlib.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include <stdlib_.h>
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define _ATEXIT_MAX 1
+
+extern void abort(void);
+extern int atexit(void (*func)(void));
+extern void exit(int status);
+
+#endif /* STDLIB_H */
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
new file mode 100644
index 000000000..050f64380
--- /dev/null
+++ b/include/lib/libc/string.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STRING_H
+#define STRING_H
+
+#include <string_.h>
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+void *memcpy(void *dst, const void *src, size_t len);
+void *memmove(void *dst, const void *src, size_t len);
+int memcmp(const void *s1, const void *s2, size_t len);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, size_t n);
+void *memchr(const void *src, int c, size_t len);
+char *strchr(const char *s, int c);
+void *memset(void *dst, int val, size_t count);
+size_t strlen(const char *s);
+size_t strnlen(const char *s, size_t maxlen);
+
+#endif /* STRING_H */
diff --git a/include/lib/libc/time.h b/include/lib/libc/time.h
new file mode 100644
index 000000000..71d3e7ec9
--- /dev/null
+++ b/include/lib/libc/time.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef TIME_H
+#define TIME_H
+
+#include <time_.h>
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#endif /* TIME_H */
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index 2320760ea..a3812fbf2 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PMF_H__
-#define __PMF_H__
+#ifndef PMF_H
+#define PMF_H
#include <cassert.h>
#include <pmf_helpers.h>
@@ -31,8 +31,8 @@
* Flags passed to PMF_GET_TIMESTAMP_XXX
* and PMF_CAPTURE_TIMESTAMP
*/
-#define PMF_CACHE_MAINT (1 << 0)
-#define PMF_NO_CACHE_MAINT 0
+#define PMF_CACHE_MAINT (U(1) << 0)
+#define PMF_NO_CACHE_MAINT U(0)
/*
* Defines for PMF SMC function ids.
@@ -68,7 +68,7 @@
#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \
do { \
unsigned long long ts = read_cntpct_el0(); \
- if ((_flags) & PMF_CACHE_MAINT) \
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
else \
pmf_capture_timestamp_ ## _name((_tid), ts); \
@@ -78,7 +78,7 @@
do { \
(_tsval) = read_cntpct_el0(); \
CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
- if ((_flags) & PMF_CACHE_MAINT) \
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
else \
pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
@@ -87,7 +87,7 @@
#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \
do { \
CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
- if ((_flags) & PMF_CACHE_MAINT) \
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
else \
pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
@@ -173,4 +173,4 @@ uintptr_t pmf_smc_handler(unsigned int smc_fid,
void *handle,
u_register_t flags);
-#endif /* __PMF_H__ */
+#endif /* PMF_H */
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index 829ad6cca..b9757de07 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PMF_HELPERS_H__
-#define __PMF_HELPERS_H__
+#ifndef PMF_HELPERS_H
+#define PMF_HELPERS_H
#include <arch_helpers.h>
#include <assert.h>
@@ -77,9 +77,9 @@ typedef struct pmf_svc_desc {
CASSERT(_flags, select_proper_config); \
PMF_VALIDATE_TID(_name, tid); \
uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
- if ((_flags) & PMF_STORE_ENABLE) \
+ if (((_flags) & PMF_STORE_ENABLE) != 0) \
__pmf_store_timestamp(base_addr, tid, ts); \
- if ((_flags) & PMF_DUMP_ENABLE) \
+ if (((_flags) & PMF_DUMP_ENABLE) != 0) \
__pmf_dump_timestamp(tid, ts); \
} \
void pmf_capture_timestamp_with_cache_maint_ ## _name( \
@@ -92,9 +92,9 @@ typedef struct pmf_svc_desc {
CASSERT(_flags, select_proper_config); \
PMF_VALIDATE_TID(_name, tid); \
uintptr_t base_addr = (uintptr_t) pmf_ts_mem_ ## _name; \
- if ((_flags) & PMF_STORE_ENABLE) \
+ if (((_flags) & PMF_STORE_ENABLE) != 0) \
__pmf_store_timestamp_with_cache_maint(base_addr, tid, ts);\
- if ((_flags) & PMF_DUMP_ENABLE) \
+ if (((_flags) & PMF_DUMP_ENABLE) != 0) \
__pmf_dump_timestamp(tid, ts); \
}
@@ -159,4 +159,4 @@ unsigned long long __pmf_get_timestamp(uintptr_t base_addr,
unsigned int tid,
unsigned int cpuid,
unsigned int flags);
-#endif /* __PMF_HELPERS_H__ */
+#endif /* PMF_HELPERS_H */
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 06434f9e5..fa0da9fee 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PSCI_H__
-#define __PSCI_H__
+#ifndef PSCI_H
+#define PSCI_H
#include <bakery_lock.h>
#include <bl_common.h>
@@ -22,14 +22,14 @@
#ifdef PLAT_NUM_PWR_DOMAINS
#define PSCI_NUM_PWR_DOMAINS PLAT_NUM_PWR_DOMAINS
#else
-#define PSCI_NUM_PWR_DOMAINS (U(2) * PLATFORM_CORE_COUNT)
+#define PSCI_NUM_PWR_DOMAINS (2 * PLATFORM_CORE_COUNT)
#endif
#define PSCI_NUM_NON_CPU_PWR_DOMAINS (PSCI_NUM_PWR_DOMAINS - \
PLATFORM_CORE_COUNT)
/* This is the power level corresponding to a CPU */
-#define PSCI_CPU_PWR_LVL (0)
+#define PSCI_CPU_PWR_LVL U(0)
/*
* The maximum power level supported by PSCI. Since PSCI CPU_SUSPEND
@@ -71,9 +71,6 @@
#define PSCI_MEM_CHK_RANGE_AARCH32 U(0x84000014)
#define PSCI_MEM_CHK_RANGE_AARCH64 U(0xc4000014)
-/* Macro to help build the psci capabilities bitfield */
-#define define_psci_cap(x) (U(1) << (x & U(0x1f)))
-
/*
* Number of PSCI calls (above) implemented
*/
@@ -92,9 +89,9 @@
/*******************************************************************************
* PSCI Migrate and friends
******************************************************************************/
-#define PSCI_TOS_UP_MIG_CAP U(0)
-#define PSCI_TOS_NOT_UP_MIG_CAP U(1)
-#define PSCI_TOS_NOT_PRESENT_MP U(2)
+#define PSCI_TOS_UP_MIG_CAP 0
+#define PSCI_TOS_NOT_UP_MIG_CAP 1
+#define PSCI_TOS_NOT_PRESENT_MP 2
/*******************************************************************************
* PSCI CPU_SUSPEND 'power_state' parameter specific defines
@@ -124,12 +121,6 @@
#define PSTATE_TYPE_POWERDOWN U(0x1)
#define PSTATE_TYPE_MASK U(0x1)
-#define psci_get_pstate_id(pstate) (((pstate) >> PSTATE_ID_SHIFT) & \
- PSTATE_ID_MASK)
-#define psci_get_pstate_type(pstate) (((pstate) >> PSTATE_TYPE_SHIFT) & \
- PSTATE_TYPE_MASK)
-#define psci_check_power_state(pstate) ((pstate) & PSTATE_VALID_MASK)
-
/*******************************************************************************
* PSCI CPU_FEATURES feature flag specific defines
******************************************************************************/
@@ -172,15 +163,39 @@
/*
* SYSTEM_RESET2 macros
*/
-#define PSCI_RESET2_TYPE_VENDOR_SHIFT 31
-#define PSCI_RESET2_TYPE_VENDOR (1U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
-#define PSCI_RESET2_TYPE_ARCH (0U << PSCI_RESET2_TYPE_VENDOR_SHIFT)
-#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | 0)
+#define PSCI_RESET2_TYPE_VENDOR_SHIFT U(31)
+#define PSCI_RESET2_TYPE_VENDOR (U(1) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_TYPE_ARCH (U(0) << PSCI_RESET2_TYPE_VENDOR_SHIFT)
+#define PSCI_RESET2_SYSTEM_WARM_RESET (PSCI_RESET2_TYPE_ARCH | U(0))
#ifndef __ASSEMBLY__
#include <stdint.h>
-#include <types.h>
+
+/* Function to help build the psci capabilities bitfield */
+
+static inline unsigned int define_psci_cap(unsigned int x)
+{
+ return U(1) << (x & U(0x1f));
+}
+
+
+/* Power state helper functions */
+
+static inline unsigned int psci_get_pstate_id(unsigned int power_state)
+{
+ return ((power_state) >> PSTATE_ID_SHIFT) & PSTATE_ID_MASK;
+}
+
+static inline unsigned int psci_get_pstate_type(unsigned int power_state)
+{
+ return ((power_state) >> PSTATE_TYPE_SHIFT) & PSTATE_TYPE_MASK;
+}
+
+static inline unsigned int psci_check_power_state(unsigned int power_state)
+{
+ return ((power_state) & PSTATE_VALID_MASK);
+}
/*
* These are the states reported by the PSCI_AFFINITY_INFO API for the specified
@@ -198,11 +213,9 @@ typedef enum {
* specified CPU. The definitions of these states can be found in Section 5.15.3
* of PSCI specification (ARM DEN 0022C).
*/
-typedef enum {
- HW_ON = U(0),
- HW_OFF = U(1),
- HW_STANDBY = U(2)
-} node_hw_state_t;
+#define HW_ON 0
+#define HW_OFF 1
+#define HW_STANDBY 2
/*
* Macro to represent invalid affinity level within PSCI.
@@ -215,27 +228,33 @@ typedef enum {
typedef uint8_t plat_local_state_t;
/* The local state macro used to represent RUN state. */
-#define PSCI_LOCAL_STATE_RUN U(0)
+#define PSCI_LOCAL_STATE_RUN U(0)
/*
- * Macro to test whether the plat_local_state is RUN state
+ * Function to test whether the plat_local_state is RUN state
*/
-#define is_local_state_run(plat_local_state) \
- ((plat_local_state) == PSCI_LOCAL_STATE_RUN)
+static inline int is_local_state_run(unsigned int plat_local_state)
+{
+ return (plat_local_state == PSCI_LOCAL_STATE_RUN) ? 1 : 0;
+}
/*
- * Macro to test whether the plat_local_state is RETENTION state
+ * Function to test whether the plat_local_state is RETENTION state
*/
-#define is_local_state_retn(plat_local_state) \
- (((plat_local_state) > PSCI_LOCAL_STATE_RUN) && \
- ((plat_local_state) <= PLAT_MAX_RET_STATE))
+static inline int is_local_state_retn(unsigned int plat_local_state)
+{
+ return ((plat_local_state > PSCI_LOCAL_STATE_RUN) &&
+ (plat_local_state <= PLAT_MAX_RET_STATE)) ? 1 : 0;
+}
/*
- * Macro to test whether the plat_local_state is OFF state
+ * Function to test whether the plat_local_state is OFF state
*/
-#define is_local_state_off(plat_local_state) \
- (((plat_local_state) > PLAT_MAX_RET_STATE) && \
- ((plat_local_state) <= PLAT_MAX_OFF_STATE))
+static inline int is_local_state_off(unsigned int plat_local_state)
+{
+ return ((plat_local_state > PLAT_MAX_RET_STATE) &&
+ (plat_local_state <= PLAT_MAX_OFF_STATE)) ? 1 : 0;
+}
/*****************************************************************************
* This data structure defines the representation of the power state parameter
@@ -266,7 +285,7 @@ typedef struct psci_cpu_data {
* Highest power level which takes part in a power management
* operation.
*/
- unsigned char target_pwrlvl;
+ unsigned int target_pwrlvl;
/* The local power state of this CPU */
plat_local_state_t local_state;
@@ -324,7 +343,7 @@ int psci_affinity_info(u_register_t target_affinity,
unsigned int lowest_affinity_level);
int psci_migrate(u_register_t target_cpu);
int psci_migrate_info_type(void);
-long psci_migrate_info_up_cpu(void);
+u_register_t psci_migrate_info_up_cpu(void);
int psci_node_hw_state(u_register_t target_cpu,
unsigned int power_level);
int psci_features(unsigned int psci_fid);
@@ -339,4 +358,4 @@ void psci_entrypoint(void) __deprecated;
#endif /*__ASSEMBLY__*/
-#endif /* __PSCI_H__ */
+#endif /* PSCI_H */
diff --git a/include/lib/psci/psci_compat.h b/include/lib/psci/psci_compat.h
index 65ac15fc0..11ed16d00 100644
--- a/include/lib/psci/psci_compat.h
+++ b/include/lib/psci/psci_compat.h
@@ -1,14 +1,15 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PSCI_COMPAT_H__
-#define __PSCI_COMPAT_H__
+#ifndef PSCI_COMPAT_H
+#define PSCI_COMPAT_H
#include <arch.h>
#include <platform_def.h>
+#include <utils_def.h>
#ifndef __ASSEMBLY__
/*
@@ -25,10 +26,10 @@
#define PSCI_AFF_ABSENT 0x0
#define PSCI_AFF_PRESENT 0x1
-#define PSCI_STATE_ON 0x0
-#define PSCI_STATE_OFF 0x1
-#define PSCI_STATE_ON_PENDING 0x2
-#define PSCI_STATE_SUSPEND 0x3
+#define PSCI_STATE_ON U(0x0)
+#define PSCI_STATE_OFF U(0x1)
+#define PSCI_STATE_ON_PENDING U(0x2)
+#define PSCI_STATE_SUSPEND U(0x3)
/*
* Using the compatibility platform interfaces means that the local states
@@ -38,8 +39,8 @@
* involved. Hence if we assume 3 generic states viz, run, standby and
* power down, we can assign 1 and 2 to standby and power down respectively.
*/
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
/*
* Macro to represent invalid affinity level within PSCI.
@@ -89,4 +90,4 @@ unsigned int psci_get_max_phys_off_afflvl(void);
int psci_get_suspend_afflvl(void);
#endif /* ____ASSEMBLY__ */
-#endif /* __PSCI_COMPAT_H__ */
+#endif /* PSCI_COMPAT_H */
diff --git a/include/lib/psci/psci_lib.h b/include/lib/psci/psci_lib.h
index 4697f17c8..134cad9e0 100644
--- a/include/lib/psci/psci_lib.h
+++ b/include/lib/psci/psci_lib.h
@@ -1,16 +1,17 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PSCI_LIB_H__
-#define __PSCI_LIB_H__
+#ifndef PSCI_LIB_H
+#define PSCI_LIB_H
#include <ep_info.h>
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <cdefs.h>
+#include <stdint.h>
/*******************************************************************************
* Optional structure populated by the Secure Payload Dispatcher to be given a
@@ -20,9 +21,9 @@
******************************************************************************/
typedef struct spd_pm_ops {
void (*svc_on)(u_register_t target_cpu);
- int32_t (*svc_off)(u_register_t __unused);
+ int32_t (*svc_off)(u_register_t __unused unused);
void (*svc_suspend)(u_register_t max_off_pwrlvl);
- void (*svc_on_finish)(u_register_t __unused);
+ void (*svc_on_finish)(u_register_t __unused unused);
void (*svc_suspend_finish)(u_register_t max_off_pwrlvl);
int32_t (*svc_migrate)(u_register_t from_cpu, u_register_t to_cpu);
int32_t (*svc_migrate_info)(u_register_t *resident_cpu);
@@ -58,17 +59,17 @@ typedef struct psci_lib_args {
.h.type = (uint8_t)PARAM_PSCI_LIB_ARGS, \
.h.version = (uint8_t)VERSION_1, \
.h.size = (uint16_t)sizeof(_name), \
- .h.attr = 0, \
+ .h.attr = 0U, \
.mailbox_ep = (_entry) \
}
/* Helper macro to verify the pointer to psci_lib_args_t structure */
-#define VERIFY_PSCI_LIB_ARGS_V1(_p) ((_p) \
+#define VERIFY_PSCI_LIB_ARGS_V1(_p) (((_p) != NULL) \
&& ((_p)->h.type == PARAM_PSCI_LIB_ARGS) \
&& ((_p)->h.version == VERSION_1) \
&& ((_p)->h.size == sizeof(*(_p))) \
&& ((_p)->h.attr == 0) \
- && ((_p)->mailbox_ep))
+ && ((_p)->mailbox_ep != NULL))
/******************************************************************************
* PSCI Library Interfaces
@@ -89,5 +90,4 @@ void psci_prepare_next_non_secure_ctx(
entry_point_info_t *next_image_info);
#endif /* __ASSEMBLY__ */
-#endif /* __PSCI_LIB_H */
-
+#endif /* PSCI_LIB_H */
diff --git a/include/lib/spinlock.h b/include/lib/spinlock.h
index a7b0d3940..8aec70789 100644
--- a/include/lib/spinlock.h
+++ b/include/lib/spinlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct spinlock {
volatile uint32_t lock;
diff --git a/include/lib/stdlib/assert.h b/include/lib/stdlib/assert.h
deleted file mode 100644
index db567dbb2..000000000
--- a/include/lib/stdlib/assert.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)assert.h 8.2 (Berkeley) 1/21/94
- * $FreeBSD$
- */
-/*
- * Portions copyright (c) 2017, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _ASSERT_H_
-#define _ASSERT_H_
-
-#include <debug.h>
-#include <platform_def.h>
-#include <sys/cdefs.h>
-
-#ifndef PLAT_LOG_LEVEL_ASSERT
-#define PLAT_LOG_LEVEL_ASSERT LOG_LEVEL
-#endif
-
-#if ENABLE_ASSERTIONS
-#define _assert(e) assert(e)
-# if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__, #e))
-# elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
-# define assert(e) ((e) ? (void)0 : __assert(__FILE__, __LINE__))
-# else
-# define assert(e) ((e) ? (void)0 : __assert())
-# endif
-#else
-#define assert(e) ((void)0)
-#define _assert(e) ((void)0)
-#endif /* ENABLE_ASSERTIONS */
-
-__BEGIN_DECLS
-#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
-void __assert(const char *, unsigned int, const char *) __dead2;
-#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
-void __assert(const char *, unsigned int) __dead2;
-#else
-void __assert(void) __dead2;
-#endif
-__END_DECLS
-
-#endif /* !_ASSERT_H_ */
diff --git a/include/lib/stdlib/inttypes.h b/include/lib/stdlib/inttypes.h
deleted file mode 100644
index 269f3e7c9..000000000
--- a/include/lib/stdlib/inttypes.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*-
- * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _INTTYPES_H_
-#define _INTTYPES_H_
-
-#include <machine/_inttypes.h>
-#include <sys/stdint.h>
-
-typedef struct {
- intmax_t quot; /* Quotient. */
- intmax_t rem; /* Remainder. */
-} imaxdiv_t;
-
-__BEGIN_DECLS
-#ifdef _XLOCALE_H_
-#include <xlocale/_inttypes.h>
-#endif
-intmax_t imaxabs(intmax_t) __pure2;
-imaxdiv_t imaxdiv(intmax_t, intmax_t) __pure2;
-
-intmax_t strtoimax(const char *__restrict, char **__restrict, int);
-uintmax_t strtoumax(const char *__restrict, char **__restrict, int);
-
-__END_DECLS
-
-#endif /* !_INTTYPES_H_ */
diff --git a/include/lib/stdlib/machine/_inttypes.h b/include/lib/stdlib/machine/_inttypes.h
deleted file mode 100644
index 7dfe9c3d5..000000000
--- a/include/lib/stdlib/machine/_inttypes.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef _MACHINE_INTTYPES_H_
-#define _MACHINE_INTTYPES_H_
-
-/*
- * Trusted Firmware does not depend on any definitions in this file. Content
- * will be added as needed.
- */
-
-#endif /* !_MACHINE_INTTYPES_H_ */
diff --git a/include/lib/stdlib/machine/_limits.h b/include/lib/stdlib/machine/_limits.h
deleted file mode 100644
index 3bdc66f14..000000000
--- a/include/lib/stdlib/machine/_limits.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*-
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- *
- * @(#)limits.h 8.3 (Berkeley) 1/4/94
- * $FreeBSD$
- */
-
-/*
- * Portions copyright (c) 2017, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _MACHINE__LIMITS_H_
-#define _MACHINE__LIMITS_H_
-
-/*
- * According to ANSI (section 2.2.4.2), the values below must be usable by
- * #if preprocessing directives. Additionally, the expression must have the
- * same type as would an expression that is an object of the corresponding
- * type converted according to the integral promotions. The subtraction for
- * INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
- * unsigned int for 32-bit two's complement ANSI compilers (section 3.1.3.2).
- */
-
-#define __CHAR_BIT 8 /* number of bits in a char */
-
-#define __SCHAR_MAX 0x7f /* max value for a signed char */
-#define __SCHAR_MIN (-0x7f-1) /* min value for a signed char */
-
-#define __UCHAR_MAX 0xff /* max value for an unsigned char */
-
-#define __USHRT_MAX 0xffff /* max value for an unsigned short */
-#define __SHRT_MAX 0x7fff /* max value for a short */
-#define __SHRT_MIN (-0x7fff-1) /* min value for a short */
-
-#define __UINT_MAX 0xffffffffU /* max value for an unsigned int */
-#define __INT_MAX 0x7fffffff /* max value for an int */
-#define __INT_MIN (-0x7fffffff-1) /* min value for an int */
-
-#ifdef AARCH32
-#define __ULONG_MAX 0xffffffffUL /* max for an unsigned long */
-#define __LONG_MAX 0x7fffffffL /* max for a long */
-#define __LONG_MIN (-0x7fffffffL-1) /* min for a long */
-#else
-#define __ULONG_MAX 0xffffffffffffffffUL /* max for an unsigned long */
-#define __LONG_MAX 0x7fffffffffffffffL /* max for a long */
-#define __LONG_MIN (-0x7fffffffffffffffL-1) /* min for a long */
-#endif
-
-#define __ULLONG_MAX 0xffffffffffffffffULL /* max for an unsigned long long */
-#define __LLONG_MAX 0x7fffffffffffffffLL /* max for a long long */
-#define __LLONG_MIN (-0x7fffffffffffffffLL-1) /* min for a long long */
-
-#define __SSIZE_MAX __LONG_MAX /* max value for a ssize_t */
-
-#define __SIZE_T_MAX __ULONG_MAX /* max value for a size_t */
-
-#define __OFF_MAX __LONG_MAX /* max value for an off_t */
-#define __OFF_MIN __LONG_MIN /* min value for an off_t */
-
-#ifdef AARCH32
-/* Quads and long longs are the same size. Ensure they stay in sync. */
-#define __UQUAD_MAX (__ULLONG_MAX) /* max value for a uquad_t */
-#define __QUAD_MAX (__LLONG_MAX) /* max value for a quad_t */
-#define __QUAD_MIN (__LLONG_MIN) /* min value for a quad_t */
-#else
-/* Quads and longs are the same size. Ensure they stay in sync. */
-#define __UQUAD_MAX (__ULONG_MAX) /* max value for a uquad_t */
-#define __QUAD_MAX (__LONG_MAX) /* max value for a quad_t */
-#define __QUAD_MIN (__LONG_MIN) /* min value for a quad_t */
-#endif
-
-#ifdef AARCH32
-#define __LONG_BIT 32
-#else
-#define __LONG_BIT 64
-#endif
-#define __WORD_BIT 32
-
-/* Minimum signal stack size. */
-#define __MINSIGSTKSZ (1024 * 4)
-
-#endif /* !_MACHINE__LIMITS_H_ */
diff --git a/include/lib/stdlib/machine/_stdint.h b/include/lib/stdlib/machine/_stdint.h
deleted file mode 100644
index ee5372d54..000000000
--- a/include/lib/stdlib/machine/_stdint.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*-
- * Copyright (c) 2001, 2002 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 2001 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Klaus Klein.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
- *
- * $FreeBSD$
- */
-
-/*
- * Portions copyright (c) 2016-2017, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _MACHINE__STDINT_H_
-#define _MACHINE__STDINT_H_
-
-#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
-
-#define INT8_C(c) (c)
-#define INT16_C(c) (c)
-#define INT32_C(c) (c)
-#define INT64_C(c) (c ## LL)
-
-#define UINT8_C(c) (c)
-#define UINT16_C(c) (c)
-#define UINT32_C(c) (c ## U)
-#define UINT64_C(c) (c ## ULL)
-
-#define INTMAX_C(c) INT64_C(c)
-#define UINTMAX_C(c) UINT64_C(c)
-
-#endif /* !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) */
-
-#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.2.1 Limits of exact-width integer types
- */
-/* Minimum values of exact-width signed integer types. */
-#define INT8_MIN (-0x7f-1)
-#define INT16_MIN (-0x7fff-1)
-#define INT32_MIN (-0x7fffffff-1)
-#define INT64_MIN (-0x7fffffffffffffffLL-1)
-
-/* Maximum values of exact-width signed integer types. */
-#define INT8_MAX 0x7f
-#define INT16_MAX 0x7fff
-#define INT32_MAX 0x7fffffff
-#define INT64_MAX 0x7fffffffffffffffLL
-
-/* Maximum values of exact-width unsigned integer types. */
-#define UINT8_MAX 0xff
-#define UINT16_MAX 0xffff
-#define UINT32_MAX 0xffffffffU
-#define UINT64_MAX 0xffffffffffffffffULL
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.2.2 Limits of minimum-width integer types
- */
-/* Minimum values of minimum-width signed integer types. */
-#define INT_LEAST8_MIN INT8_MIN
-#define INT_LEAST16_MIN INT16_MIN
-#define INT_LEAST32_MIN INT32_MIN
-#define INT_LEAST64_MIN INT64_MIN
-
-/* Maximum values of minimum-width signed integer types. */
-#define INT_LEAST8_MAX INT8_MAX
-#define INT_LEAST16_MAX INT16_MAX
-#define INT_LEAST32_MAX INT32_MAX
-#define INT_LEAST64_MAX INT64_MAX
-
-/* Maximum values of minimum-width unsigned integer types. */
-#define UINT_LEAST8_MAX UINT8_MAX
-#define UINT_LEAST16_MAX UINT16_MAX
-#define UINT_LEAST32_MAX UINT32_MAX
-#define UINT_LEAST64_MAX UINT64_MAX
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.2.3 Limits of fastest minimum-width integer types
- */
-/* Minimum values of fastest minimum-width signed integer types. */
-#define INT_FAST8_MIN INT32_MIN
-#define INT_FAST16_MIN INT32_MIN
-#define INT_FAST32_MIN INT32_MIN
-#define INT_FAST64_MIN INT64_MIN
-
-/* Maximum values of fastest minimum-width signed integer types. */
-#define INT_FAST8_MAX INT32_MAX
-#define INT_FAST16_MAX INT32_MAX
-#define INT_FAST32_MAX INT32_MAX
-#define INT_FAST64_MAX INT64_MAX
-
-/* Maximum values of fastest minimum-width unsigned integer types. */
-#define UINT_FAST8_MAX UINT32_MAX
-#define UINT_FAST16_MAX UINT32_MAX
-#define UINT_FAST32_MAX UINT32_MAX
-#define UINT_FAST64_MAX UINT64_MAX
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.2.4 Limits of integer types capable of holding object pointers
- */
-#ifdef AARCH32
-#define INTPTR_MIN INT32_MIN
-#define INTPTR_MAX INT32_MAX
-#define UINTPTR_MAX UINT32_MAX
-#else
-#define INTPTR_MIN INT64_MIN
-#define INTPTR_MAX INT64_MAX
-#define UINTPTR_MAX UINT64_MAX
-#endif
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.2.5 Limits of greatest-width integer types
- */
-#define INTMAX_MIN INT64_MIN
-#define INTMAX_MAX INT64_MAX
-#define UINTMAX_MAX UINT64_MAX
-
-/*
- * ISO/IEC 9899:1999
- * 7.18.3 Limits of other integer types
- */
-/* Limits of ptrdiff_t. */
-#ifdef AARCH32
-#define PTRDIFF_MIN INT32_MIN
-#define PTRDIFF_MAX INT32_MAX
-#else
-#define PTRDIFF_MIN INT64_MIN
-#define PTRDIFF_MAX INT64_MAX
-#endif
-
-/* Limits of sig_atomic_t. */
-#define SIG_ATOMIC_MIN INT32_MIN
-#define SIG_ATOMIC_MAX INT32_MAX
-
-/* Limit of size_t. */
-#ifdef AARCH32
-#define SIZE_MAX UINT32_MAX
-#else
-#define SIZE_MAX UINT64_MAX
-#endif
-
-#ifndef WCHAR_MIN /* Also possibly defined in <wchar.h> */
-/* Limits of wchar_t. */
-#define WCHAR_MIN INT32_MIN
-#define WCHAR_MAX INT32_MAX
-#endif
-
-/* Limits of wint_t. */
-#define WINT_MIN INT32_MIN
-#define WINT_MAX INT32_MAX
-
-#endif /* !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) */
-
-#endif /* !_MACHINE__STDINT_H_ */
diff --git a/include/lib/stdlib/machine/_types.h b/include/lib/stdlib/machine/_types.h
deleted file mode 100644
index 037fdf2f3..000000000
--- a/include/lib/stdlib/machine/_types.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*-
- * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * From: @(#)ansi.h 8.2 (Berkeley) 1/4/94
- * From: @(#)types.h 8.3 (Berkeley) 1/5/94
- * $FreeBSD$
- */
-/*
- * Portions copyright (c) 2016, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _MACHINE__TYPES_H_
-#define _MACHINE__TYPES_H_
-
-#ifndef _SYS_CDEFS_H_
-#error this file needs sys/cdefs.h as a prerequisite
-#endif
-
-/*
- * Basic types upon which most other types are built.
- */
-typedef __signed char __int8_t;
-typedef unsigned char __uint8_t;
-typedef short __int16_t;
-typedef unsigned short __uint16_t;
-typedef int __int32_t;
-typedef unsigned int __uint32_t;
-typedef long long __int64_t;
-typedef unsigned long long __uint64_t;
-
-/*
- * Standard type definitions.
- */
-typedef __int32_t __clock_t; /* clock()... */
-typedef long __critical_t;
-typedef double __double_t;
-typedef float __float_t;
-typedef long __intfptr_t;
-typedef __int64_t __intmax_t;
-typedef long __intptr_t;
-typedef __int32_t __int_fast8_t;
-typedef __int32_t __int_fast16_t;
-typedef __int32_t __int_fast32_t;
-typedef __int64_t __int_fast64_t;
-typedef __int8_t __int_least8_t;
-typedef __int16_t __int_least16_t;
-typedef __int32_t __int_least32_t;
-typedef __int64_t __int_least64_t;
-typedef long __ptrdiff_t; /* ptr1 - ptr2 */
-typedef long __register_t;
-typedef long __segsz_t; /* segment size (in pages) */
-#ifdef AARCH32
-typedef unsigned int __size_t; /* sizeof() */
-typedef int __ssize_t; /* byte count or error */
-#elif defined AARCH64
-typedef unsigned long __size_t; /* sizeof() */
-typedef long __ssize_t; /* byte count or error */
-#else
-#error "Only AArch32 or AArch64 supported"
-#endif /* AARCH32 */
-typedef __int64_t __time_t; /* time()... */
-typedef unsigned long __uintfptr_t;
-typedef __uint64_t __uintmax_t;
-typedef unsigned long __uintptr_t;
-typedef __uint32_t __uint_fast8_t;
-typedef __uint32_t __uint_fast16_t;
-typedef __uint32_t __uint_fast32_t;
-typedef __uint64_t __uint_fast64_t;
-typedef __uint8_t __uint_least8_t;
-typedef __uint16_t __uint_least16_t;
-typedef __uint32_t __uint_least32_t;
-typedef __uint64_t __uint_least64_t;
-typedef unsigned long __u_register_t;
-typedef unsigned long __vm_offset_t;
-typedef __int64_t __vm_ooffset_t;
-typedef unsigned long __vm_paddr_t;
-typedef __uint64_t __vm_pindex_t;
-typedef unsigned long __vm_size_t;
-
-/*
- * Unusual type definitions.
- */
-#ifdef __GNUCLIKE_BUILTIN_VARARGS
-typedef __builtin_va_list __va_list; /* internally known to gcc */
-#else
-typedef char * __va_list;
-#endif /* __GNUCLIKE_BUILTIN_VARARGS */
-#if defined(__GNUCLIKE_BUILTIN_VAALIST) && !defined(__GNUC_VA_LIST) \
- && !defined(__NO_GNUC_VA_LIST)
-#define __GNUC_VA_LIST
-typedef __va_list __gnuc_va_list; /* compatibility w/GNU headers*/
-#endif
-
-#endif /* !_MACHINE__TYPES_H_ */
diff --git a/include/lib/stdlib/stdbool.h b/include/lib/stdlib/stdbool.h
deleted file mode 100644
index 48070c18d..000000000
--- a/include/lib/stdlib/stdbool.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2000 Jeroen Ruigrok van der Werven <asmodai@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef __bool_true_false_are_defined
-#define __bool_true_false_are_defined 1
-
-#ifndef __cplusplus
-
-#define false 0
-#define true 1
-
-#define bool _Bool
-#if __STDC_VERSION__ < 199901L && __GNUC__ < 3 && !defined(__INTEL_COMPILER)
-typedef int _Bool;
-#endif
-
-#endif /* !__cplusplus */
-#endif /* __bool_true_false_are_defined */
diff --git a/include/lib/stdlib/stddef.h b/include/lib/stdlib/stddef.h
deleted file mode 100644
index ea88214f7..000000000
--- a/include/lib/stdlib/stddef.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)stddef.h 8.1 (Berkeley) 6/2/93
- *
- * $FreeBSD$
- */
-
-#ifndef _STDDEF_H_
-#define _STDDEF_H_
-
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
-
-typedef __ptrdiff_t ptrdiff_t;
-
-#if __BSD_VISIBLE
-#ifndef _RUNE_T_DECLARED
-typedef __rune_t rune_t;
-#define _RUNE_T_DECLARED
-#endif
-#endif
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-#ifndef __cplusplus
-#ifndef _WCHAR_T_DECLARED
-typedef __wchar_t wchar_t;
-#define _WCHAR_T_DECLARED
-#endif
-#endif
-
-#define offsetof(type, member) __offsetof(type, member)
-
-#endif /* _STDDEF_H_ */
diff --git a/include/lib/stdlib/stdio.h b/include/lib/stdlib/stdio.h
deleted file mode 100644
index 57e5c7fa4..000000000
--- a/include/lib/stdlib/stdio.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)stdio.h 8.5 (Berkeley) 4/29/95
- * $FreeBSD$
- */
-
-/*
- * Portions copyright (c) 2013-2014, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-
-#ifndef _STDIO_H_
-#define _STDIO_H_
-
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-#ifndef _SSIZE_T_DECLARED
-#define _SSIZE_T_DECLARED
-typedef __ssize_t ssize_t;
-#endif
-
-#define EOF (-1)
-
-int printf(const char * __restrict, ...) __printflike(1, 2);
-int putchar(int);
-int puts(const char *);
-int sprintf(char * __restrict, const char * __restrict, ...)
- __printflike(2, 3);
-int vsprintf(char * __restrict, const char * __restrict,
- __va_list) __printflike(2, 0);
-
-int sscanf(const char *__restrict, char const *__restrict, ...);
-
-#if __ISO_C_VISIBLE >= 1999
-int snprintf(char * __restrict, size_t, const char * __restrict,
- ...) __printflike(3, 4);
-int vsnprintf(char * __restrict, size_t, const char * __restrict,
- __va_list) __printflike(3, 0);
-#endif
-
-#endif /* !_STDIO_H_ */
diff --git a/include/lib/stdlib/stdlib.h b/include/lib/stdlib/stdlib.h
deleted file mode 100644
index b1ac1bf94..000000000
--- a/include/lib/stdlib/stdlib.h
+++ /dev/null
@@ -1,313 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)stdlib.h 8.5 (Berkeley) 5/19/95
- * $FreeBSD$
- */
-
-#ifndef _STDLIB_H_
-#define _STDLIB_H_
-
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
-
-#if __BSD_VISIBLE
-#ifndef _RUNE_T_DECLARED
-typedef __rune_t rune_t;
-#define _RUNE_T_DECLARED
-#endif
-#endif
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-typedef struct {
- int quot; /* quotient */
- int rem; /* remainder */
-} div_t;
-
-typedef struct {
- long quot;
- long rem;
-} ldiv_t;
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#define RAND_MAX 0x7ffffffd
-
-__BEGIN_DECLS
-#ifdef _XLOCALE_H_
-#include <xlocale/_stdlib.h>
-#endif
-extern int __mb_cur_max;
-extern int ___mb_cur_max(void);
-#define MB_CUR_MAX (___mb_cur_max())
-
-_Noreturn void abort(void);
-int abs(int) __pure2;
-int atexit(void (*)(void));
-double atof(const char *);
-int atoi(const char *);
-long atol(const char *);
-void *bsearch(const void *, const void *, size_t,
- size_t, int (*)(const void *, const void *));
-void *calloc(size_t, size_t) __malloc_like;
-div_t div(int, int) __pure2;
-_Noreturn void exit(int);
-void free(void *);
-char *getenv(const char *);
-long labs(long) __pure2;
-ldiv_t ldiv(long, long) __pure2;
-void *malloc(size_t) __malloc_like;
-int mblen(const char *, size_t);
-void qsort(void *, size_t, size_t,
- int (*)(const void *, const void *));
-int rand(void);
-void *realloc(void *, size_t);
-void srand(unsigned);
-double strtod(const char *__restrict, char **__restrict);
-float strtof(const char *__restrict, char **__restrict);
-long strtol(const char *__restrict, char **__restrict, int);
-long double
- strtold(const char *__restrict, char **__restrict);
-unsigned long
- strtoul(const char *__restrict, char **__restrict, int);
-int system(const char *);
-
-/*
- * Functions added in C99 which we make conditionally available in the
- * BSD^C89 namespace if the compiler supports `long long'.
- * The #if test is more complicated than it ought to be because
- * __BSD_VISIBLE implies __ISO_C_VISIBLE == 1999 *even if* `long long'
- * is not supported in the compilation environment (which therefore means
- * that it can't really be ISO C99).
- *
- * (The only other extension made by C99 in thie header is _Exit().)
- */
-#if __ISO_C_VISIBLE >= 1999
-#ifdef __LONG_LONG_SUPPORTED
-/* LONGLONG */
-typedef struct {
- long long quot;
- long long rem;
-} lldiv_t;
-
-/* LONGLONG */
-long long
- atoll(const char *);
-/* LONGLONG */
-long long
- llabs(long long) __pure2;
-/* LONGLONG */
-lldiv_t lldiv(long long, long long) __pure2;
-/* LONGLONG */
-long long
- strtoll(const char *__restrict, char **__restrict, int);
-/* LONGLONG */
-unsigned long long
- strtoull(const char *__restrict, char **__restrict, int);
-#endif /* __LONG_LONG_SUPPORTED */
-
-_Noreturn void _Exit(int);
-#endif /* __ISO_C_VISIBLE >= 1999 */
-
-/*
- * If we're in a mode greater than C99, expose C11 functions.
- */
-#if __ISO_C_VISIBLE >= 2011 || __cplusplus >= 201103L
-void *aligned_alloc(size_t, size_t) __malloc_like;
-int at_quick_exit(void (*)(void));
-_Noreturn void
- quick_exit(int);
-#endif /* __ISO_C_VISIBLE >= 2011 */
-/*
- * Extensions made by POSIX relative to C.
- */
-#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
-char *realpath(const char *__restrict, char *__restrict);
-#endif
-#if __POSIX_VISIBLE >= 199506
-int rand_r(unsigned *); /* (TSF) */
-#endif
-#if __POSIX_VISIBLE >= 200112
-int posix_memalign(void **, size_t, size_t); /* (ADV) */
-int setenv(const char *, const char *, int);
-int unsetenv(const char *);
-#endif
-
-#if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE
-int getsubopt(char **, char *const *, char **);
-#ifndef _MKDTEMP_DECLARED
-char *mkdtemp(char *);
-#define _MKDTEMP_DECLARED
-#endif
-#ifndef _MKSTEMP_DECLARED
-int mkstemp(char *);
-#define _MKSTEMP_DECLARED
-#endif
-#endif /* __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE */
-
-/*
- * The only changes to the XSI namespace in revision 6 were the deletion
- * of the ttyslot() and valloc() functions, which FreeBSD never declared
- * in this header. For revision 7, ecvt(), fcvt(), and gcvt(), which
- * FreeBSD also does not have, and mktemp(), are to be deleted.
- */
-#if __XSI_VISIBLE
-/* XXX XSI requires pollution from <sys/wait.h> here. We'd rather not. */
-long a64l(const char *);
-double drand48(void);
-/* char *ecvt(double, int, int * __restrict, int * __restrict); */
-double erand48(unsigned short[3]);
-/* char *fcvt(double, int, int * __restrict, int * __restrict); */
-/* char *gcvt(double, int, int * __restrict, int * __restrict); */
-int grantpt(int);
-char *initstate(unsigned long /* XSI requires u_int */, char *, long);
-long jrand48(unsigned short[3]);
-char *l64a(long);
-void lcong48(unsigned short[7]);
-long lrand48(void);
-#if !defined(_MKTEMP_DECLARED) && (__BSD_VISIBLE || __XSI_VISIBLE <= 600)
-char *mktemp(char *);
-#define _MKTEMP_DECLARED
-#endif
-long mrand48(void);
-long nrand48(unsigned short[3]);
-int posix_openpt(int);
-char *ptsname(int);
-int putenv(char *);
-long random(void);
-unsigned short
- *seed48(unsigned short[3]);
-#ifndef _SETKEY_DECLARED
-int setkey(const char *);
-#define _SETKEY_DECLARED
-#endif
-char *setstate(/* const */ char *);
-void srand48(long);
-void srandom(unsigned long);
-int unlockpt(int);
-#endif /* __XSI_VISIBLE */
-
-#if __BSD_VISIBLE
-extern const char *malloc_conf;
-extern void (*malloc_message)(void *, const char *);
-
-/*
- * The alloca() function can't be implemented in C, and on some
- * platforms it can't be implemented at all as a callable function.
- * The GNU C compiler provides a built-in alloca() which we can use;
- * in all other cases, provide a prototype, mainly to pacify various
- * incarnations of lint. On platforms where alloca() is not in libc,
- * programs which use it will fail to link when compiled with non-GNU
- * compilers.
- */
-#if __GNUC__ >= 2 || defined(__INTEL_COMPILER)
-#undef alloca /* some GNU bits try to get cute and define this on their own */
-#define alloca(sz) __builtin_alloca(sz)
-#elif defined(lint)
-void *alloca(size_t);
-#endif
-
-void abort2(const char *, int, void **) __dead2;
-__uint32_t
- arc4random(void);
-void arc4random_addrandom(unsigned char *, int);
-void arc4random_buf(void *, size_t);
-void arc4random_stir(void);
-__uint32_t
- arc4random_uniform(__uint32_t);
-#ifdef __BLOCKS__
-int atexit_b(void (^)(void));
-void *bsearch_b(const void *, const void *, size_t,
- size_t, int (^)(const void *, const void *));
-#endif
-char *getbsize(int *, long *);
- /* getcap(3) functions */
-char *cgetcap(char *, const char *, int);
-int cgetclose(void);
-int cgetent(char **, char **, const char *);
-int cgetfirst(char **, char **);
-int cgetmatch(const char *, const char *);
-int cgetnext(char **, char **);
-int cgetnum(char *, const char *, long *);
-int cgetset(const char *);
-int cgetstr(char *, const char *, char **);
-int cgetustr(char *, const char *, char **);
-
-int daemon(int, int);
-char *devname(__dev_t, __mode_t);
-char *devname_r(__dev_t, __mode_t, char *, int);
-char *fdevname(int);
-char *fdevname_r(int, char *, int);
-int getloadavg(double [], int);
-const char *
- getprogname(void);
-
-int heapsort(void *, size_t, size_t, int (*)(const void *, const void *));
-#ifdef __BLOCKS__
-int heapsort_b(void *, size_t, size_t, int (^)(const void *, const void *));
-void qsort_b(void *, size_t, size_t,
- int (^)(const void *, const void *));
-#endif
-int l64a_r(long, char *, int);
-int mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
-#ifdef __BLOCKS__
-int mergesort_b(void *, size_t, size_t, int (^)(const void *, const void *));
-#endif
-int mkostemp(char *, int);
-int mkostemps(char *, int, int);
-void qsort_r(void *, size_t, size_t, void *,
- int (*)(void *, const void *, const void *));
-int radixsort(const unsigned char **, int, const unsigned char *,
- unsigned);
-void *reallocf(void *, size_t);
-int rpmatch(const char *);
-void setprogname(const char *);
-int sradixsort(const unsigned char **, int, const unsigned char *,
- unsigned);
-void sranddev(void);
-void srandomdev(void);
-long long
- strtonum(const char *, long long, long long, const char **);
-
-/* Deprecated interfaces, to be removed in FreeBSD 6.0. */
-__int64_t
- strtoq(const char *, char **, int);
-__uint64_t
- strtouq(const char *, char **, int);
-
-extern char *suboptarg; /* getsubopt(3) external variable */
-#endif /* __BSD_VISIBLE */
-__END_DECLS
-
-#endif /* !_STDLIB_H_ */
diff --git a/include/lib/stdlib/string.h b/include/lib/stdlib/string.h
deleted file mode 100644
index 56677b2cf..000000000
--- a/include/lib/stdlib/string.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)string.h 8.1 (Berkeley) 6/2/93
- * $FreeBSD$
- */
-
-/*
- * Portions copyright (c) 2013-2017, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _STRING_H_
-#define _STRING_H_
-
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-__BEGIN_DECLS
-
-void *memchr(const void *, int, size_t) __pure;
-int memcmp(const void *, const void *, size_t) __pure;
-void *memcpy(void * __restrict, const void * __restrict, size_t);
-void *memcpy16(void * __restrict, const void * __restrict, size_t);
-void *memmove(void *, const void *, size_t);
-void *memset(void *, int, size_t);
-
-char *strchr(const char *, int) __pure;
-int strcmp(const char *, const char *) __pure;
-size_t strlen(const char *) __pure;
-int strncmp(const char *, const char *, size_t) __pure;
-size_t strnlen(const char *, size_t) __pure;
-int strcasecmp(const char *, const char *);
-int timingsafe_bcmp(const void *, const void *, size_t);
-
-__END_DECLS
-
-#endif /* _STRING_H_ */
diff --git a/include/lib/stdlib/strings.h b/include/lib/stdlib/strings.h
deleted file mode 100644
index 2210df04f..000000000
--- a/include/lib/stdlib/strings.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _STRINGS_H_
-#define _STRINGS_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-__BEGIN_DECLS
-#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
-int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */
-void bcopy(const void *, void *, size_t); /* LEGACY */
-void bzero(void *, size_t); /* LEGACY */
-#endif
-#if __BSD_VISIBLE
-void explicit_bzero(void *, size_t);
-#endif
-#if __XSI_VISIBLE
-int ffs(int) __pure2;
-#endif
-#if __BSD_VISIBLE
-int ffsl(long) __pure2;
-int ffsll(long long) __pure2;
-int fls(int) __pure2;
-int flsl(long) __pure2;
-int flsll(long long) __pure2;
-#endif
-#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
-char *index(const char *, int) __pure; /* LEGACY */
-char *rindex(const char *, int) __pure; /* LEGACY */
-#endif
-int strcasecmp(const char *, const char *) __pure;
-int strncasecmp(const char *, const char *, size_t) __pure;
-
-#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
-#include <xlocale/_strings.h>
-#endif
-__END_DECLS
-
-#endif /* _STRINGS_H_ */
diff --git a/include/lib/stdlib/sys/_null.h b/include/lib/stdlib/sys/_null.h
deleted file mode 100644
index 92706c6a0..000000000
--- a/include/lib/stdlib/sys/_null.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 2003 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef NULL
-
-#if !defined(__cplusplus)
-#define NULL ((void *)0)
-#else
-#if __cplusplus >= 201103L
-#define NULL nullptr
-#elif defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4
-#define NULL __null
-#else
-#if defined(__LP64__)
-#define NULL (0L)
-#else
-#define NULL 0
-#endif /* __LP64__ */
-#endif /* __GNUG__ */
-#endif /* !__cplusplus */
-
-#endif
diff --git a/include/lib/stdlib/sys/_stdint.h b/include/lib/stdlib/sys/_stdint.h
deleted file mode 100644
index d0f92493b..000000000
--- a/include/lib/stdlib/sys/_stdint.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*-
- * Copyright (c) 2011 David E. O'Brien <obrien@FreeBSD.org>
- * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS__STDINT_H_
-#define _SYS__STDINT_H_
-
-#ifndef _INT8_T_DECLARED
-typedef __int8_t int8_t;
-#define _INT8_T_DECLARED
-#endif
-
-#ifndef _INT16_T_DECLARED
-typedef __int16_t int16_t;
-#define _INT16_T_DECLARED
-#endif
-
-#ifndef _INT32_T_DECLARED
-typedef __int32_t int32_t;
-#define _INT32_T_DECLARED
-#endif
-
-#ifndef _INT64_T_DECLARED
-typedef __int64_t int64_t;
-#define _INT64_T_DECLARED
-#endif
-
-#ifndef _UINT8_T_DECLARED
-typedef __uint8_t uint8_t;
-#define _UINT8_T_DECLARED
-#endif
-
-#ifndef _UINT16_T_DECLARED
-typedef __uint16_t uint16_t;
-#define _UINT16_T_DECLARED
-#endif
-
-#ifndef _UINT32_T_DECLARED
-typedef __uint32_t uint32_t;
-#define _UINT32_T_DECLARED
-#endif
-
-#ifndef _UINT64_T_DECLARED
-typedef __uint64_t uint64_t;
-#define _UINT64_T_DECLARED
-#endif
-
-#ifndef _INTPTR_T_DECLARED
-typedef __intptr_t intptr_t;
-#define _INTPTR_T_DECLARED
-#endif
-#ifndef _UINTPTR_T_DECLARED
-typedef __uintptr_t uintptr_t;
-#define _UINTPTR_T_DECLARED
-#endif
-
-#endif /* !_SYS__STDINT_H_ */
diff --git a/include/lib/stdlib/sys/_timespec.h b/include/lib/stdlib/sys/_timespec.h
deleted file mode 100644
index d51559c2a..000000000
--- a/include/lib/stdlib/sys/_timespec.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)time.h 8.5 (Berkeley) 5/4/95
- * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
- * $FreeBSD$
- */
-
-#ifndef _SYS__TIMESPEC_H_
-#define _SYS__TIMESPEC_H_
-
-#include <sys/_types.h>
-
-#ifndef _TIME_T_DECLARED
-typedef __time_t time_t;
-#define _TIME_T_DECLARED
-#endif
-
-struct timespec {
- time_t tv_sec; /* seconds */
- long tv_nsec; /* and nanoseconds */
-};
-
-#endif /* !_SYS__TIMESPEC_H_ */
diff --git a/include/lib/stdlib/sys/_types.h b/include/lib/stdlib/sys/_types.h
deleted file mode 100644
index c59afd31c..000000000
--- a/include/lib/stdlib/sys/_types.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*-
- * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS__TYPES_H_
-#define _SYS__TYPES_H_
-
-#include <sys/cdefs.h>
-#include <machine/_types.h>
-
-/*
- * Standard type definitions.
- */
-typedef __uint32_t __blksize_t; /* file block size */
-typedef __int64_t __blkcnt_t; /* file block count */
-typedef __int32_t __clockid_t; /* clock_gettime()... */
-typedef __uint64_t __cap_rights_t; /* capability rights */
-typedef __uint32_t __fflags_t; /* file flags */
-typedef __uint64_t __fsblkcnt_t;
-typedef __uint64_t __fsfilcnt_t;
-typedef __uint32_t __gid_t;
-typedef __int64_t __id_t; /* can hold a gid_t, pid_t, or uid_t */
-typedef __uint32_t __ino_t; /* inode number */
-typedef long __key_t; /* IPC key (for Sys V IPC) */
-typedef __int32_t __lwpid_t; /* Thread ID (a.k.a. LWP) */
-typedef __uint16_t __mode_t; /* permissions */
-typedef int __accmode_t; /* access permissions */
-typedef int __nl_item;
-typedef __uint16_t __nlink_t; /* link count */
-typedef __int64_t __off_t; /* file offset */
-typedef __int32_t __pid_t; /* process [group] */
-typedef __int64_t __rlim_t; /* resource limit - intentionally */
- /* signed, because of legacy code */
- /* that uses -1 for RLIM_INFINITY */
-typedef __uint8_t __sa_family_t;
-typedef __uint32_t __socklen_t;
-typedef long __suseconds_t; /* microseconds (signed) */
-typedef struct __timer *__timer_t; /* timer_gettime()... */
-typedef struct __mq *__mqd_t; /* mq_open()... */
-typedef __uint32_t __uid_t;
-typedef unsigned int __useconds_t; /* microseconds (unsigned) */
-typedef int __cpuwhich_t; /* which parameter for cpuset. */
-typedef int __cpulevel_t; /* level parameter for cpuset. */
-typedef int __cpusetid_t; /* cpuset identifier. */
-
-/*
- * Unusual type definitions.
- */
-/*
- * rune_t is declared to be an ``int'' instead of the more natural
- * ``unsigned long'' or ``long''. Two things are happening here. It is not
- * unsigned so that EOF (-1) can be naturally assigned to it and used. Also,
- * it looks like 10646 will be a 31 bit standard. This means that if your
- * ints cannot hold 32 bits, you will be in trouble. The reason an int was
- * chosen over a long is that the is*() and to*() routines take ints (says
- * ANSI C), but they use __ct_rune_t instead of int.
- *
- * NOTE: rune_t is not covered by ANSI nor other standards, and should not
- * be instantiated outside of lib/libc/locale. Use wchar_t. wchar_t and
- * rune_t must be the same type. Also, wint_t must be no narrower than
- * wchar_t, and should be able to hold all members of the largest
- * character set plus one extra value (WEOF), and must be at least 16 bits.
- */
-typedef int __ct_rune_t; /* arg type for ctype funcs */
-typedef __ct_rune_t __rune_t; /* rune_t (see above) */
-typedef __ct_rune_t __wchar_t; /* wchar_t (see above) */
-typedef __ct_rune_t __wint_t; /* wint_t (see above) */
-
-typedef __uint32_t __dev_t; /* device number */
-
-typedef __uint32_t __fixpt_t; /* fixed point number */
-
-/*
- * mbstate_t is an opaque object to keep conversion state during multibyte
- * stream conversions.
- */
-typedef union {
- char __mbstate8[128];
- __int64_t _mbstateL; /* for alignment */
-} __mbstate_t;
-
-#endif /* !_SYS__TYPES_H_ */
diff --git a/include/lib/stdlib/sys/cdefs.h b/include/lib/stdlib/sys/cdefs.h
deleted file mode 100644
index 70c09fdbb..000000000
--- a/include/lib/stdlib/sys/cdefs.h
+++ /dev/null
@@ -1,688 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Berkeley Software Design, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)cdefs.h 8.8 (Berkeley) 1/9/95
- * $FreeBSD$
- */
-
-#ifndef _SYS_CDEFS_H_
-#define _SYS_CDEFS_H_
-
-#if defined(__cplusplus)
-#define __BEGIN_DECLS extern "C" {
-#define __END_DECLS }
-#else
-#define __BEGIN_DECLS
-#define __END_DECLS
-#endif
-
-/*
- * This code has been put in place to help reduce the addition of
- * compiler specific defines in FreeBSD code. It helps to aid in
- * having a compiler-agnostic source tree.
- */
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER)
-
-#if __GNUC__ >= 3 || defined(__INTEL_COMPILER)
-#define __GNUCLIKE_ASM 3
-#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS
-#else
-#define __GNUCLIKE_ASM 2
-#endif
-#define __GNUCLIKE___TYPEOF 1
-#define __GNUCLIKE___OFFSETOF 1
-#define __GNUCLIKE___SECTION 1
-
-#ifndef __INTEL_COMPILER
-# define __GNUCLIKE_CTOR_SECTION_HANDLING 1
-#endif
-
-#define __GNUCLIKE_BUILTIN_CONSTANT_P 1
-# if defined(__INTEL_COMPILER) && defined(__cplusplus) \
- && __INTEL_COMPILER < 800
-# undef __GNUCLIKE_BUILTIN_CONSTANT_P
-# endif
-
-#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER)
-# define __GNUCLIKE_BUILTIN_VARARGS 1
-# define __GNUCLIKE_BUILTIN_STDARG 1
-# define __GNUCLIKE_BUILTIN_VAALIST 1
-#endif
-
-#if defined(__GNUC__)
-# define __GNUC_VA_LIST_COMPATIBILITY 1
-#endif
-
-#ifndef __INTEL_COMPILER
-# define __GNUCLIKE_BUILTIN_NEXT_ARG 1
-# define __GNUCLIKE_MATH_BUILTIN_RELOPS
-#endif
-
-#define __GNUCLIKE_BUILTIN_MEMCPY 1
-
-/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */
-#define __CC_SUPPORTS_INLINE 1
-#define __CC_SUPPORTS___INLINE 1
-#define __CC_SUPPORTS___INLINE__ 1
-
-#define __CC_SUPPORTS___FUNC__ 1
-#define __CC_SUPPORTS_WARNING 1
-
-#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */
-
-#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1
-
-#endif /* __GNUC__ || __INTEL_COMPILER */
-
-/*
- * Macro to test if we're using a specific version of gcc or later.
- */
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-#define __GNUC_PREREQ__(ma, mi) \
- (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
-#else
-#define __GNUC_PREREQ__(ma, mi) 0
-#endif
-
-/*
- * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
- * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
- * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
- * mode -- there must be no spaces between its arguments, and for nested
- * __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also
- * concatenate double-quoted strings produced by the __STRING macro, but
- * this only works with ANSI C.
- *
- * __XSTRING is like __STRING, but it expands any macros in its argument
- * first. It is only available with ANSI C.
- */
-#if defined(__STDC__) || defined(__cplusplus)
-#define __P(protos) protos /* full-blown ANSI C */
-#define __CONCAT1(x,y) x ## y
-#define __CONCAT(x,y) __CONCAT1(x,y)
-#define __STRING(x) #x /* stringify without expanding x */
-#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
-
-#define __const const /* define reserved names to standard */
-#define __signed signed
-#define __volatile volatile
-#if defined(__cplusplus)
-#define __inline inline /* convert to C++ keyword */
-#else
-#if !(defined(__CC_SUPPORTS___INLINE))
-#define __inline /* delete GCC keyword */
-#endif /* ! __CC_SUPPORTS___INLINE */
-#endif /* !__cplusplus */
-
-#else /* !(__STDC__ || __cplusplus) */
-#define __P(protos) () /* traditional C preprocessor */
-#define __CONCAT(x,y) x/**/y
-#define __STRING(x) "x"
-
-#if !defined(__CC_SUPPORTS___INLINE)
-#define __const /* delete pseudo-ANSI C keywords */
-#define __inline
-#define __signed
-#define __volatile
-/*
- * In non-ANSI C environments, new programs will want ANSI-only C keywords
- * deleted from the program and old programs will want them left alone.
- * When using a compiler other than gcc, programs using the ANSI C keywords
- * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
- * When using "gcc -traditional", we assume that this is the intent; if
- * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
- */
-#ifndef NO_ANSI_KEYWORDS
-#define const /* delete ANSI C keywords */
-#define inline
-#define signed
-#define volatile
-#endif /* !NO_ANSI_KEYWORDS */
-#endif /* !__CC_SUPPORTS___INLINE */
-#endif /* !(__STDC__ || __cplusplus) */
-
-/*
- * Compiler-dependent macros to help declare dead (non-returning) and
- * pure (no side effects) functions, and unused variables. They are
- * null except for versions of gcc that are known to support the features
- * properly (old versions of gcc-2 supported the dead and pure features
- * in a different (wrong) way). If we do not provide an implementation
- * for a given compiler, let the compile fail if it is told to use
- * a feature that we cannot live without.
- */
-#ifdef lint
-#define __dead2
-#define __pure2
-#define __unused
-#define __packed
-#define __aligned(x)
-#define __section(x)
-#else
-#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
-#define __dead2
-#define __pure2
-#define __unused
-#endif
-#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
-#define __dead2 __attribute__((__noreturn__))
-#define __pure2 __attribute__((__const__))
-#define __unused
-/* XXX Find out what to do for __packed, __aligned and __section */
-#endif
-#if __GNUC_PREREQ__(2, 7)
-#define __dead2 __attribute__((__noreturn__))
-#define __pure2 __attribute__((__const__))
-#define __unused __attribute__((__unused__))
-#define __used __attribute__((__used__))
-#define __packed __attribute__((__packed__))
-#define __aligned(x) __attribute__((__aligned__(x)))
-#define __section(x) __attribute__((__section__(x)))
-#endif
-#if defined(__INTEL_COMPILER)
-#define __dead2 __attribute__((__noreturn__))
-#define __pure2 __attribute__((__const__))
-#define __unused __attribute__((__unused__))
-#define __used __attribute__((__used__))
-#define __packed __attribute__((__packed__))
-#define __aligned(x) __attribute__((__aligned__(x)))
-#define __section(x) __attribute__((__section__(x)))
-#endif
-#endif
-
-#if !__GNUC_PREREQ__(2, 95)
-#define __alignof(x) __offsetof(struct { char __a; x __b; }, __b)
-#endif
-
-/*
- * Keywords added in C11.
- */
-#if defined(__cplusplus) && __cplusplus >= 201103L
-#define _Alignas(e) alignas(e)
-#define _Alignof(e) alignof(e)
-#define _Noreturn [[noreturn]]
-#define _Static_assert(e, s) static_assert(e, s)
-/* FIXME: change this to thread_local when clang in base supports it */
-#define _Thread_local __thread
-#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
-/* Do nothing. They are language keywords. */
-#else
-/* Not supported. Implement them using our versions. */
-#define _Alignas(x) __aligned(x)
-#define _Alignof(x) __alignof(x)
-#define _Noreturn __dead2
-#define _Thread_local __thread
-#ifdef __COUNTER__
-#define _Static_assert(x, y) __Static_assert(x, __COUNTER__)
-#define __Static_assert(x, y) ___Static_assert(x, y)
-#define ___Static_assert(x, y) typedef char __assert_ ## y[(x) ? 1 : -1]
-#else
-#define _Static_assert(x, y) struct __hack
-#endif
-#endif
-
-/*
- * Emulation of C11 _Generic(). Unlike the previously defined C11
- * keywords, it is not possible to implement this using exactly the same
- * syntax. Therefore implement something similar under the name
- * __generic(). Unlike _Generic(), this macro can only distinguish
- * between a single type, so it requires nested invocations to
- * distinguish multiple cases.
- */
-
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
-#define __generic(expr, t, yes, no) \
- _Generic(expr, t: yes, default: no)
-#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
-#define __generic(expr, t, yes, no) \
- __builtin_choose_expr( \
- __builtin_types_compatible_p(__typeof(expr), t), yes, no)
-#endif
-
-#if __GNUC_PREREQ__(2, 96)
-#define __malloc_like __attribute__((__malloc__))
-#define __pure __attribute__((__pure__))
-#else
-#define __malloc_like
-#define __pure
-#endif
-
-#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
-#define __always_inline __attribute__((__always_inline__))
-#else
-#define __always_inline
-#endif
-
-#if __GNUC_PREREQ__(3, 1)
-#define __noinline __attribute__ ((__noinline__))
-#define __deprecated __attribute__ ((__deprecated__))
-#else
-#define __noinline
-#define __deprecated
-#endif
-
-#if __GNUC_PREREQ__(3, 3)
-#define __nonnull(x) __attribute__((__nonnull__(x)))
-#else
-#define __nonnull(x)
-#endif
-
-#if __GNUC_PREREQ__(3, 4)
-#define __fastcall __attribute__((__fastcall__))
-#else
-#define __fastcall
-#endif
-
-#if __GNUC_PREREQ__(4, 1)
-#define __returns_twice __attribute__((__returns_twice__))
-#else
-#define __returns_twice
-#endif
-
-/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
-#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
-#define __func__ NULL
-#endif
-
-#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
-#define __LONG_LONG_SUPPORTED
-#endif
-
-/* C++11 exposes a load of C99 stuff */
-#if defined(__cplusplus) && __cplusplus >= 201103L
-#define __LONG_LONG_SUPPORTED
-#ifndef __STDC_LIMIT_MACROS
-#define __STDC_LIMIT_MACROS
-#endif
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#endif
-
-/*
- * GCC 2.95 provides `__restrict' as an extension to C90 to support the
- * C99-specific `restrict' type qualifier. We happen to use `__restrict' as
- * a way to define the `restrict' type qualifier without disturbing older
- * software that is unaware of C99 keywords.
- */
-#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
-#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901 || defined(lint)
-#define __restrict
-#else
-#define __restrict restrict
-#endif
-#endif
-
-/*
- * GNU C version 2.96 adds explicit branch prediction so that
- * the CPU back-end can hint the processor and also so that
- * code blocks can be reordered such that the predicted path
- * sees a more linear flow, thus improving cache behavior, etc.
- *
- * The following two macros provide us with a way to utilize this
- * compiler feature. Use __predict_true() if you expect the expression
- * to evaluate to true, and __predict_false() if you expect the
- * expression to evaluate to false.
- *
- * A few notes about usage:
- *
- * * Generally, __predict_false() error condition checks (unless
- * you have some _strong_ reason to do otherwise, in which case
- * document it), and/or __predict_true() `no-error' condition
- * checks, assuming you want to optimize for the no-error case.
- *
- * * Other than that, if you don't know the likelihood of a test
- * succeeding from empirical or other `hard' evidence, don't
- * make predictions.
- *
- * * These are meant to be used in places that are run `a lot'.
- * It is wasteful to make predictions in code that is run
- * seldomly (e.g. at subsystem initialization time) as the
- * basic block reordering that this affects can often generate
- * larger code.
- */
-#if __GNUC_PREREQ__(2, 96)
-#define __predict_true(exp) __builtin_expect((exp), 1)
-#define __predict_false(exp) __builtin_expect((exp), 0)
-#else
-#define __predict_true(exp) (exp)
-#define __predict_false(exp) (exp)
-#endif
-
-#if __GNUC_PREREQ__(4, 2)
-#define __hidden __attribute__((__visibility__("hidden")))
-#define __exported __attribute__((__visibility__("default")))
-#else
-#define __hidden
-#define __exported
-#endif
-
-/*
- * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
- * require it.
- */
-#if __GNUC_PREREQ__(4, 1)
-#define __offsetof(type, field) __builtin_offsetof(type, field)
-#else
-#ifndef __cplusplus
-#define __offsetof(type, field) \
- ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
-#else
-#define __offsetof(type, field) \
- (__offsetof__ (reinterpret_cast <__size_t> \
- (&reinterpret_cast <const volatile char &> \
- (static_cast<type *> (0)->field))))
-#endif
-#endif
-#define __rangeof(type, start, end) \
- (__offsetof(type, end) - __offsetof(type, start))
-
-/*
- * Given the pointer x to the member m of the struct s, return
- * a pointer to the containing structure. When using GCC, we first
- * assign pointer x to a local variable, to check that its type is
- * compatible with member m.
- */
-#if __GNUC_PREREQ__(3, 1)
-#define __containerof(x, s, m) ({ \
- const volatile __typeof(((s *)0)->m) *__x = (x); \
- __DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
-})
-#else
-#define __containerof(x, s, m) \
- __DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
-#endif
-
-/*
- * Compiler-dependent macros to declare that functions take printf-like
- * or scanf-like arguments. They are null except for versions of gcc
- * that are known to support the features properly (old versions of gcc-2
- * didn't permit keeping the keywords out of the application namespace).
- */
-#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
-#define __printflike(fmtarg, firstvararg)
-#define __scanflike(fmtarg, firstvararg)
-#define __format_arg(fmtarg)
-#define __strfmonlike(fmtarg, firstvararg)
-#define __strftimelike(fmtarg, firstvararg)
-#else
-#define __printflike(fmtarg, firstvararg) \
- __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
-#define __scanflike(fmtarg, firstvararg) \
- __attribute__((__format__ (__scanf__, fmtarg, firstvararg)))
-#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg)))
-#define __strfmonlike(fmtarg, firstvararg) \
- __attribute__((__format__ (__strfmon__, fmtarg, firstvararg)))
-#define __strftimelike(fmtarg, firstvararg) \
- __attribute__((__format__ (__strftime__, fmtarg, firstvararg)))
-#endif
-
-/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
-#if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER)
-#define __printf0like(fmtarg, firstvararg) \
- __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
-#else
-#define __printf0like(fmtarg, firstvararg)
-#endif
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER)
-#ifndef __INTEL_COMPILER
-#define __strong_reference(sym,aliassym) \
- extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
-#endif
-#ifdef __STDC__
-#define __weak_reference(sym,alias) \
- __asm__(".weak " #alias); \
- __asm__(".equ " #alias ", " #sym)
-#define __warn_references(sym,msg) \
- __asm__(".section .gnu.warning." #sym); \
- __asm__(".asciz \"" msg "\""); \
- __asm__(".previous")
-#define __sym_compat(sym,impl,verid) \
- __asm__(".symver " #impl ", " #sym "@" #verid)
-#define __sym_default(sym,impl,verid) \
- __asm__(".symver " #impl ", " #sym "@@" #verid)
-#else
-#define __weak_reference(sym,alias) \
- __asm__(".weak alias"); \
- __asm__(".equ alias, sym")
-#define __warn_references(sym,msg) \
- __asm__(".section .gnu.warning.sym"); \
- __asm__(".asciz \"msg\""); \
- __asm__(".previous")
-#define __sym_compat(sym,impl,verid) \
- __asm__(".symver impl, sym@verid")
-#define __sym_default(impl,sym,verid) \
- __asm__(".symver impl, sym@@verid")
-#endif /* __STDC__ */
-#endif /* __GNUC__ || __INTEL_COMPILER */
-
-#define __GLOBL1(sym) __asm__(".globl " #sym)
-#define __GLOBL(sym) __GLOBL1(sym)
-
-#if defined(__GNUC__) || defined(__INTEL_COMPILER)
-#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"")
-#else
-/*
- * The following definition might not work well if used in header files,
- * but it should be better than nothing. If you want a "do nothing"
- * version, then it should generate some harmless declaration, such as:
- * #define __IDSTRING(name,string) struct __hack
- */
-#define __IDSTRING(name,string) static const char name[] __unused = string
-#endif
-
-/*
- * Embed the rcs id of a source file in the resulting library. Note that in
- * more recent ELF binutils, we use .ident allowing the ID to be stripped.
- * Usage:
- * __FBSDID("$FreeBSD$");
- */
-#ifndef __FBSDID
-#if !defined(lint) && !defined(STRIP_FBSDID)
-#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
-#else
-#define __FBSDID(s) struct __hack
-#endif
-#endif
-
-#ifndef __RCSID
-#ifndef NO__RCSID
-#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
-#else
-#define __RCSID(s) struct __hack
-#endif
-#endif
-
-#ifndef __RCSID_SOURCE
-#ifndef NO__RCSID_SOURCE
-#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
-#else
-#define __RCSID_SOURCE(s) struct __hack
-#endif
-#endif
-
-#ifndef __SCCSID
-#ifndef NO__SCCSID
-#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
-#else
-#define __SCCSID(s) struct __hack
-#endif
-#endif
-
-#ifndef __COPYRIGHT
-#ifndef NO__COPYRIGHT
-#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
-#else
-#define __COPYRIGHT(s) struct __hack
-#endif
-#endif
-
-#ifndef __DECONST
-#define __DECONST(type, var) ((type)(__uintptr_t)(const void *)(var))
-#endif
-
-#ifndef __DEVOLATILE
-#define __DEVOLATILE(type, var) ((type)(__uintptr_t)(volatile void *)(var))
-#endif
-
-#ifndef __DEQUALIFY
-#define __DEQUALIFY(type, var) ((type)(__uintptr_t)(const volatile void *)(var))
-#endif
-
-/*-
- * The following definitions are an extension of the behavior originally
- * implemented in <sys/_posix.h>, but with a different level of granularity.
- * POSIX.1 requires that the macros we test be defined before any standard
- * header file is included.
- *
- * Here's a quick run-down of the versions:
- * defined(_POSIX_SOURCE) 1003.1-1988
- * _POSIX_C_SOURCE == 1 1003.1-1990
- * _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option
- * _POSIX_C_SOURCE == 199309 1003.1b-1993
- * _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995,
- * and the omnibus ISO/IEC 9945-1: 1996
- * _POSIX_C_SOURCE == 200112 1003.1-2001
- * _POSIX_C_SOURCE == 200809 1003.1-2008
- *
- * In addition, the X/Open Portability Guide, which is now the Single UNIX
- * Specification, defines a feature-test macro which indicates the version of
- * that specification, and which subsumes _POSIX_C_SOURCE.
- *
- * Our macros begin with two underscores to avoid namespace screwage.
- */
-
-/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
-#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */
-#define _POSIX_C_SOURCE 199009
-#endif
-
-/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
-#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
-#undef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 199209
-#endif
-
-/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
-#ifdef _XOPEN_SOURCE
-#if _XOPEN_SOURCE - 0 >= 700
-#define __XSI_VISIBLE 700
-#undef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200809
-#elif _XOPEN_SOURCE - 0 >= 600
-#define __XSI_VISIBLE 600
-#undef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 200112
-#elif _XOPEN_SOURCE - 0 >= 500
-#define __XSI_VISIBLE 500
-#undef _POSIX_C_SOURCE
-#define _POSIX_C_SOURCE 199506
-#endif
-#endif
-
-/*
- * Deal with all versions of POSIX. The ordering relative to the tests above is
- * important.
- */
-#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 198808
-#endif
-#ifdef _POSIX_C_SOURCE
-#if _POSIX_C_SOURCE >= 200809
-#define __POSIX_VISIBLE 200809
-#define __ISO_C_VISIBLE 1999
-#elif _POSIX_C_SOURCE >= 200112
-#define __POSIX_VISIBLE 200112
-#define __ISO_C_VISIBLE 1999
-#elif _POSIX_C_SOURCE >= 199506
-#define __POSIX_VISIBLE 199506
-#define __ISO_C_VISIBLE 1990
-#elif _POSIX_C_SOURCE >= 199309
-#define __POSIX_VISIBLE 199309
-#define __ISO_C_VISIBLE 1990
-#elif _POSIX_C_SOURCE >= 199209
-#define __POSIX_VISIBLE 199209
-#define __ISO_C_VISIBLE 1990
-#elif _POSIX_C_SOURCE >= 199009
-#define __POSIX_VISIBLE 199009
-#define __ISO_C_VISIBLE 1990
-#else
-#define __POSIX_VISIBLE 198808
-#define __ISO_C_VISIBLE 0
-#endif /* _POSIX_C_SOURCE */
-#else
-/*-
- * Deal with _ANSI_SOURCE:
- * If it is defined, and no other compilation environment is explicitly
- * requested, then define our internal feature-test macros to zero. This
- * makes no difference to the preprocessor (undefined symbols in preprocessing
- * expressions are defined to have value zero), but makes it more convenient for
- * a test program to print out the values.
- *
- * If a program mistakenly defines _ANSI_SOURCE and some other macro such as
- * _POSIX_C_SOURCE, we will assume that it wants the broader compilation
- * environment (and in fact we will never get here).
- */
-#if defined(_ANSI_SOURCE) /* Hide almost everything. */
-#define __POSIX_VISIBLE 0
-#define __XSI_VISIBLE 0
-#define __BSD_VISIBLE 0
-#define __ISO_C_VISIBLE 1990
-#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */
-#define __POSIX_VISIBLE 0
-#define __XSI_VISIBLE 0
-#define __BSD_VISIBLE 0
-#define __ISO_C_VISIBLE 1999
-#else /* Default environment: show everything. */
-#define __POSIX_VISIBLE 200809
-#define __XSI_VISIBLE 700
-#define __BSD_VISIBLE 1
-#define __ISO_C_VISIBLE 1999
-#endif
-#endif
-
-#ifndef __has_feature
-#define __has_feature(x) 0
-#endif
-#ifndef __has_include
-#define __has_include(x) 0
-#endif
-#ifndef __has_builtin
-#define __has_builtin(x) 0
-#endif
-
-#if defined(__mips) || defined(__powerpc64__) || defined(__arm__)
-#define __NO_TLS 1
-#endif
-
-#endif /* !_SYS_CDEFS_H_ */
diff --git a/include/lib/stdlib/sys/ctype.h b/include/lib/stdlib/sys/ctype.h
deleted file mode 100644
index f2758b774..000000000
--- a/include/lib/stdlib/sys/ctype.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*-
- * Copyright (c) 1982, 1988, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * $FreeBSD$
- */
-
-/*
- * Portions copyright (c) 2009-2014, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#ifndef _SYS_CTYPE_H_
-#define _SYS_CTYPE_H_
-
-#define isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r'))
-#define isascii(c) (((c) & ~0x7f) == 0)
-#define isupper(c) ((c) >= 'A' && (c) <= 'Z')
-#define islower(c) ((c) >= 'a' && (c) <= 'z')
-#define isalpha(c) (isupper(c) || islower(c))
-#define isdigit(c) ((c) >= '0' && (c) <= '9')
-#define isxdigit(c) (isdigit(c) \
- || ((c) >= 'A' && (c) <= 'F') \
- || ((c) >= 'a' && (c) <= 'f'))
-#define isprint(c) ((c) >= ' ' && (c) <= '~')
-
-#define toupper(c) ((c) - 0x20 * (((c) >= 'a') && ((c) <= 'z')))
-#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z')))
-
-#endif /* !_SYS_CTYPE_H_ */
diff --git a/include/lib/stdlib/sys/limits.h b/include/lib/stdlib/sys/limits.h
deleted file mode 100644
index c56a337de..000000000
--- a/include/lib/stdlib/sys/limits.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*-
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS_LIMITS_H_
-#define _SYS_LIMITS_H_
-
-#include <sys/cdefs.h>
-#include <machine/_limits.h>
-
-#define CHAR_BIT __CHAR_BIT /* number of bits in a char */
-
-#define SCHAR_MAX __SCHAR_MAX /* max value for a signed char */
-#define SCHAR_MIN __SCHAR_MIN /* min value for a signed char */
-
-#define UCHAR_MAX __UCHAR_MAX /* max value for an unsigned char */
-
-#ifdef __CHAR_UNSIGNED__
-#define CHAR_MAX UCHAR_MAX /* max value for a char */
-#define CHAR_MIN 0 /* min value for a char */
-#else
-#define CHAR_MAX SCHAR_MAX
-#define CHAR_MIN SCHAR_MIN
-#endif
-
-#define USHRT_MAX __USHRT_MAX /* max value for an unsigned short */
-#define SHRT_MAX __SHRT_MAX /* max value for a short */
-#define SHRT_MIN __SHRT_MIN /* min value for a short */
-
-#define UINT_MAX __UINT_MAX /* max value for an unsigned int */
-#define INT_MAX __INT_MAX /* max value for an int */
-#define INT_MIN __INT_MIN /* min value for an int */
-
-#define ULONG_MAX __ULONG_MAX /* max for an unsigned long */
-#define LONG_MAX __LONG_MAX /* max for a long */
-#define LONG_MIN __LONG_MIN /* min for a long */
-
-#ifdef __LONG_LONG_SUPPORTED
-#define ULLONG_MAX __ULLONG_MAX /* max for an unsigned long long */
-#define LLONG_MAX __LLONG_MAX /* max for a long long */
-#define LLONG_MIN __LLONG_MIN /* min for a long long */
-#endif
-
-#if __POSIX_VISIBLE || __XSI_VISIBLE
-#define SSIZE_MAX __SSIZE_MAX /* max value for an ssize_t */
-#endif
-
-#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
-#define SIZE_T_MAX __SIZE_T_MAX /* max value for a size_t */
-
-#define OFF_MAX __OFF_MAX /* max value for an off_t */
-#define OFF_MIN __OFF_MIN /* min value for an off_t */
-#endif
-
-#if __BSD_VISIBLE
-#define GID_MAX UINT_MAX /* max value for a gid_t */
-#define UID_MAX UINT_MAX /* max value for a uid_t */
-
-#define UQUAD_MAX (__UQUAD_MAX) /* max value for a uquad_t */
-#define QUAD_MAX (__QUAD_MAX) /* max value for a quad_t */
-#define QUAD_MIN (__QUAD_MIN) /* min value for a quad_t */
-#endif
-
-#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
-#define LONG_BIT __LONG_BIT
-#define WORD_BIT __WORD_BIT
-#endif
-
-#if __POSIX_VISIBLE
-#define MQ_PRIO_MAX 64
-#endif
-
-#endif /* !_SYS_LIMITS_H_ */
diff --git a/include/lib/stdlib/sys/stdarg.h b/include/lib/stdlib/sys/stdarg.h
deleted file mode 100644
index c315dfcee..000000000
--- a/include/lib/stdlib/sys/stdarg.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * Copyright (c) 2002 David E. O'Brien. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _MACHINE_STDARG_H_
-#define _MACHINE_STDARG_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-
-#ifndef _VA_LIST_DECLARED
-#define _VA_LIST_DECLARED
-typedef __va_list va_list;
-#endif
-
-#ifdef __GNUCLIKE_BUILTIN_STDARG
-
-#define va_start(ap, last) \
- __builtin_va_start((ap), (last))
-
-#define va_arg(ap, type) \
- __builtin_va_arg((ap), type)
-
-#define __va_copy(dest, src) \
- __builtin_va_copy((dest), (src))
-
-#if __ISO_C_VISIBLE >= 1999
-#define va_copy(dest, src) \
- __va_copy(dest, src)
-#endif
-
-#define va_end(ap) \
- __builtin_va_end(ap)
-
-#elif defined(lint)
-/* Provide a fake implementation for lint's benefit */
-#define __va_size(type) \
- (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
-#define va_start(ap, last) \
- ((ap) = (va_list)&(last) + __va_size(last))
-#define va_arg(ap, type) \
- (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
-#define va_end(ap)
-
-#else
-#error this file needs to be ported to your compiler
-#endif
-
-#endif /* !_MACHINE_STDARG_H_ */
diff --git a/include/lib/stdlib/sys/stdint.h b/include/lib/stdlib/sys/stdint.h
deleted file mode 100644
index aa5ac81d1..000000000
--- a/include/lib/stdlib/sys/stdint.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*-
- * Copyright (c) 2001 Mike Barcroft <mike@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS_STDINT_H_
-#define _SYS_STDINT_H_
-
-#include <sys/cdefs.h>
-#include <sys/_types.h>
-
-#include <machine/_stdint.h>
-#include <sys/_stdint.h>
-
-typedef __int_least8_t int_least8_t;
-typedef __int_least16_t int_least16_t;
-typedef __int_least32_t int_least32_t;
-typedef __int_least64_t int_least64_t;
-
-typedef __uint_least8_t uint_least8_t;
-typedef __uint_least16_t uint_least16_t;
-typedef __uint_least32_t uint_least32_t;
-typedef __uint_least64_t uint_least64_t;
-
-typedef __int_fast8_t int_fast8_t;
-typedef __int_fast16_t int_fast16_t;
-typedef __int_fast32_t int_fast32_t;
-typedef __int_fast64_t int_fast64_t;
-
-typedef __uint_fast8_t uint_fast8_t;
-typedef __uint_fast16_t uint_fast16_t;
-typedef __uint_fast32_t uint_fast32_t;
-typedef __uint_fast64_t uint_fast64_t;
-
-#ifndef _INTMAX_T_DECLARED
-typedef __intmax_t intmax_t;
-#define _INTMAX_T_DECLARED
-#endif
-#ifndef _UINTMAX_T_DECLARED
-typedef __uintmax_t uintmax_t;
-#define _UINTMAX_T_DECLARED
-#endif
-
-/* GNU and Darwin define this and people seem to think it's portable */
-#if defined(UINTPTR_MAX) && defined(UINT64_MAX) && (UINTPTR_MAX == UINT64_MAX)
-#define __WORDSIZE 64
-#else
-#define __WORDSIZE 32
-#endif
-
-#endif /* !_SYS_STDINT_H_ */
diff --git a/include/lib/stdlib/sys/timespec.h b/include/lib/stdlib/sys/timespec.h
deleted file mode 100644
index 2505cef89..000000000
--- a/include/lib/stdlib/sys/timespec.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)time.h 8.5 (Berkeley) 5/4/95
- * from: FreeBSD: src/sys/sys/time.h,v 1.43 2000/03/20 14:09:05 phk Exp
- * $FreeBSD$
- */
-
-#ifndef _SYS_TIMESPEC_H_
-#define _SYS_TIMESPEC_H_
-
-#include <sys/cdefs.h>
-#include <sys/_timespec.h>
-
-#if __BSD_VISIBLE
-#define TIMEVAL_TO_TIMESPEC(tv, ts) \
- do { \
- (ts)->tv_sec = (tv)->tv_sec; \
- (ts)->tv_nsec = (tv)->tv_usec * 1000; \
- } while (0)
-#define TIMESPEC_TO_TIMEVAL(tv, ts) \
- do { \
- (tv)->tv_sec = (ts)->tv_sec; \
- (tv)->tv_usec = (ts)->tv_nsec / 1000; \
- } while (0)
-
-#endif /* __BSD_VISIBLE */
-
-/*
- * Structure defined by POSIX.1b to be like a itimerval, but with
- * timespecs. Used in the timer_*() system calls.
- */
-struct itimerspec {
- struct timespec it_interval;
- struct timespec it_value;
-};
-
-#endif /* _SYS_TIMESPEC_H_ */
diff --git a/include/lib/stdlib/sys/types.h b/include/lib/stdlib/sys/types.h
deleted file mode 100644
index ae2ea33a5..000000000
--- a/include/lib/stdlib/sys/types.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*-
- * Copyright (c) 1982, 1986, 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)types.h 8.6 (Berkeley) 2/19/95
- * $FreeBSD$
- */
-
-#ifndef _SYS_TYPES_H_
-#define _SYS_TYPES_H_
-
-#include <sys/cdefs.h>
-
-/* Machine type dependent parameters. */
-#include <sys/_types.h>
-
-#if __BSD_VISIBLE
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-#ifndef _KERNEL
-typedef unsigned short ushort; /* Sys V compatibility */
-typedef unsigned int uint; /* Sys V compatibility */
-#endif
-#endif
-
-/*
- * XXX POSIX sized integrals that should appear only in <sys/stdint.h>.
- */
-#include <sys/_stdint.h>
-
-typedef __uint8_t u_int8_t; /* unsigned integrals (deprecated) */
-typedef __uint16_t u_int16_t;
-typedef __uint32_t u_int32_t;
-typedef __uint64_t u_int64_t;
-
-typedef __uint64_t u_quad_t; /* quads (deprecated) */
-typedef __int64_t quad_t;
-typedef quad_t *qaddr_t;
-
-typedef char *caddr_t; /* core address */
-typedef const char *c_caddr_t; /* core address, pointer to const */
-
-#ifndef _BLKSIZE_T_DECLARED
-typedef __blksize_t blksize_t;
-#define _BLKSIZE_T_DECLARED
-#endif
-
-typedef __cpuwhich_t cpuwhich_t;
-typedef __cpulevel_t cpulevel_t;
-typedef __cpusetid_t cpusetid_t;
-
-#ifndef _BLKCNT_T_DECLARED
-typedef __blkcnt_t blkcnt_t;
-#define _BLKCNT_T_DECLARED
-#endif
-
-#ifndef _CLOCK_T_DECLARED
-typedef __clock_t clock_t;
-#define _CLOCK_T_DECLARED
-#endif
-
-#ifndef _CLOCKID_T_DECLARED
-typedef __clockid_t clockid_t;
-#define _CLOCKID_T_DECLARED
-#endif
-
-typedef __critical_t critical_t; /* Critical section value */
-typedef __int64_t daddr_t; /* disk address */
-
-#ifndef _DEV_T_DECLARED
-typedef __dev_t dev_t; /* device number or struct cdev */
-#define _DEV_T_DECLARED
-#endif
-
-#ifndef _FFLAGS_T_DECLARED
-typedef __fflags_t fflags_t; /* file flags */
-#define _FFLAGS_T_DECLARED
-#endif
-
-typedef __fixpt_t fixpt_t; /* fixed point number */
-
-#ifndef _FSBLKCNT_T_DECLARED /* for statvfs() */
-typedef __fsblkcnt_t fsblkcnt_t;
-typedef __fsfilcnt_t fsfilcnt_t;
-#define _FSBLKCNT_T_DECLARED
-#endif
-
-#ifndef _GID_T_DECLARED
-typedef __gid_t gid_t; /* group id */
-#define _GID_T_DECLARED
-#endif
-
-#ifndef _IN_ADDR_T_DECLARED
-typedef __uint32_t in_addr_t; /* base type for internet address */
-#define _IN_ADDR_T_DECLARED
-#endif
-
-#ifndef _IN_PORT_T_DECLARED
-typedef __uint16_t in_port_t;
-#define _IN_PORT_T_DECLARED
-#endif
-
-#ifndef _ID_T_DECLARED
-typedef __id_t id_t; /* can hold a uid_t or pid_t */
-#define _ID_T_DECLARED
-#endif
-
-#ifndef _INO_T_DECLARED
-typedef __ino_t ino_t; /* inode number */
-#define _INO_T_DECLARED
-#endif
-
-#ifndef _KEY_T_DECLARED
-typedef __key_t key_t; /* IPC key (for Sys V IPC) */
-#define _KEY_T_DECLARED
-#endif
-
-#ifndef _LWPID_T_DECLARED
-typedef __lwpid_t lwpid_t; /* Thread ID (a.k.a. LWP) */
-#define _LWPID_T_DECLARED
-#endif
-
-#ifndef _MODE_T_DECLARED
-typedef __mode_t mode_t; /* permissions */
-#define _MODE_T_DECLARED
-#endif
-
-#ifndef _ACCMODE_T_DECLARED
-typedef __accmode_t accmode_t; /* access permissions */
-#define _ACCMODE_T_DECLARED
-#endif
-
-#ifndef _NLINK_T_DECLARED
-typedef __nlink_t nlink_t; /* link count */
-#define _NLINK_T_DECLARED
-#endif
-
-#ifndef _OFF_T_DECLARED
-typedef __off_t off_t; /* file offset */
-#define _OFF_T_DECLARED
-#endif
-
-#ifndef _PID_T_DECLARED
-typedef __pid_t pid_t; /* process id */
-#define _PID_T_DECLARED
-#endif
-
-typedef __register_t register_t;
-
-#ifndef _RLIM_T_DECLARED
-typedef __rlim_t rlim_t; /* resource limit */
-#define _RLIM_T_DECLARED
-#endif
-
-typedef __int64_t sbintime_t;
-
-typedef __segsz_t segsz_t; /* segment size (in pages) */
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-#ifndef _SSIZE_T_DECLARED
-typedef __ssize_t ssize_t;
-#define _SSIZE_T_DECLARED
-#endif
-
-#ifndef _SUSECONDS_T_DECLARED
-typedef __suseconds_t suseconds_t; /* microseconds (signed) */
-#define _SUSECONDS_T_DECLARED
-#endif
-
-#ifndef _TIME_T_DECLARED
-typedef __time_t time_t;
-#define _TIME_T_DECLARED
-#endif
-
-#ifndef _TIMER_T_DECLARED
-typedef __timer_t timer_t;
-#define _TIMER_T_DECLARED
-#endif
-
-#ifndef _MQD_T_DECLARED
-typedef __mqd_t mqd_t;
-#define _MQD_T_DECLARED
-#endif
-
-typedef __u_register_t u_register_t;
-
-#ifndef _UID_T_DECLARED
-typedef __uid_t uid_t; /* user id */
-#define _UID_T_DECLARED
-#endif
-
-#ifndef _USECONDS_T_DECLARED
-typedef __useconds_t useconds_t; /* microseconds (unsigned) */
-#define _USECONDS_T_DECLARED
-#endif
-
-#ifndef _CAP_RIGHTS_T_DECLARED
-#define _CAP_RIGHTS_T_DECLARED
-struct cap_rights;
-
-typedef struct cap_rights cap_rights_t;
-#endif
-
-typedef __vm_offset_t vm_offset_t;
-typedef __vm_ooffset_t vm_ooffset_t;
-typedef __vm_paddr_t vm_paddr_t;
-typedef __vm_pindex_t vm_pindex_t;
-typedef __vm_size_t vm_size_t;
-
-#endif /* !_SYS_TYPES_H_ */
diff --git a/include/lib/stdlib/time.h b/include/lib/stdlib/time.h
deleted file mode 100644
index 08200cfb2..000000000
--- a/include/lib/stdlib/time.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)time.h 8.3 (Berkeley) 1/21/94
- */
-
-/*
- * $FreeBSD$
- */
-
-#ifndef _TIME_H_
-#define _TIME_H_
-
-#include <sys/cdefs.h>
-#include <sys/_null.h>
-#include <sys/_types.h>
-
-#if __POSIX_VISIBLE > 0 && __POSIX_VISIBLE < 200112 || __BSD_VISIBLE
-/*
- * Frequency of the clock ticks reported by times(). Deprecated - use
- * sysconf(_SC_CLK_TCK) instead. (Removed in 1003.1-2001.)
- */
-#define CLK_TCK 128
-#endif
-
-/* Frequency of the clock ticks reported by clock(). */
-#define CLOCKS_PER_SEC 128
-
-#ifndef _CLOCK_T_DECLARED
-typedef __clock_t clock_t;
-#define _CLOCK_T_DECLARED
-#endif
-
-#ifndef _TIME_T_DECLARED
-typedef __time_t time_t;
-#define _TIME_T_DECLARED
-#endif
-
-#ifndef _SIZE_T_DECLARED
-typedef __size_t size_t;
-#define _SIZE_T_DECLARED
-#endif
-
-#if __POSIX_VISIBLE >= 199309
-/*
- * New in POSIX 1003.1b-1993.
- */
-#ifndef _CLOCKID_T_DECLARED
-typedef __clockid_t clockid_t;
-#define _CLOCKID_T_DECLARED
-#endif
-
-#ifndef _TIMER_T_DECLARED
-typedef __timer_t timer_t;
-#define _TIMER_T_DECLARED
-#endif
-
-#include <sys/timespec.h>
-#endif /* __POSIX_VISIBLE >= 199309 */
-
-#if __POSIX_VISIBLE >= 200112
-#ifndef _PID_T_DECLARED
-typedef __pid_t pid_t;
-#define _PID_T_DECLARED
-#endif
-#endif
-
-/* These macros are also in sys/time.h. */
-#if !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112
-#define CLOCK_REALTIME 0
-#ifdef __BSD_VISIBLE
-#define CLOCK_VIRTUAL 1
-#define CLOCK_PROF 2
-#endif
-#define CLOCK_MONOTONIC 4
-#define CLOCK_UPTIME 5 /* FreeBSD-specific. */
-#define CLOCK_UPTIME_PRECISE 7 /* FreeBSD-specific. */
-#define CLOCK_UPTIME_FAST 8 /* FreeBSD-specific. */
-#define CLOCK_REALTIME_PRECISE 9 /* FreeBSD-specific. */
-#define CLOCK_REALTIME_FAST 10 /* FreeBSD-specific. */
-#define CLOCK_MONOTONIC_PRECISE 11 /* FreeBSD-specific. */
-#define CLOCK_MONOTONIC_FAST 12 /* FreeBSD-specific. */
-#define CLOCK_SECOND 13 /* FreeBSD-specific. */
-#define CLOCK_THREAD_CPUTIME_ID 14
-#define CLOCK_PROCESS_CPUTIME_ID 15
-#endif /* !defined(CLOCK_REALTIME) && __POSIX_VISIBLE >= 200112 */
-
-#if !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112
-#if __BSD_VISIBLE
-#define TIMER_RELTIME 0x0 /* relative timer */
-#endif
-#define TIMER_ABSTIME 0x1 /* absolute timer */
-#endif /* !defined(TIMER_ABSTIME) && __POSIX_VISIBLE >= 200112 */
-
-struct tm {
- int tm_sec; /* seconds after the minute [0-60] */
- int tm_min; /* minutes after the hour [0-59] */
- int tm_hour; /* hours since midnight [0-23] */
- int tm_mday; /* day of the month [1-31] */
- int tm_mon; /* months since January [0-11] */
- int tm_year; /* years since 1900 */
- int tm_wday; /* days since Sunday [0-6] */
- int tm_yday; /* days since January 1 [0-365] */
- int tm_isdst; /* Daylight Savings Time flag */
- long tm_gmtoff; /* offset from UTC in seconds */
- char *tm_zone; /* timezone abbreviation */
-};
-
-#if __POSIX_VISIBLE
-extern char *tzname[];
-#endif
-
-__BEGIN_DECLS
-char *asctime(const struct tm *);
-clock_t clock(void);
-char *ctime(const time_t *);
-double difftime(time_t, time_t);
-/* XXX missing: getdate() */
-struct tm *gmtime(const time_t *);
-struct tm *localtime(const time_t *);
-time_t mktime(struct tm *);
-size_t strftime(char *__restrict, size_t, const char *__restrict,
- const struct tm *__restrict);
-time_t time(time_t *);
-#if __POSIX_VISIBLE >= 200112
-struct sigevent;
-int timer_create(clockid_t, struct sigevent *__restrict, timer_t *__restrict);
-int timer_delete(timer_t);
-int timer_gettime(timer_t, struct itimerspec *);
-int timer_getoverrun(timer_t);
-int timer_settime(timer_t, int, const struct itimerspec *__restrict,
- struct itimerspec *__restrict);
-#endif
-#if __POSIX_VISIBLE
-void tzset(void);
-#endif
-
-#if __POSIX_VISIBLE >= 199309
-int clock_getres(clockid_t, struct timespec *);
-int clock_gettime(clockid_t, struct timespec *);
-int clock_settime(clockid_t, const struct timespec *);
-/* XXX missing: clock_nanosleep() */
-int nanosleep(const struct timespec *, struct timespec *);
-#endif /* __POSIX_VISIBLE >= 199309 */
-
-#if __POSIX_VISIBLE >= 200112
-int clock_getcpuclockid(pid_t, clockid_t *);
-#endif
-
-#if __POSIX_VISIBLE >= 199506
-char *asctime_r(const struct tm *, char *);
-char *ctime_r(const time_t *, char *);
-struct tm *gmtime_r(const time_t *, struct tm *);
-struct tm *localtime_r(const time_t *, struct tm *);
-#endif
-
-#if __XSI_VISIBLE
-char *strptime(const char *__restrict, const char *__restrict,
- struct tm *__restrict);
-#endif
-
-#if __BSD_VISIBLE
-char *timezone(int, int); /* XXX XSI conflict */
-void tzsetwall(void);
-time_t timelocal(struct tm * const);
-time_t timegm(struct tm * const);
-#endif /* __BSD_VISIBLE */
-
-#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)
-#include <xlocale/_time.h>
-#endif
-__END_DECLS
-
-#endif /* !_TIME_H_ */
diff --git a/include/lib/stdlib/xlocale/_strings.h b/include/lib/stdlib/xlocale/_strings.h
deleted file mode 100644
index da1cff3e7..000000000
--- a/include/lib/stdlib/xlocale/_strings.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-
- * Copyright (c) 2011, 2012 The FreeBSD Foundation
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _LOCALE_T_DEFINED
-#define _LOCALE_T_DEFINED
-typedef struct _xlocale *locale_t;
-#endif
-
-/*
- * This file is included from both strings.h and xlocale.h. We need to expose
- * the declarations unconditionally if we are included from xlocale.h, but only
- * if we are in POSIX2008 mode if included from string.h.
- */
-
-#ifndef _XLOCALE_STRINGS1_H
-#define _XLOCALE_STRINGS1_H
-
-/*
- * POSIX2008 functions
- */
-int strcasecmp_l(const char *, const char *, locale_t);
-int strncasecmp_l(const char *, const char *, size_t, locale_t);
-#endif /* _XLOCALE_STRINGS1_H */
diff --git a/include/lib/stdlib/xlocale/_time.h b/include/lib/stdlib/xlocale/_time.h
deleted file mode 100644
index 6da49a427..000000000
--- a/include/lib/stdlib/xlocale/_time.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 2011, 2012 The FreeBSD Foundation
- * All rights reserved.
- *
- * This software was developed by David Chisnall under sponsorship from
- * the FreeBSD Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _LOCALE_T_DEFINED
-#define _LOCALE_T_DEFINED
-typedef struct _xlocale *locale_t;
-#endif
-
-/*
- * This file is included from both locale.h and xlocale.h. We need to expose
- * the declarations unconditionally if we are included from xlocale.h, but only
- * if we are in POSIX2008 mode if included from locale.h.
- */
-#ifndef _XLOCALE_LOCALE1_H
-#define _XLOCALE_LOCALE1_H
-
-size_t strftime_l(char *__restrict, size_t, const char *__restrict,
- const struct tm *__restrict, locale_t) __strftimelike(3, 0);
-
-#endif /* _XLOCALE_LOCALE1_H */
-
-#ifdef _XLOCALE_H_
-#ifndef _XLOCALE_LOCALE2_H
-#define _XLOCALE_LOCALE2_H
-
-char *strptime_l(const char *__restrict, const char *__restrict,
- struct tm *__restrict, locale_t);
-
-#endif /* _XLOCALE_LOCALE2_H */
-#endif /* _XLOCALE_H_ */
diff --git a/include/lib/utils.h b/include/lib/utils.h
index 5f13e993f..09ec8d99b 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -17,7 +17,7 @@
*/
#if !(defined(__LINKER__) || defined(__ASSEMBLY__))
-#include <types.h>
+#include <stdint.h>
typedef struct mem_region {
uintptr_t base;
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 1bdf3c4b0..5b4fd7808 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __UTILS_DEF_H__
-#define __UTILS_DEF_H__
+#ifndef UTILS_DEF_H
+#define UTILS_DEF_H
/* Compute the number of elements in the given array */
#define ARRAY_SIZE(a) \
@@ -88,31 +88,37 @@
* Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
* Both arguments must be unsigned pointer values (i.e. uintptr_t).
*/
-#define check_uptr_overflow(ptr, inc) \
- (((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
+#define check_uptr_overflow(_ptr, _inc) \
+ ((_ptr) > (UINTPTR_MAX - (_inc)))
/*
* Evaluates to 1 if (u32 + inc) overflows, 0 otherwise.
* Both arguments must be 32-bit unsigned integers (i.e. effectively uint32_t).
*/
-#define check_u32_overflow(u32, inc) \
- ((u32) > (UINT32_MAX - (inc)) ? 1 : 0)
+#define check_u32_overflow(_u32, _inc) \
+ ((_u32) > (UINT32_MAX - (_inc)))
/*
- * For those constants to be shared between C and other sources, apply a 'u'
- * or 'ull' suffix to the argument only in C, to avoid undefined or unintended
- * behaviour.
+ * For those constants to be shared between C and other sources, apply a 'U',
+ * 'UL', 'ULL', 'L' or 'LL' suffix to the argument only in C, to avoid
+ * undefined or unintended behaviour.
*
- * The GNU assembler and linker do not support the 'u' and 'ull' suffix (it
- * causes the build process to fail) therefore the suffix is omitted when used
- * in linker scripts and assembler files.
+ * The GNU assembler and linker do not support these suffixes (it causes the
+ * build process to fail) therefore the suffix is omitted when used in linker
+ * scripts and assembler files.
*/
#if defined(__LINKER__) || defined(__ASSEMBLY__)
-# define U(_x) (_x)
+# define U(_x) (_x)
+# define UL(_x) (_x)
# define ULL(_x) (_x)
+# define L(_x) (_x)
+# define LL(_x) (_x)
#else
-# define U(_x) (_x##U)
+# define U(_x) (_x##U)
+# define UL(_x) (_x##UL)
# define ULL(_x) (_x##ULL)
+# define L(_x) (_x##L)
+# define LL(_x) (_x##LL)
#endif
/* Register size of the current architecture. */
@@ -147,4 +153,4 @@
#define ASSERT_SYM_PTR_ALIGN(sym) assert(((size_t)(sym) % __alignof__(*(sym))) == 0)
-#endif /* __UTILS_DEF_H__ */
+#endif /* UTILS_DEF_H */
diff --git a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
index 808589ac3..37f3b53b7 100644
--- a/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
+++ b/include/lib/xlat_tables/aarch32/xlat_tables_aarch32.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_AARCH32_H__
-#define __XLAT_TABLES_AARCH32_H__
+#ifndef XLAT_TABLES_AARCH32_H
+#define XLAT_TABLES_AARCH32_H
#include <arch.h>
#include <utils_def.h>
@@ -24,7 +24,7 @@
* The define below specifies the first table level that allows block
* descriptors.
*/
-#if PAGE_SIZE != (4 * 1024)
+#if PAGE_SIZE != PAGE_SIZE_4KB
#error "Invalid granule size. AArch32 supports 4KB pages only."
#endif
@@ -43,8 +43,8 @@
* [1] See the ARMv8-A Architecture Reference Manual (DDI 0487A.j) for more
* information, Section G4.6.5
*/
-#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (32 - TTBCR_TxSZ_MAX))
-#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (32 - TTBCR_TxSZ_MIN))
+#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(32) - TTBCR_TxSZ_MAX))
+#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(32) - TTBCR_TxSZ_MIN))
/*
* Here we calculate the initial lookup level from the value of the given
@@ -66,7 +66,8 @@
* valid. Therefore, the caller is expected to check it is the case using the
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
*/
-#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size) \
- (((_virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? 1 : 2)
+#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
+ (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) ? \
+ U(1) : U(2))
-#endif /* __XLAT_TABLES_AARCH32_H__ */
+#endif /* XLAT_TABLES_AARCH32_H */
diff --git a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
index ad48a358a..91ca8e477 100644
--- a/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
+++ b/include/lib/xlat_tables/aarch64/xlat_tables_aarch64.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_AARCH64_H__
-#define __XLAT_TABLES_AARCH64_H__
+#ifndef XLAT_TABLES_AARCH64_H
+#define XLAT_TABLES_AARCH64_H
#include <arch.h>
#include <utils_def.h>
@@ -30,9 +30,9 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* The define below specifies the first table level that allows block
* descriptors.
*/
-#if PAGE_SIZE == (4 * 1024)
+#if PAGE_SIZE == PAGE_SIZE_4KB
# define MIN_LVL_BLOCK_DESC U(1)
-#elif PAGE_SIZE == (16 * 1024) || PAGE_SIZE == (64 * 1024)
+#elif (PAGE_SIZE == PAGE_SIZE_16KB) || (PAGE_SIZE == PAGE_SIZE_64KB)
# define MIN_LVL_BLOCK_DESC U(2)
#endif
@@ -50,8 +50,8 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* information:
* Page 1730: 'Input address size', 'For all translation stages'.
*/
-#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (64 - TCR_TxSZ_MAX))
-#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (64 - TCR_TxSZ_MIN))
+#define MIN_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MAX))
+#define MAX_VIRT_ADDR_SPACE_SIZE (ULL(1) << (U(64) - TCR_TxSZ_MIN))
/*
* Here we calculate the initial lookup level from the value of the given
@@ -74,10 +74,10 @@ unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr);
* valid. Therefore, the caller is expected to check it is the case using the
* CHECK_VIRT_ADDR_SPACE_SIZE() macro first.
*/
-#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size) \
- (((_virt_addr_space_size) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT)) \
- ? 0 \
- : (((_virt_addr_space_size) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
- ? 1 : 2))
+#define GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_sz) \
+ (((_virt_addr_space_sz) > (ULL(1) << L0_XLAT_ADDRESS_SHIFT)) \
+ ? 0U \
+ : (((_virt_addr_space_sz) > (ULL(1) << L1_XLAT_ADDRESS_SHIFT)) \
+ ? 1U : 2U))
-#endif /* __XLAT_TABLES_AARCH64_H__ */
+#endif /* XLAT_TABLES_AARCH64_H */
diff --git a/include/lib/xlat_tables/xlat_mmu_helpers.h b/include/lib/xlat_tables/xlat_mmu_helpers.h
index b6c53e267..ab491e367 100644
--- a/include/lib/xlat_tables/xlat_mmu_helpers.h
+++ b/include/lib/xlat_tables/xlat_mmu_helpers.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_MMU_HELPERS_H__
-#define __XLAT_MMU_HELPERS_H__
+#ifndef XLAT_MMU_HELPERS_H
+#define XLAT_MMU_HELPERS_H
/*
* The following flags are passed to enable_mmu_xxx() to override the default
@@ -41,27 +41,56 @@
*/
#define XLAT_TABLE_NC (U(1) << 1)
+/*
+ * Offsets into a mmu_cfg_params array generated by setup_mmu_cfg(). All
+ * parameters are 64 bits wide.
+ */
+#define MMU_CFG_MAIR 0
+#define MMU_CFG_TCR 1
+#define MMU_CFG_TTBR0 2
+#define MMU_CFG_PARAM_MAX 3
+
#ifndef __ASSEMBLY__
-#include <sys/types.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+/*
+ * Return the values that the MMU configuration registers must contain for the
+ * specified translation context. `params` must be a pointer to array of size
+ * MMU_CFG_PARAM_MAX.
+ */
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, int xlat_regime);
#ifdef AARCH32
/* AArch32 specific translation table API */
+#if !ERROR_DEPRECATED
void enable_mmu_secure(unsigned int flags);
-
void enable_mmu_direct(unsigned int flags);
+#endif
+
+void enable_mmu_svc_mon(unsigned int flags);
+void enable_mmu_hyp(unsigned int flags);
+
+void enable_mmu_direct_svc_mon(unsigned int flags);
+void enable_mmu_direct_hyp(unsigned int flags);
#else
/* AArch64 specific translation table APIs */
void enable_mmu_el1(unsigned int flags);
+void enable_mmu_el2(unsigned int flags);
void enable_mmu_el3(unsigned int flags);
void enable_mmu_direct_el1(unsigned int flags);
+void enable_mmu_direct_el2(unsigned int flags);
void enable_mmu_direct_el3(unsigned int flags);
#endif /* AARCH32 */
-int xlat_arch_is_granule_size_supported(size_t size);
+bool xlat_arch_is_granule_size_supported(size_t size);
size_t xlat_arch_get_max_supported_granule_size(void);
#endif /* __ASSEMBLY__ */
-#endif /* __XLAT_MMU_HELPERS_H__ */
+#endif /* XLAT_MMU_HELPERS_H */
diff --git a/include/lib/xlat_tables/xlat_tables.h b/include/lib/xlat_tables/xlat_tables.h
index c017e193d..4097c76f4 100644
--- a/include/lib/xlat_tables/xlat_tables.h
+++ b/include/lib/xlat_tables/xlat_tables.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_H__
-#define __XLAT_TABLES_H__
+#ifndef XLAT_TABLES_H
+#define XLAT_TABLES_H
#include <xlat_tables_defs.h>
@@ -92,4 +92,4 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
void mmap_add(const mmap_region_t *mm);
#endif /*__ASSEMBLY__*/
-#endif /* __XLAT_TABLES_H__ */
+#endif /* XLAT_TABLES_H */
diff --git a/include/lib/xlat_tables/xlat_tables_arch.h b/include/lib/xlat_tables/xlat_tables_arch.h
index af8c46331..251b0206a 100644
--- a/include/lib/xlat_tables/xlat_tables_arch.h
+++ b/include/lib/xlat_tables/xlat_tables_arch.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_ARCH_H__
-#define __XLAT_TABLES_ARCH_H__
+#ifndef XLAT_TABLES_ARCH_H
+#define XLAT_TABLES_ARCH_H
#ifdef AARCH32
#include "aarch32/xlat_tables_aarch32.h"
@@ -21,8 +21,8 @@
* limits. Not that these limits are different for AArch32 and AArch64.
*/
#define CHECK_VIRT_ADDR_SPACE_SIZE(size) \
- (((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) && \
- ((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) && \
+ (((unsigned long long)(size) >= MIN_VIRT_ADDR_SPACE_SIZE) && \
+ ((unsigned long long)(size) <= MAX_VIRT_ADDR_SPACE_SIZE) && \
IS_POWER_OF_TWO(size))
/*
@@ -40,4 +40,4 @@
((addr_space_size) >> \
XLAT_ADDR_SHIFT(GET_XLAT_TABLE_LEVEL_BASE(addr_space_size)))
-#endif /* __XLAT_TABLES_ARCH_H__ */
+#endif /* XLAT_TABLES_ARCH_H */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 5eb1d309d..d260c3ef0 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_DEFS_H__
-#define __XLAT_TABLES_DEFS_H__
+#ifndef XLAT_TABLES_DEFS_H
+#define XLAT_TABLES_DEFS_H
#include <arch.h>
#include <utils_def.h>
@@ -24,6 +24,10 @@
#define TWO_MB_INDEX(x) ((x) >> TWO_MB_SHIFT)
#define FOUR_KB_INDEX(x) ((x) >> FOUR_KB_SHIFT)
+#define PAGE_SIZE_4KB U(4096)
+#define PAGE_SIZE_16KB U(16384)
+#define PAGE_SIZE_64KB U(65536)
+
#define INVALID_DESC U(0x0)
/*
* A block descriptor points to a region of memory bigger than the granule size
@@ -62,12 +66,12 @@
/*
* The ARMv8-A architecture allows translation granule sizes of 4KB, 16KB or
- * 64KB. However, TF only supports the 4KB case at the moment.
+ * 64KB. However, only 4KB are supported at the moment.
*/
#define PAGE_SIZE_SHIFT FOUR_KB_SHIFT
#define PAGE_SIZE (U(1) << PAGE_SIZE_SHIFT)
-#define PAGE_SIZE_MASK (PAGE_SIZE - 1)
-#define IS_PAGE_ALIGNED(addr) (((addr) & PAGE_SIZE_MASK) == 0)
+#define PAGE_SIZE_MASK (PAGE_SIZE - U(1))
+#define IS_PAGE_ALIGNED(addr) (((addr) & PAGE_SIZE_MASK) == U(0))
#define XLAT_ENTRY_SIZE_SHIFT U(3) /* Each MMU table entry is 8 bytes (1 << 3) */
#define XLAT_ENTRY_SIZE (U(1) << XLAT_ENTRY_SIZE_SHIFT)
@@ -80,7 +84,7 @@
/* Values for number of entries in each MMU translation table */
#define XLAT_TABLE_ENTRIES_SHIFT (XLAT_TABLE_SIZE_SHIFT - XLAT_ENTRY_SIZE_SHIFT)
#define XLAT_TABLE_ENTRIES (U(1) << XLAT_TABLE_ENTRIES_SHIFT)
-#define XLAT_TABLE_ENTRIES_MASK (XLAT_TABLE_ENTRIES - 1)
+#define XLAT_TABLE_ENTRIES_MASK (XLAT_TABLE_ENTRIES - U(1))
/* Values to convert a memory address to an index into a translation table */
#define L3_XLAT_ADDRESS_SHIFT PAGE_SIZE_SHIFT
@@ -90,9 +94,9 @@
#define XLAT_ADDR_SHIFT(level) (PAGE_SIZE_SHIFT + \
((XLAT_TABLE_LEVEL_MAX - (level)) * XLAT_TABLE_ENTRIES_SHIFT))
-#define XLAT_BLOCK_SIZE(level) ((u_register_t)1 << XLAT_ADDR_SHIFT(level))
+#define XLAT_BLOCK_SIZE(level) (UL(1) << XLAT_ADDR_SHIFT(level))
/* Mask to get the bits used to index inside a block of a certain level */
-#define XLAT_BLOCK_MASK(level) (XLAT_BLOCK_SIZE(level) - 1)
+#define XLAT_BLOCK_MASK(level) (XLAT_BLOCK_SIZE(level) - UL(1))
/* Mask to get the address bits common to a block of a certain table level*/
#define XLAT_ADDR_MASK(level) (~XLAT_BLOCK_MASK(level))
/*
@@ -111,13 +115,13 @@
* when stage 1 translations can only support one VA range.
*/
#define AP2_SHIFT U(0x7)
-#define AP2_RO U(0x1)
-#define AP2_RW U(0x0)
+#define AP2_RO ULL(0x1)
+#define AP2_RW ULL(0x0)
#define AP1_SHIFT U(0x6)
-#define AP1_ACCESS_UNPRIVILEGED U(0x1)
-#define AP1_NO_ACCESS_UNPRIVILEGED U(0x0)
-#define AP1_RES1 U(0x1)
+#define AP1_ACCESS_UNPRIVILEGED ULL(0x1)
+#define AP1_NO_ACCESS_UNPRIVILEGED ULL(0x0)
+#define AP1_RES1 ULL(0x1)
/*
* The following definitions must all be passed to the LOWER_ATTRS() macro to
@@ -129,9 +133,9 @@
#define AP_NO_ACCESS_UNPRIVILEGED (AP1_NO_ACCESS_UNPRIVILEGED << 4)
#define AP_ONE_VA_RANGE_RES1 (AP1_RES1 << 4)
#define NS (U(0x1) << 3)
-#define ATTR_NON_CACHEABLE_INDEX U(0x2)
-#define ATTR_DEVICE_INDEX U(0x1)
-#define ATTR_IWBWA_OWBWA_NTR_INDEX U(0x0)
+#define ATTR_NON_CACHEABLE_INDEX ULL(0x2)
+#define ATTR_DEVICE_INDEX ULL(0x1)
+#define ATTR_IWBWA_OWBWA_NTR_INDEX ULL(0x0)
#define LOWER_ATTRS(x) (((x) & U(0xfff)) << 2)
/* Normal Memory, Outer Write-Through non-transient, Inner Non-cacheable */
diff --git a/include/lib/xlat_tables/xlat_tables_v2.h b/include/lib/xlat_tables/xlat_tables_v2.h
index 20a9ea1de..52c4dc6dd 100644
--- a/include/lib/xlat_tables/xlat_tables_v2.h
+++ b/include/lib/xlat_tables/xlat_tables_v2.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_V2_H__
-#define __XLAT_TABLES_V2_H__
+#ifndef XLAT_TABLES_V2_H
+#define XLAT_TABLES_V2_H
#include <xlat_tables_defs.h>
#include <xlat_tables_v2_helpers.h>
@@ -27,7 +27,7 @@
/* Helper macro to define an mmap_region_t. */
#define MAP_REGION(_pa, _va, _sz, _attr) \
- _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, REGION_DEFAULT_GRANULARITY)
+ MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, REGION_DEFAULT_GRANULARITY)
/* Helper macro to define an mmap_region_t with an identity mapping. */
#define MAP_REGION_FLAT(_adr, _sz, _attr) \
@@ -44,7 +44,7 @@
* equivalent to the MAP_REGION() macro.
*/
#define MAP_REGION2(_pa, _va, _sz, _attr, _gr) \
- _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)
+ MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)
/*
* Shifts and masks to access fields of an mmap attribute
@@ -121,10 +121,13 @@ typedef struct mmap_region {
} mmap_region_t;
/*
- * Translation regimes supported by this library.
+ * Translation regimes supported by this library. EL_REGIME_INVALID tells the
+ * library to detect it at runtime.
*/
#define EL1_EL0_REGIME 1
+#define EL2_REGIME 2
#define EL3_REGIME 3
+#define EL_REGIME_INVALID -1
/*
* Declare the translation context type.
@@ -161,12 +164,11 @@ typedef struct xlat_ctx xlat_ctx_t;
*/
#define REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count, \
_virt_addr_space_size, _phy_addr_space_size) \
- _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \
+ REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \
(_xlat_tables_count), \
(_virt_addr_space_size), \
(_phy_addr_space_size), \
- IMAGE_XLAT_DEFAULT_REGIME, \
- "xlat_table")
+ EL_REGIME_INVALID, "xlat_table")
/*
* Same as REGISTER_XLAT_CONTEXT plus the additional parameters:
@@ -182,7 +184,7 @@ typedef struct xlat_ctx xlat_ctx_t;
#define REGISTER_XLAT_CONTEXT2(_ctx_name, _mmap_count, _xlat_tables_count, \
_virt_addr_space_size, _phy_addr_space_size, \
_xlat_regime, _section_name) \
- _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \
+ REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, (_mmap_count), \
(_xlat_tables_count), \
(_virt_addr_space_size), \
(_phy_addr_space_size), \
@@ -295,14 +297,15 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx,
* translation tables are not modified by any other code while this function is
* executing.
*/
-int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size,
- uint32_t attr);
+int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+ size_t size, uint32_t attr);
+int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr);
/*
* Query the memory attributes of a memory page in a set of translation tables.
*
* Return 0 on success, a negative error code on error.
- * On success, the attributes are stored into *attributes.
+ * On success, the attributes are stored into *attr.
*
* ctx
* Translation context to work on.
@@ -310,11 +313,12 @@ int change_mem_attributes(xlat_ctx_t *ctx, uintptr_t base_va, size_t size,
* Virtual address of the page to get the attributes of.
* There are no alignment restrictions on this address. The attributes of the
* memory page it lies within are returned.
- * attributes
+ * attr
* Output parameter where to store the attributes of the targeted memory page.
*/
-int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
- uint32_t *attributes);
+int xlat_get_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+ uint32_t *attr);
+int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr);
#endif /*__ASSEMBLY__*/
-#endif /* __XLAT_TABLES_V2_H__ */
+#endif /* XLAT_TABLES_V2_H */
diff --git a/include/lib/xlat_tables/xlat_tables_v2_helpers.h b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
index 56b9a93f4..fa8995886 100644
--- a/include/lib/xlat_tables/xlat_tables_v2_helpers.h
+++ b/include/lib/xlat_tables/xlat_tables_v2_helpers.h
@@ -9,31 +9,22 @@
* used outside of this library code.
*/
-#ifndef __XLAT_TABLES_V2_HELPERS_H__
-#define __XLAT_TABLES_V2_HELPERS_H__
+#ifndef XLAT_TABLES_V2_HELPERS_H
+#define XLAT_TABLES_V2_HELPERS_H
-#ifndef __XLAT_TABLES_V2_H__
+#ifndef XLAT_TABLES_V2_H
#error "Do not include this header file directly. Include xlat_tables_v2.h instead."
#endif
-/* Offsets into mmu_cfg_params array. All parameters are 32 bits wide. */
-#define MMU_CFG_MAIR0 0
-#define MMU_CFG_TCR 1
-#define MMU_CFG_TTBR0_LO 2
-#define MMU_CFG_TTBR0_HI 3
-#define MMU_CFG_PARAM_MAX 4
-
#ifndef __ASSEMBLY__
#include <cassert.h>
#include <platform_def.h>
+#include <stdbool.h>
#include <stddef.h>
#include <xlat_tables_arch.h>
#include <xlat_tables_defs.h>
-/* Parameters of register values required when enabling MMU */
-extern uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/* Forward declaration */
struct mmap_region;
@@ -42,7 +33,7 @@ struct mmap_region;
* the fields of the structure but its parameter list is not guaranteed to
* remain stable as we add members to mmap_region_t.
*/
-#define _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \
+#define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \
{ \
.base_pa = (_pa), \
.base_va = (_va), \
@@ -68,7 +59,7 @@ struct xlat_ctx {
* null entry.
*/
struct mmap_region *mmap;
- unsigned int mmap_num;
+ int mmap_num;
/*
* Array of finer-grain translation tables.
@@ -76,7 +67,7 @@ struct xlat_ctx {
* contain both level-2 and level-3 entries.
*/
uint64_t (*tables)[XLAT_TABLE_ENTRIES];
- unsigned int tables_num;
+ int tables_num;
/*
* Keep track of how many regions are mapped in each table. The base
* table can't be unmapped so it isn't needed to keep track of it.
@@ -85,7 +76,7 @@ struct xlat_ctx {
int *tables_mapped_regions;
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
- unsigned int next_table;
+ int next_table;
/*
* Base translation table. It doesn't need to have the same amount of
@@ -105,8 +96,8 @@ struct xlat_ctx {
/* Level of the base translation table. */
unsigned int base_level;
- /* Set to 1 when the translation tables are initialized. */
- unsigned int initialized;
+ /* Set to true when the translation tables are initialized. */
+ bool initialized;
/*
* Translation regime managed by this xlat_ctx_t. It should be one of
@@ -116,85 +107,60 @@ struct xlat_ctx {
};
#if PLAT_XLAT_TABLES_DYNAMIC
-#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
+#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
static int _ctx_name##_mapped_regions[_xlat_tables_count];
-#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \
+#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
.tables_mapped_regions = _ctx_name##_mapped_regions,
#else
-#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
+#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
/* do nothing */
-#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \
+#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
/* do nothing */
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
-#define _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, _xlat_tables_count, \
- _virt_addr_space_size, _phy_addr_space_size, \
- _xlat_regime, _section_name) \
- CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \
- assert_invalid_virtual_addr_space_size_for_##_ctx_name); \
- \
- CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
- assert_invalid_physical_addr_space_sizefor_##_ctx_name); \
- \
- static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
- \
- static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
- [XLAT_TABLE_ENTRIES] \
- __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
- \
- static uint64_t _ctx_name##_base_xlat_table \
- [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
- __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) \
- * sizeof(uint64_t)); \
- \
- _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
- \
- static xlat_ctx_t _ctx_name##_xlat_ctx = { \
- .va_max_address = (_virt_addr_space_size) - 1, \
- .pa_max_address = (_phy_addr_space_size) - 1, \
- .mmap = _ctx_name##_mmap, \
- .mmap_num = (_mmap_count), \
- .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size), \
- .base_table = _ctx_name##_base_xlat_table, \
- .base_table_entries = \
- GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size), \
- .tables = _ctx_name##_xlat_tables, \
- .tables_num = _xlat_tables_count, \
- _REGISTER_DYNMAP_STRUCT(_ctx_name) \
- .xlat_regime = (_xlat_regime), \
- .max_pa = 0, \
- .max_va = 0, \
- .next_table = 0, \
- .initialized = 0, \
+#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
+ _xlat_tables_count, _virt_addr_space_size, \
+ _phy_addr_space_size, _xlat_regime, _section_name)\
+ CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \
+ assert_invalid_virtual_addr_space_size_for_##_ctx_name);\
+ \
+ CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
+ assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
+ \
+ static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
+ \
+ static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
+ [XLAT_TABLE_ENTRIES] \
+ __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
+ \
+ static uint64_t _ctx_name##_base_xlat_table \
+ [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
+ __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
+ * sizeof(uint64_t)); \
+ \
+ XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
+ \
+ static xlat_ctx_t _ctx_name##_xlat_ctx = { \
+ .va_max_address = (_virt_addr_space_size) - 1UL, \
+ .pa_max_address = (_phy_addr_space_size) - 1ULL, \
+ .mmap = _ctx_name##_mmap, \
+ .mmap_num = (_mmap_count), \
+ .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
+ .base_table = _ctx_name##_base_xlat_table, \
+ .base_table_entries = \
+ GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
+ .tables = _ctx_name##_xlat_tables, \
+ .tables_num = _xlat_tables_count, \
+ XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
+ .xlat_regime = (_xlat_regime), \
+ .max_pa = 0U, \
+ .max_va = 0U, \
+ .next_table = 0, \
+ .initialized = false, \
}
#endif /*__ASSEMBLY__*/
-#if AARCH64
-
-/*
- * This IMAGE_EL macro must not to be used outside the library, and it is only
- * used in AArch64.
- */
-#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
-# define IMAGE_EL 3
-# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME
-#else
-# define IMAGE_EL 1
-# define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
-#endif
-
-#else /* if AARCH32 */
-
-/*
- * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in
- * AArch64 except for the XN bits, but we set and unset them at the same time,
- * so there's no difference in practice.
- */
-#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
-
-#endif /* AARCH64 */
-
-#endif /* __XLAT_TABLES_V2_HELPERS_H__ */
+#endif /* XLAT_TABLES_V2_HELPERS_H */
diff --git a/include/plat/arm/board/common/board_arm_def.h b/include/plat/arm/board/common/board_arm_def.h
index 5e1d680ce..a388ed9ac 100644
--- a/include/plat/arm/board/common/board_arm_def.h
+++ b/include/plat/arm/board/common/board_arm_def.h
@@ -28,7 +28,7 @@
# define PLATFORM_STACK_SIZE 0x400
# endif
#elif defined(IMAGE_BL2U)
-# define PLATFORM_STACK_SIZE 0x200
+# define PLATFORM_STACK_SIZE 0x400
#elif defined(IMAGE_BL31)
#if ENABLE_SPM
# define PLATFORM_STACK_SIZE 0x500
@@ -71,9 +71,12 @@
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
# define MAX_XLAT_TABLES 5
-#else
+#elif !USE_ROMLIB
# define PLAT_ARM_MMAP_ENTRIES 11
# define MAX_XLAT_TABLES 5
+#else
+# define PLAT_ARM_MMAP_ENTRIES 12
+# define MAX_XLAT_TABLES 6
#endif
/*
@@ -83,6 +86,18 @@
#define PLAT_ARM_MAX_BL1_RW_SIZE 0xB000
/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0xe000
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0
+#endif
+
+/*
* PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
* little space for growth.
*/
diff --git a/include/plat/arm/common/arm_config.h b/include/plat/arm/common/arm_config.h
index 02e04fd3b..44610bd97 100644
--- a/include/plat/arm/common/arm_config.h
+++ b/include/plat/arm/common/arm_config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,19 +9,21 @@
#include <stdint.h>
#include <utils_def.h>
-enum arm_config_flags {
- /* Whether Base memory map is in use */
- ARM_CONFIG_BASE_MMAP = BIT(1),
- /* Whether TZC should be configured */
- ARM_CONFIG_HAS_TZC = BIT(2),
- /* FVP model has shifted affinity */
- ARM_CONFIG_FVP_SHIFTED_AFF = BIT(3),
- /* FVP model has SMMUv3 affinity */
- ARM_CONFIG_FVP_HAS_SMMUV3 = BIT(4),
- /* FVP model has CCI (400 or 500/550) devices */
- ARM_CONFIG_FVP_HAS_CCI400 = BIT(5),
- ARM_CONFIG_FVP_HAS_CCI5XX = BIT(6),
-};
+/* Whether Base memory map is in use */
+#define ARM_CONFIG_BASE_MMAP BIT(1)
+
+/* Whether TZC should be configured */
+#define ARM_CONFIG_HAS_TZC BIT(2)
+
+/* FVP model has shifted affinity */
+#define ARM_CONFIG_FVP_SHIFTED_AFF BIT(3)
+
+/* FVP model has SMMUv3 affinity */
+#define ARM_CONFIG_FVP_HAS_SMMUV3 BIT(4)
+
+/* FVP model has CCI (400 or 500/550) devices */
+#define ARM_CONFIG_FVP_HAS_CCI400 BIT(5)
+#define ARM_CONFIG_FVP_HAS_CCI5XX BIT(6)
typedef struct arm_config {
unsigned long flags;
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index e3d0edbce..ea9d811c2 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -3,8 +3,8 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __ARM_DEF_H__
-#define __ARM_DEF_H__
+#ifndef ARM_DEF_H
+#define ARM_DEF_H
#include <arch.h>
#include <common_def.h>
@@ -40,12 +40,12 @@
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
-#define ARM_LOCAL_STATE_RUN 0
+#define ARM_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define ARM_LOCAL_STATE_RET 1
+#define ARM_LOCAL_STATE_RET U(1)
/* Local power state for OFF/power-down. Valid for CPU and cluster power
domains */
-#define ARM_LOCAL_STATE_OFF 2
+#define ARM_LOCAL_STATE_OFF U(2)
/* Memory location options for TSP */
#define ARM_TRUSTED_SRAM_ID 0
@@ -186,25 +186,25 @@
* as Group 0 interrupts.
*/
#define ARM_G1S_IRQ_PROPS(grp) \
- INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE)
#define ARM_G0_IRQ_PROPS(grp) \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, PLAT_SDEI_NORMAL_PRI, (grp), \
GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \
GIC_INTR_CFG_EDGE)
#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
@@ -242,15 +242,50 @@
MT_MEMORY | MT_RW | MT_SECURE)
/*
- * The number of regions like RO(code), coherent and data required by
- * different BL stages which need to be mapped in the MMU.
+ * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
+ * otherwise one region is defined containing both.
*/
-#if USE_COHERENT_MEM
-# define ARM_BL_REGIONS 4
+#if SEPARATE_CODE_AND_RODATA
+#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE), \
+ MAP_REGION_FLAT( \
+ BL_RO_DATA_BASE, \
+ BL_RO_DATA_END \
+ - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
#else
-# define ARM_BL_REGIONS 3
+#define ARM_MAP_BL_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+#endif
+#if USE_COHERENT_MEM
+#define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \
+ BL_COHERENT_RAM_BASE, \
+ BL_COHERENT_RAM_END \
+ - BL_COHERENT_RAM_BASE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+#endif
+#if USE_ROMLIB
+#define ARM_MAP_ROMLIB_CODE MAP_REGION_FLAT( \
+ ROMLIB_RO_BASE, \
+ ROMLIB_RO_LIMIT - ROMLIB_RO_BASE,\
+ MT_CODE | MT_SECURE)
+
+#define ARM_MAP_ROMLIB_DATA MAP_REGION_FLAT( \
+ ROMLIB_RW_BASE, \
+ ROMLIB_RW_END - ROMLIB_RW_BASE,\
+ MT_MEMORY | MT_RW | MT_SECURE)
#endif
+/*
+ * The max number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+# define ARM_BL_REGIONS 4
+
#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \
ARM_BL_REGIONS)
@@ -322,14 +357,23 @@
******************************************************************************/
#define BL1_RO_BASE PLAT_ARM_TRUSTED_ROM_BASE
#define BL1_RO_LIMIT (PLAT_ARM_TRUSTED_ROM_BASE \
- + PLAT_ARM_TRUSTED_ROM_SIZE)
+ + (PLAT_ARM_TRUSTED_ROM_SIZE - \
+ PLAT_ARM_MAX_ROMLIB_RO_SIZE))
/*
* Put BL1 RW at the top of the Trusted SRAM.
*/
#define BL1_RW_BASE (ARM_BL_RAM_BASE + \
ARM_BL_RAM_SIZE - \
- PLAT_ARM_MAX_BL1_RW_SIZE)
-#define BL1_RW_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
+ (PLAT_ARM_MAX_BL1_RW_SIZE +\
+ PLAT_ARM_MAX_ROMLIB_RW_SIZE))
+#define BL1_RW_LIMIT (ARM_BL_RAM_BASE + \
+ (ARM_BL_RAM_SIZE - PLAT_ARM_MAX_ROMLIB_RW_SIZE))
+
+#define ROMLIB_RO_BASE BL1_RO_LIMIT
+#define ROMLIB_RO_LIMIT (PLAT_ARM_TRUSTED_ROM_BASE + PLAT_ARM_TRUSTED_ROM_SIZE)
+
+#define ROMLIB_RW_BASE (BL1_RW_BASE + PLAT_ARM_MAX_BL1_RW_SIZE)
+#define ROMLIB_RW_END (ROMLIB_RW_BASE + PLAT_ARM_MAX_ROMLIB_RW_SIZE)
/*******************************************************************************
* BL2 specific defines.
@@ -509,4 +553,4 @@
SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_1, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC), \
SDEI_SHARED_EVENT(ARM_SDEI_DS_EVENT_2, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
-#endif /* __ARM_DEF_H__ */
+#endif /* ARM_DEF_H */
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 83277a6c5..6aa8ce8ec 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.h
@@ -7,7 +7,6 @@
#define __ARM_SPM_DEF_H__
#include <arm_def.h>
-#include <platform_def.h>
#include <utils_def.h>
#include <xlat_tables_defs.h>
@@ -73,12 +72,11 @@
/*
* RW memory, which uses the remaining Trusted DRAM. Placed after the memory
- * shared between Secure and Non-secure worlds. First there is the stack memory
- * for all CPUs and then there is the common heap memory. Both are mapped with
- * RW permissions.
+ * shared between Secure and Non-secure worlds, or after the platform specific
+ * buffers, if defined. First there is the stack memory for all CPUs and then
+ * there is the common heap memory. Both are mapped with RW permissions.
*/
-#define PLAT_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
- ARM_SP_IMAGE_NS_BUF_SIZE)
+#define PLAT_SP_IMAGE_STACK_BASE PLAT_ARM_SP_IMAGE_STACK_BASE
#define PLAT_SP_IMAGE_STACK_PCPU_SIZE ULL(0x2000)
#define ARM_SP_IMAGE_STACK_TOTAL_SIZE (PLATFORM_CORE_COUNT * \
PLAT_SP_IMAGE_STACK_PCPU_SIZE)
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 42bbf385b..1af4dd1ac 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -69,17 +69,10 @@ typedef struct arm_tzc_regions_info {
/*
* Utility functions common to ARM standard platforms
*/
-void arm_setup_page_tables(uintptr_t total_base,
- size_t total_size,
- uintptr_t code_start,
- uintptr_t code_limit,
- uintptr_t rodata_start,
- uintptr_t rodata_limit
-#if USE_COHERENT_MEM
- , uintptr_t coh_start,
- uintptr_t coh_limit
-#endif
-);
+void arm_setup_page_tables(const mmap_region_t bl_regions[],
+ const mmap_region_t plat_regions[]);
+
+void arm_setup_romlib(void);
#if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
/*
@@ -292,5 +285,6 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
/* global variables */
extern plat_psci_ops_t plat_arm_psci_pm_ops;
extern const mmap_region_t plat_arm_mmap[];
+extern const unsigned int arm_pm_idle_states[];
#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 725c27cbc..048c58a31 100644
--- a/include/plat/arm/css/common/css_def.h
+++ b/include/plat/arm/css/common/css_def.h
@@ -101,6 +101,14 @@
NSRAM_SIZE, \
MT_DEVICE | MT_RW | MT_NS)
+#if defined(IMAGE_BL2U)
+#define CSS_MAP_SCP_BL2U MAP_REGION_FLAT( \
+ SCP_BL2U_BASE, \
+ SCP_BL2U_LIMIT \
+ - SCP_BL2U_BASE,\
+ MT_RW_DATA | MT_SECURE)
+#endif
+
/* Platform ID address */
#define SSC_VERSION_OFFSET 0x040
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index e834fffc6..a24367134 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -9,7 +9,7 @@
#include <cdefs.h>
#include <psci.h>
-#include <types.h>
+#include <stdint.h>
/* System power domain at level 2, as currently implemented by CSS platforms */
#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
diff --git a/include/plat/common/common_def.h b/include/plat/common/common_def.h
index 827d416f3..e66af782a 100644
--- a/include/plat/common/common_def.h
+++ b/include/plat/common/common_def.h
@@ -8,6 +8,7 @@
#include <bl_common.h>
#include <platform_def.h>
+#include <xlat_tables_defs.h>
/******************************************************************************
* Required platform porting definitions that are expected to be common to
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index cd17a00f1..dae958957 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -4,13 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_H__
-#define __PLATFORM_H__
+#ifndef PLATFORM_H
+#define PLATFORM_H
#include <psci.h>
#include <stdint.h>
-#include <types.h>
-
/*******************************************************************************
* Forward declarations
@@ -401,5 +399,4 @@ unsigned int platform_get_core_pos(unsigned long mpidr) __deprecated;
#endif /* __ENABLE_PLAT_COMPAT__ */
-#endif /* __PLATFORM_H__ */
-
+#endif /* PLATFORM_H */
diff --git a/include/plat/marvell/a8k/common/a8k_common.h b/include/plat/marvell/a8k/common/a8k_common.h
new file mode 100644
index 000000000..e72746792
--- /dev/null
+++ b/include/plat/marvell/a8k/common/a8k_common.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __A8K_COMMON_H__
+#define __A8K_COMMON_H__
+
+#include <amb_adec.h>
+#include <io_win.h>
+#include <iob.h>
+#include <ccu.h>
+
+/*
+ * This struct supports skip image request
+ * detection_method: the method used to detect the request "signal".
+ * info:
+ * GPIO:
+ * detection_method: HIGH (pressed button), LOW (unpressed button),
+ * num (button mpp number).
+ * i2c:
+ * i2c_addr: the address of the i2c chosen.
+ * i2d_reg: the i2c register chosen.
+ * test:
+ * choose the DIE you picked the button in (AP or CP).
+ * in case of CP(cp_index = 0 if CP0, cp_index = 1 if CP1)
+ */
+struct skip_image {
+ enum {
+ GPIO,
+ I2C,
+ USER_DEFINED
+ } detection_method;
+
+ struct {
+ struct {
+ int num;
+ enum {
+ HIGH,
+ LOW
+ } button_state;
+
+ } gpio;
+
+ struct {
+ int i2c_addr;
+ int i2c_reg;
+ } i2c;
+
+ struct {
+ enum {
+ CP,
+ AP
+ } cp_ap;
+ int cp_index;
+ } test;
+ } info;
+};
+
+/*
+ * This struct supports SoC power off method
+ * type: the method used to power off the SoC
+ * cfg:
+ * PMIC_GPIO:
+ * pin_count: current GPIO pin number used for toggling the signal for
+ * notifying external PMIC
+ * info: holds the GPIOs information, CP GPIO should be used and
+ * all GPIOs should be within same GPIO config. register
+ * step_count: current step number to toggle the GPIO for PMIC
+ * seq: GPIO toggling values in sequence, each bit represents a GPIO.
+ * For example, bit0 represents first GPIO used for toggling
+ * the GPIO the last step is used to trigger the power off
+ * signal
+ * delay_ms: transition interval for the GPIO setting to take effect
+ * in unit of ms
+ */
+/* Max GPIO number used to notify PMIC to power off the SoC */
+#define PMIC_GPIO_MAX_NUMBER 8
+/* Max GPIO toggling steps in sequence to power off the SoC */
+#define PMIC_GPIO_MAX_TOGGLE_STEP 8
+
+enum gpio_output_state {
+ GPIO_LOW = 0,
+ GPIO_HIGH
+};
+
+typedef struct gpio_info {
+ int cp_index;
+ int gpio_index;
+} gpio_info_t;
+
+struct power_off_method {
+ enum {
+ PMIC_GPIO,
+ } type;
+
+ struct {
+ struct {
+ int pin_count;
+ struct gpio_info info[PMIC_GPIO_MAX_NUMBER];
+ int step_count;
+ uint32_t seq[PMIC_GPIO_MAX_TOGGLE_STEP];
+ int delay_ms;
+ } gpio;
+ } cfg;
+};
+
+int marvell_gpio_config(void);
+uint32_t marvell_get_io_win_gcr_target(int ap_idx);
+uint32_t marvell_get_ccu_gcr_target(int ap_idx);
+
+
+/*
+ * The functions below are defined as Weak and may be overridden
+ * in specific Marvell standard platform
+ */
+int marvell_get_amb_memory_map(struct addr_map_win **win,
+ uint32_t *size, uintptr_t base);
+int marvell_get_io_win_memory_map(int ap_idx, struct addr_map_win **win,
+ uint32_t *size);
+int marvell_get_iob_memory_map(struct addr_map_win **win,
+ uint32_t *size, uintptr_t base);
+int marvell_get_ccu_memory_map(int ap_idx, struct addr_map_win **win,
+ uint32_t *size);
+
+#endif /* __A8K_COMMON_H__ */
diff --git a/include/plat/marvell/a8k/common/board_marvell_def.h b/include/plat/marvell/a8k/common/board_marvell_def.h
new file mode 100644
index 000000000..b1054db22
--- /dev/null
+++ b/include/plat/marvell/a8k/common/board_marvell_def.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __BOARD_MARVELL_DEF_H__
+#define __BOARD_MARVELL_DEF_H__
+
+/*
+ * Required platform porting definitions common to all ARM
+ * development platforms
+ */
+
+/* Size of cacheable stacks */
+#if DEBUG_XLAT_TABLE
+# define PLATFORM_STACK_SIZE 0x800
+#elif IMAGE_BL1
+#if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+#else
+# define PLATFORM_STACK_SIZE 0x440
+#endif
+#elif IMAGE_BL2
+# if TRUSTED_BOARD_BOOT
+# define PLATFORM_STACK_SIZE 0x1000
+# else
+# define PLATFORM_STACK_SIZE 0x400
+# endif
+#elif IMAGE_BL31
+# define PLATFORM_STACK_SIZE 0x400
+#elif IMAGE_BL32
+# define PLATFORM_STACK_SIZE 0x440
+#endif
+
+/*
+ * PLAT_MARVELL_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if IMAGE_BLE
+# define PLAT_MARVELL_MMAP_ENTRIES 3
+#endif
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+# define PLAT_MARVELL_MMAP_ENTRIES 7
+# else
+# define PLAT_MARVELL_MMAP_ENTRIES 6
+# endif /* TRUSTED_BOARD_BOOT */
+#endif
+#if IMAGE_BL2
+# define PLAT_MARVELL_MMAP_ENTRIES 8
+#endif
+#if IMAGE_BL31
+#define PLAT_MARVELL_MMAP_ENTRIES 5
+#endif
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#if IMAGE_BL1
+#define MAX_XLAT_TABLES 4
+#elif IMAGE_BLE
+# define MAX_XLAT_TABLES 4
+#elif IMAGE_BL2
+# define MAX_XLAT_TABLES 4
+#elif IMAGE_BL31
+# define MAX_XLAT_TABLES 4
+#elif IMAGE_BL32
+# define MAX_XLAT_TABLES 4
+#endif
+
+#define MAX_IO_DEVICES 3
+#define MAX_IO_HANDLES 4
+
+#define PLAT_MARVELL_TRUSTED_SRAM_SIZE 0x80000 /* 512 KB */
+
+
+#endif /* __BOARD_MARVELL_DEF_H__ */
diff --git a/include/plat/marvell/a8k/common/marvell_def.h b/include/plat/marvell/a8k/common/marvell_def.h
new file mode 100644
index 000000000..7dacf820a
--- /dev/null
+++ b/include/plat/marvell/a8k/common/marvell_def.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MARVELL_DEF_H__
+#define __MARVELL_DEF_H__
+
+#include <arch.h>
+#include <common_def.h>
+#include <platform_def.h>
+#include <tbbr_img_def.h>
+#include <xlat_tables.h>
+
+
+/******************************************************************************
+ * Definitions common to all MARVELL standard platforms
+ *****************************************************************************/
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define MARVELL_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
+
+
+#define MARVELL_CACHE_WRITEBACK_SHIFT 6
+
+/*
+ * Macros mapping the MPIDR Affinity levels to MARVELL Platform Power levels.
+ * The power levels have a 1:1 mapping with the MPIDR affinity levels.
+ */
+#define MARVELL_PWR_LVL0 MPIDR_AFFLVL0
+#define MARVELL_PWR_LVL1 MPIDR_AFFLVL1
+#define MARVELL_PWR_LVL2 MPIDR_AFFLVL2
+
+/*
+ * Macros for local power states in Marvell platforms encoded by
+ * State-ID field within the power-state parameter.
+ */
+/* Local power state for power domains in Run state. */
+#define MARVELL_LOCAL_STATE_RUN 0
+/* Local power state for retention. Valid only for CPU power domains */
+#define MARVELL_LOCAL_STATE_RET 1
+/*
+ * Local power state for OFF/power-down. Valid for CPU
+ * and cluster power domains
+ */
+#define MARVELL_LOCAL_STATE_OFF 2
+
+/* The first 4KB of Trusted SRAM are used as shared memory */
+#define MARVELL_TRUSTED_SRAM_BASE PLAT_MARVELL_ATF_BASE
+#define MARVELL_SHARED_RAM_BASE MARVELL_TRUSTED_SRAM_BASE
+#define MARVELL_SHARED_RAM_SIZE 0x00001000 /* 4 KB */
+
+/* The remaining Trusted SRAM is used to load the BL images */
+#define MARVELL_BL_RAM_BASE (MARVELL_SHARED_RAM_BASE + \
+ MARVELL_SHARED_RAM_SIZE)
+#define MARVELL_BL_RAM_SIZE (PLAT_MARVELL_TRUSTED_SRAM_SIZE - \
+ MARVELL_SHARED_RAM_SIZE)
+/* Non-shared DRAM */
+#define MARVELL_DRAM_BASE ULL(0x0)
+#define MARVELL_DRAM_SIZE ULL(0x80000000)
+#define MARVELL_DRAM_END (MARVELL_DRAM_BASE + \
+ MARVELL_DRAM_SIZE - 1)
+
+#define MARVELL_IRQ_SEC_PHY_TIMER 29
+
+#define MARVELL_IRQ_SEC_SGI_0 8
+#define MARVELL_IRQ_SEC_SGI_1 9
+#define MARVELL_IRQ_SEC_SGI_2 10
+#define MARVELL_IRQ_SEC_SGI_3 11
+#define MARVELL_IRQ_SEC_SGI_4 12
+#define MARVELL_IRQ_SEC_SGI_5 13
+#define MARVELL_IRQ_SEC_SGI_6 14
+#define MARVELL_IRQ_SEC_SGI_7 15
+
+#define MARVELL_MAP_SHARED_RAM MAP_REGION_FLAT( \
+ MARVELL_SHARED_RAM_BASE,\
+ MARVELL_SHARED_RAM_SIZE,\
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#define MARVELL_MAP_DRAM MAP_REGION_FLAT( \
+ MARVELL_DRAM_BASE, \
+ MARVELL_DRAM_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+
+/*
+ * The number of regions like RO(code), coherent and data required by
+ * different BL stages which need to be mapped in the MMU.
+ */
+#if USE_COHERENT_MEM
+#define MARVELL_BL_REGIONS 3
+#else
+#define MARVELL_BL_REGIONS 2
+#endif
+
+#define MAX_MMAP_REGIONS (PLAT_MARVELL_MMAP_ENTRIES + \
+ MARVELL_BL_REGIONS)
+
+#define MARVELL_CONSOLE_BAUDRATE 115200
+
+/******************************************************************************
+ * Required platform porting definitions common to all MARVELL std. platforms
+ *****************************************************************************/
+
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+
+/*
+ * This macro defines the deepest retention state possible. A higher state
+ * id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE MARVELL_LOCAL_STATE_RET
+
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE MARVELL_LOCAL_STATE_OFF
+
+
+#define PLATFORM_CORE_COUNT PLAT_MARVELL_CORE_COUNT
+#define PLAT_NUM_PWR_DOMAINS (PLAT_MARVELL_CLUSTER_COUNT + \
+ PLATFORM_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
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_GRANULE (1 << MARVELL_CACHE_WRITEBACK_SHIFT)
+
+
+/*******************************************************************************
+ * BL1 specific defines.
+ * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of
+ * addresses.
+ ******************************************************************************/
+#define BL1_RO_BASE PLAT_MARVELL_TRUSTED_ROM_BASE
+#define BL1_RO_LIMIT (PLAT_MARVELL_TRUSTED_ROM_BASE \
+ + PLAT_MARVELL_TRUSTED_ROM_SIZE)
+/*
+ * Put BL1 RW at the top of the Trusted SRAM.
+ */
+#define BL1_RW_BASE (MARVELL_BL_RAM_BASE + \
+ MARVELL_BL_RAM_SIZE - \
+ PLAT_MARVELL_MAX_BL1_RW_SIZE)
+#define BL1_RW_LIMIT (MARVELL_BL_RAM_BASE + MARVELL_BL_RAM_SIZE)
+
+/*******************************************************************************
+ * BLE specific defines.
+ ******************************************************************************/
+#define BLE_BASE PLAT_MARVELL_SRAM_BASE
+#define BLE_LIMIT PLAT_MARVELL_SRAM_END
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL2 just below BL31.
+ */
+#define BL2_BASE (BL31_BASE - PLAT_MARVELL_MAX_BL2_SIZE)
+#define BL2_LIMIT BL31_BASE
+
+/*******************************************************************************
+ * BL31 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL31 at the top of the Trusted SRAM.
+ */
+#define BL31_BASE (MARVELL_BL_RAM_BASE + \
+ MARVELL_BL_RAM_SIZE - \
+ PLAT_MARVEL_MAX_BL31_SIZE)
+#define BL31_PROGBITS_LIMIT BL1_RW_BASE
+#define BL31_LIMIT (MARVELL_BL_RAM_BASE + \
+ MARVELL_BL_RAM_SIZE)
+
+
+#endif /* __MARVELL_DEF_H__ */
diff --git a/include/plat/marvell/a8k/common/plat_marvell.h b/include/plat/marvell/a8k/common/plat_marvell.h
new file mode 100644
index 000000000..81cbf3871
--- /dev/null
+++ b/include/plat/marvell/a8k/common/plat_marvell.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PLAT_MARVELL_H__
+#define __PLAT_MARVELL_H__
+
+#include <cassert.h>
+#include <cpu_data.h>
+#include <stdint.h>
+#include <utils.h>
+#include <xlat_tables.h>
+
+/*
+ * Extern declarations common to Marvell standard platforms
+ */
+extern const mmap_region_t plat_marvell_mmap[];
+
+#define MARVELL_CASSERT_MMAP \
+ CASSERT((ARRAY_SIZE(plat_marvell_mmap) + MARVELL_BL_REGIONS) \
+ <= MAX_MMAP_REGIONS, \
+ assert_max_mmap_regions)
+
+/*
+ * Utility functions common to Marvell standard platforms
+ */
+void marvell_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+ , uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+);
+
+/* IO storage utility functions */
+void marvell_io_setup(void);
+
+/* Systimer utility function */
+void marvell_configure_sys_timer(void);
+
+/* Topology utility function */
+int marvell_check_mpidr(u_register_t mpidr);
+
+/* BLE utility functions */
+int ble_plat_setup(int *skip);
+void plat_marvell_dram_update_topology(void);
+void ble_plat_pcie_ep_setup(void);
+struct pci_hw_cfg *plat_get_pcie_hw_data(void);
+
+/* BL1 utility functions */
+void marvell_bl1_early_platform_setup(void);
+void marvell_bl1_platform_setup(void);
+void marvell_bl1_plat_arch_setup(void);
+
+/* BL2 utility functions */
+void marvell_bl2_early_platform_setup(meminfo_t *mem_layout);
+void marvell_bl2_platform_setup(void);
+void marvell_bl2_plat_arch_setup(void);
+uint32_t marvell_get_spsr_for_bl32_entry(void);
+uint32_t marvell_get_spsr_for_bl33_entry(void);
+
+/* BL31 utility functions */
+void marvell_bl31_early_platform_setup(struct bl31_params *from_bl2,
+ uintptr_t soc_fw_config,
+ uintptr_t hw_config,
+ void *plat_params_from_bl2);
+void marvell_bl31_platform_setup(void);
+void marvell_bl31_plat_runtime_setup(void);
+void marvell_bl31_plat_arch_setup(void);
+
+/* Power management config to power off the SoC */
+void *plat_marvell_get_pm_cfg(void);
+
+/* Check if MSS AP CM3 firmware contains PM support */
+_Bool is_pm_fw_running(void);
+
+/* Bootrom image recovery utility functions */
+void *plat_marvell_get_skip_image_data(void);
+
+/* FIP TOC validity check */
+int marvell_io_is_toc_valid(void);
+
+/*
+ * PSCI functionality
+ */
+void marvell_psci_arch_init(int ap_idx);
+void plat_marvell_system_reset(void);
+
+/*
+ * Optional functions required in Marvell standard platforms
+ */
+void plat_marvell_io_setup(void);
+int plat_marvell_get_alt_image_source(
+ unsigned int image_id,
+ uintptr_t *dev_handle,
+ uintptr_t *image_spec);
+unsigned int plat_marvell_calc_core_pos(u_register_t mpidr);
+
+const mmap_region_t *plat_marvell_get_mmap(void);
+void marvell_ble_prepare_exit(void);
+void marvell_exit_bootrom(uintptr_t base);
+
+int plat_marvell_early_cpu_powerdown(void);
+#endif /* __PLAT_MARVELL_H__ */
diff --git a/include/plat/marvell/a8k/common/plat_pm_trace.h b/include/plat/marvell/a8k/common/plat_pm_trace.h
new file mode 100644
index 000000000..0878959c4
--- /dev/null
+++ b/include/plat/marvell/a8k/common/plat_pm_trace.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PLAT_PM_TRACE_H
+#define __PLAT_PM_TRACE_H
+
+
+/*
+ * PM Trace is for Debug purpose only!!!
+ * It should not be enabled during System Run time
+ */
+#undef PM_TRACE_ENABLE
+
+
+/* trace entry time */
+struct pm_trace_entry {
+ /* trace entry time stamp */
+ unsigned int timestamp;
+
+ /* trace info
+ * [16-31] - API Trace Id
+ * [00-15] - API Step Id
+ */
+ unsigned int trace_info;
+};
+
+struct pm_trace_ctrl {
+ /* trace pointer - points to next free entry in trace cyclic queue */
+ unsigned int trace_pointer;
+
+ /* trace count - number of entries in the queue, clear upon read */
+ unsigned int trace_count;
+};
+
+/* trace size definition */
+#define AP_MSS_ATF_CORE_INFO_SIZE (256)
+#define AP_MSS_ATF_CORE_ENTRY_SIZE (8)
+#define AP_MSS_ATF_TRACE_SIZE_MASK (0xFF)
+
+/* trace address definition */
+#define AP_MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110)
+
+#define AP_MSS_ATF_CORE_0_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520140)
+#define AP_MSS_ATF_CORE_1_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520150)
+#define AP_MSS_ATF_CORE_2_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520160)
+#define AP_MSS_ATF_CORE_3_CTRL_BASE (MVEBU_REGS_BASE_MASK + 0x520170)
+#define AP_MSS_ATF_CORE_CTRL_BASE (AP_MSS_ATF_CORE_0_CTRL_BASE)
+
+#define AP_MSS_ATF_CORE_0_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5201C0)
+#define AP_MSS_ATF_CORE_0_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5201C4)
+#define AP_MSS_ATF_CORE_1_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5209C0)
+#define AP_MSS_ATF_CORE_1_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5209C4)
+#define AP_MSS_ATF_CORE_2_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5211C0)
+#define AP_MSS_ATF_CORE_2_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5211C4)
+#define AP_MSS_ATF_CORE_3_INFO_BASE (MVEBU_REGS_BASE_MASK + 0x5219C0)
+#define AP_MSS_ATF_CORE_3_INFO_TRACE (MVEBU_REGS_BASE_MASK + 0x5219C4)
+#define AP_MSS_ATF_CORE_INFO_BASE (AP_MSS_ATF_CORE_0_INFO_BASE)
+
+/* trace info definition */
+#define TRACE_PWR_DOMAIN_OFF (0x10000)
+#define TRACE_PWR_DOMAIN_SUSPEND (0x20000)
+#define TRACE_PWR_DOMAIN_SUSPEND_FINISH (0x30000)
+#define TRACE_PWR_DOMAIN_ON (0x40000)
+#define TRACE_PWR_DOMAIN_ON_FINISH (0x50000)
+
+#define TRACE_PWR_DOMAIN_ON_MASK (0xFF)
+
+#ifdef PM_TRACE_ENABLE
+
+/* trace API definition */
+void pm_core_0_trace(unsigned int trace);
+void pm_core_1_trace(unsigned int trace);
+void pm_core_2_trace(unsigned int trace);
+void pm_core_3_trace(unsigned int trace);
+
+typedef void (*core_trace_func)(unsigned int);
+
+extern core_trace_func funcTbl[PLATFORM_CORE_COUNT];
+
+#define PM_TRACE(trace) funcTbl[plat_my_core_pos()](trace)
+
+#else
+
+#define PM_TRACE(trace)
+
+#endif
+
+/*******************************************************************************
+ * pm_trace_add
+ *
+ * DESCRIPTION: Add PM trace
+ ******************************************************************************
+ */
+void pm_trace_add(unsigned int trace, unsigned int core);
+
+#endif /* __PLAT_PM_TRACE_H */
diff --git a/include/plat/marvell/common/aarch64/cci_macros.S b/include/plat/marvell/common/aarch64/cci_macros.S
new file mode 100644
index 000000000..d6080cfdd
--- /dev/null
+++ b/include/plat/marvell/common/aarch64/cci_macros.S
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#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 print_cci_regs
+ adr x6, cci_iface_regs
+ /* Store in x7 the base address of the first interface */
+ mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \
+ PLAT_MARVELL_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_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \
+ PLAT_MARVELL_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/marvell/common/aarch64/marvell_macros.S b/include/plat/marvell/common/aarch64/marvell_macros.S
new file mode 100644
index 000000000..0102af042
--- /dev/null
+++ b/include/plat/marvell/common/aarch64/marvell_macros.S
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MARVELL_MACROS_S__
+#define __MARVELL_MACROS_S__
+
+#include <cci.h>
+#include <gic_common.h>
+#include <gicv2.h>
+#include <gicv3.h>
+#include <platform_def.h>
+
+/*
+ * These Macros are required by ATF
+ */
+
+.section .rodata.gic_reg_name, "aS"
+/* Applicable only to GICv2 and GICv3 with SRE disabled (legacy mode) */
+gicc_regs:
+ .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", ""
+
+#ifdef USE_CCI
+/* Applicable only to GICv3 with SRE enabled */
+icc_regs:
+ .asciz "icc_hppir0_el1", "icc_hppir1_el1", "icc_ctlr_el3", ""
+#endif
+/* Registers common to both GICv2 and GICv3 */
+gicd_pend_reg:
+ .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n" \
+ " Offset:\t\t\tvalue\n"
+newline:
+ .asciz "\n"
+spacer:
+ .asciz ":\t\t0x"
+
+ /* ---------------------------------------------
+ * The below utility macro prints out relevant GIC
+ * registers whenever an unhandled exception is
+ * taken in BL31 on ARM standard platforms.
+ * Expects: GICD base in x16, GICC base in x17
+ * Clobbers: x0 - x10, sp
+ * ---------------------------------------------
+ */
+ .macro arm_print_gic_regs
+ /* Check for GICv3 system register access */
+ mrs x7, id_aa64pfr0_el1
+ ubfx x7, x7, #ID_AA64PFR0_GIC_SHIFT, #ID_AA64PFR0_GIC_WIDTH
+ cmp x7, #1
+ b.ne print_gicv2
+
+ /* Check for SRE enable */
+ mrs x8, ICC_SRE_EL3
+ tst x8, #ICC_SRE_SRE_BIT
+ b.eq print_gicv2
+
+#ifdef USE_CCI
+ /* Load the icc reg list to x6 */
+ adr x6, icc_regs
+ /* Load the icc regs to gp regs used by str_in_crash_buf_print */
+ mrs x8, ICC_HPPIR0_EL1
+ mrs x9, ICC_HPPIR1_EL1
+ mrs x10, ICC_CTLR_EL3
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+#endif
+ b print_gic_common
+
+print_gicv2:
+ /* Load the gicc reg list to x6 */
+ adr x6, gicc_regs
+ /* Load the gicc regs to gp regs used by str_in_crash_buf_print */
+ ldr w8, [x17, #GICC_HPPIR]
+ ldr w9, [x17, #GICC_AHPPIR]
+ ldr w10, [x17, #GICC_CTLR]
+ /* Store to the crash buf and print to console */
+ bl str_in_crash_buf_print
+
+print_gic_common:
+ /* Print the GICD_ISPENDR regs */
+ add x7, x16, #GICD_ISPENDR
+ adr x4, gicd_pend_reg
+ bl asm_print_str
+gicd_ispendr_loop:
+ sub x4, x7, x16
+ cmp x4, #0x280
+ b.eq exit_print_gic_regs
+ bl asm_print_hex
+
+ adr x4, spacer
+ bl asm_print_str
+
+ ldr x4, [x7], #8
+ bl asm_print_hex
+
+ adr x4, newline
+ bl asm_print_str
+ b gicd_ispendr_loop
+exit_print_gic_regs:
+ .endm
+
+
+.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 print_cci_regs
+#ifdef USE_CCI
+ adr x6, cci_iface_regs
+ /* Store in x7 the base address of the first interface */
+ mov_imm x7, (PLAT_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \
+ PLAT_MARVELL_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_MARVELL_CCI_BASE + SLAVE_IFACE_OFFSET( \
+ PLAT_MARVELL_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
+#endif
+ .endm
+
+
+#endif /* __MARVELL_MACROS_S__ */
diff --git a/include/plat/marvell/common/marvell_plat_priv.h b/include/plat/marvell/common/marvell_plat_priv.h
new file mode 100644
index 000000000..c1dad0ef4
--- /dev/null
+++ b/include/plat/marvell/common/marvell_plat_priv.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MARVELL_PLAT_PRIV_H__
+#define __MARVELL_PLAT_PRIV_H__
+
+#include <utils.h>
+
+/*****************************************************************************
+ * Function and variable prototypes
+ *****************************************************************************
+ */
+void plat_delay_timer_init(void);
+
+uint64_t mvebu_get_dram_size(uint64_t ap_base_addr);
+
+/*
+ * GIC operation, mandatory functions required in Marvell standard platforms
+ */
+void plat_marvell_gic_driver_init(void);
+void plat_marvell_gic_init(void);
+void plat_marvell_gic_cpuif_enable(void);
+void plat_marvell_gic_cpuif_disable(void);
+void plat_marvell_gic_pcpu_init(void);
+void plat_marvell_gic_irq_save(void);
+void plat_marvell_gic_irq_restore(void);
+void plat_marvell_gic_irq_pcpu_save(void);
+void plat_marvell_gic_irq_pcpu_restore(void);
+
+#endif /* __MARVELL_PLAT_PRIV_H__ */
diff --git a/include/plat/marvell/common/marvell_pm.h b/include/plat/marvell/common/marvell_pm.h
new file mode 100644
index 000000000..2817a4626
--- /dev/null
+++ b/include/plat/marvell/common/marvell_pm.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef _MARVELL_PM_H_
+#define _MARVELL_PM_H_
+
+#define MVEBU_MAILBOX_MAGIC_NUM PLAT_MARVELL_MAILBOX_MAGIC_NUM
+#define MVEBU_MAILBOX_SUSPEND_STATE 0xb007de7c
+
+/* Mailbox entry indexes */
+/* Magic number for validity check */
+#define MBOX_IDX_MAGIC 0
+/* Recovery from suspend entry point */
+#define MBOX_IDX_SEC_ADDR 1
+/* Suspend state magic number */
+#define MBOX_IDX_SUSPEND_MAGIC 2
+/* Recovery jump address for ROM bypass */
+#define MBOX_IDX_ROM_EXIT_ADDR 3
+/* BLE execution start counter value */
+#define MBOX_IDX_START_CNT 4
+
+#endif /* _MARVELL_PM_H_ */
diff --git a/include/plat/marvell/common/mvebu.h b/include/plat/marvell/common/mvebu.h
new file mode 100644
index 000000000..a20e538e3
--- /dev/null
+++ b/include/plat/marvell/common/mvebu.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef _MVEBU_H_
+#define _MVEBU_H_
+
+/* Use this functions only when printf is allowed */
+#define debug_enter() VERBOSE("----> Enter %s\n", __func__)
+#define debug_exit() VERBOSE("<---- Exit %s\n", __func__)
+
+/* Macro for testing alignment. Positive if number is NOT aligned */
+#define IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
+
+/* Macro for alignment up. For example, ALIGN_UP(0x0330, 0x20) = 0x0340 */
+#define ALIGN_UP(number, align) (((number) & ((align) - 1)) ? \
+ (((number) + (align)) & ~((align)-1)) : (number))
+
+/* Macro for testing whether a number is a power of 2. Positive if so */
+#define IS_POWER_OF_2(number) ((number) != 0 && \
+ (((number) & ((number) - 1)) == 0))
+
+/*
+ * Macro for ronding up to next power of 2
+ * it is done by count leading 0 (clz assembly opcode) and see msb set bit.
+ * then you can shift it left and get number which power of 2
+ * Note: this Macro is for 32 bit number
+ */
+#define ROUND_UP_TO_POW_OF_2(number) (1 << \
+ (32 - __builtin_clz((number) - 1)))
+
+#define _1MB_ (1024ULL*1024ULL)
+#define _1GB_ (_1MB_*1024ULL)
+
+#endif /* MVEBU_H */
diff --git a/include/services/sdei.h b/include/services/sdei.h
index 79d1d065d..4d0fd3fd3 100644
--- a/include/services/sdei.h
+++ b/include/services/sdei.h
@@ -4,61 +4,56 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SDEI_H__
-#define __SDEI_H__
+#ifndef SDEI_H
+#define SDEI_H
#include <spinlock.h>
#include <utils_def.h>
/* Range 0xC4000020 - 0xC400003F reserved for SDE 64bit smc calls */
-#define SDEI_VERSION 0xC4000020
-#define SDEI_EVENT_REGISTER 0xC4000021
-#define SDEI_EVENT_ENABLE 0xC4000022
-#define SDEI_EVENT_DISABLE 0xC4000023
-#define SDEI_EVENT_CONTEXT 0xC4000024
-#define SDEI_EVENT_COMPLETE 0xC4000025
-#define SDEI_EVENT_COMPLETE_AND_RESUME 0xC4000026
-
-#define SDEI_EVENT_UNREGISTER 0xC4000027
-#define SDEI_EVENT_STATUS 0xC4000028
-#define SDEI_EVENT_GET_INFO 0xC4000029
-#define SDEI_EVENT_ROUTING_SET 0xC400002A
-#define SDEI_PE_MASK 0xC400002B
-#define SDEI_PE_UNMASK 0xC400002C
-
-#define SDEI_INTERRUPT_BIND 0xC400002D
-#define SDEI_INTERRUPT_RELEASE 0xC400002E
-#define SDEI_EVENT_SIGNAL 0xC400002F
-#define SDEI_FEATURES 0xC4000030
-#define SDEI_PRIVATE_RESET 0xC4000031
-#define SDEI_SHARED_RESET 0xC4000032
+#define SDEI_VERSION 0xC4000020U
+#define SDEI_EVENT_REGISTER 0xC4000021U
+#define SDEI_EVENT_ENABLE 0xC4000022U
+#define SDEI_EVENT_DISABLE 0xC4000023U
+#define SDEI_EVENT_CONTEXT 0xC4000024U
+#define SDEI_EVENT_COMPLETE 0xC4000025U
+#define SDEI_EVENT_COMPLETE_AND_RESUME 0xC4000026U
+
+#define SDEI_EVENT_UNREGISTER 0xC4000027U
+#define SDEI_EVENT_STATUS 0xC4000028U
+#define SDEI_EVENT_GET_INFO 0xC4000029U
+#define SDEI_EVENT_ROUTING_SET 0xC400002AU
+#define SDEI_PE_MASK 0xC400002BU
+#define SDEI_PE_UNMASK 0xC400002CU
+
+#define SDEI_INTERRUPT_BIND 0xC400002DU
+#define SDEI_INTERRUPT_RELEASE 0xC400002EU
+#define SDEI_EVENT_SIGNAL 0xC400002FU
+#define SDEI_FEATURES 0xC4000030U
+#define SDEI_PRIVATE_RESET 0xC4000031U
+#define SDEI_SHARED_RESET 0xC4000032U
/* SDEI_EVENT_REGISTER flags */
-#define SDEI_REGF_RM_ANY 0
-#define SDEI_REGF_RM_PE 1
+#define SDEI_REGF_RM_ANY 0ULL
+#define SDEI_REGF_RM_PE 1ULL
/* SDEI_EVENT_COMPLETE status flags */
-#define SDEI_EV_HANDLED 0
-#define SDEI_EV_FAILED 1
-
-/* SDE event status values in bit position */
-#define SDEI_STATF_REGISTERED 0
-#define SDEI_STATF_ENABLED 1
-#define SDEI_STATF_RUNNING 2
+#define SDEI_EV_HANDLED 0U
+#define SDEI_EV_FAILED 1U
/* Internal: SDEI flag bit positions */
-#define _SDEI_MAPF_DYNAMIC_SHIFT 1
-#define _SDEI_MAPF_BOUND_SHIFT 2
-#define _SDEI_MAPF_SIGNALABLE_SHIFT 3
-#define _SDEI_MAPF_PRIVATE_SHIFT 4
-#define _SDEI_MAPF_CRITICAL_SHIFT 5
-#define _SDEI_MAPF_EXPLICIT_SHIFT 6
+#define SDEI_MAPF_DYNAMIC_SHIFT_ 1U
+#define SDEI_MAPF_BOUND_SHIFT_ 2U
+#define SDEI_MAPF_SIGNALABLE_SHIFT_ 3U
+#define SDEI_MAPF_PRIVATE_SHIFT_ 4U
+#define SDEI_MAPF_CRITICAL_SHIFT_ 5U
+#define SDEI_MAPF_EXPLICIT_SHIFT_ 6U
/* SDEI event 0 */
#define SDEI_EVENT_0 0
/* Placeholder interrupt for dynamic mapping */
-#define SDEI_DYN_IRQ 0
+#define SDEI_DYN_IRQ 0U
/* SDEI flags */
@@ -80,20 +75,20 @@
*
* See also the is_map_bound() macro.
*/
-#define SDEI_MAPF_DYNAMIC BIT(_SDEI_MAPF_DYNAMIC_SHIFT)
-#define SDEI_MAPF_BOUND BIT(_SDEI_MAPF_BOUND_SHIFT)
-#define SDEI_MAPF_EXPLICIT BIT(_SDEI_MAPF_EXPLICIT_SHIFT)
+#define SDEI_MAPF_DYNAMIC BIT(SDEI_MAPF_DYNAMIC_SHIFT_)
+#define SDEI_MAPF_BOUND BIT(SDEI_MAPF_BOUND_SHIFT_)
+#define SDEI_MAPF_EXPLICIT BIT(SDEI_MAPF_EXPLICIT_SHIFT_)
-#define SDEI_MAPF_SIGNALABLE BIT(_SDEI_MAPF_SIGNALABLE_SHIFT)
-#define SDEI_MAPF_PRIVATE BIT(_SDEI_MAPF_PRIVATE_SHIFT)
+#define SDEI_MAPF_SIGNALABLE BIT(SDEI_MAPF_SIGNALABLE_SHIFT_)
+#define SDEI_MAPF_PRIVATE BIT(SDEI_MAPF_PRIVATE_SHIFT_)
#define SDEI_MAPF_NORMAL 0
-#define SDEI_MAPF_CRITICAL BIT(_SDEI_MAPF_CRITICAL_SHIFT)
+#define SDEI_MAPF_CRITICAL BIT(SDEI_MAPF_CRITICAL_SHIFT_)
/* Indices of private and shared mappings */
-#define _SDEI_MAP_IDX_PRIV 0
-#define _SDEI_MAP_IDX_SHRD 1
-#define _SDEI_MAP_IDX_MAX 2
+#define SDEI_MAP_IDX_PRIV_ 0U
+#define SDEI_MAP_IDX_SHRD_ 1U
+#define SDEI_MAP_IDX_MAX_ 2U
/* The macros below are used to identify SDEI calls from the SMC function ID */
#define SDEI_FID_MASK U(0xffe0)
@@ -104,22 +99,22 @@
#define SDEI_EVENT_MAP(_event, _intr, _flags) \
{ \
- .ev_num = _event, \
- .intr = _intr, \
- .map_flags = _flags \
+ .ev_num = (_event), \
+ .intr = (_intr), \
+ .map_flags = (_flags) \
}
#define SDEI_SHARED_EVENT(_event, _intr, _flags) \
SDEI_EVENT_MAP(_event, _intr, _flags)
#define SDEI_PRIVATE_EVENT(_event, _intr, _flags) \
- SDEI_EVENT_MAP(_event, _intr, _flags | SDEI_MAPF_PRIVATE)
+ SDEI_EVENT_MAP(_event, _intr, (_flags) | SDEI_MAPF_PRIVATE)
#define SDEI_DEFINE_EVENT_0(_intr) \
- SDEI_PRIVATE_EVENT(SDEI_EVENT_0, _intr, SDEI_MAPF_SIGNALABLE)
+ SDEI_PRIVATE_EVENT(SDEI_EVENT_0, (_intr), SDEI_MAPF_SIGNALABLE)
#define SDEI_EXPLICIT_EVENT(_event, _pri) \
- SDEI_EVENT_MAP(_event, 0, _pri | SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE)
+ SDEI_EVENT_MAP((_event), 0, (_pri) | SDEI_MAPF_EXPLICIT | SDEI_MAPF_PRIVATE)
/*
* Declare shared and private entries for each core. Also declare a global
@@ -133,12 +128,12 @@
[PLATFORM_CORE_COUNT * ARRAY_SIZE(_private)]; \
sdei_entry_t sdei_shared_event_table[ARRAY_SIZE(_shared)]; \
const sdei_mapping_t sdei_global_mappings[] = { \
- [_SDEI_MAP_IDX_PRIV] = { \
- .map = _private, \
+ [SDEI_MAP_IDX_PRIV_] = { \
+ .map = (_private), \
.num_maps = ARRAY_SIZE(_private) \
}, \
- [_SDEI_MAP_IDX_SHRD] = { \
- .map = _shared, \
+ [SDEI_MAP_IDX_SHRD_] = { \
+ .map = (_shared), \
.num_maps = ARRAY_SIZE(_shared) \
}, \
}
@@ -185,4 +180,4 @@ void sdei_init(void);
/* Public API to dispatch an event to Normal world */
int sdei_dispatch_event(int ev_num);
-#endif /* __SDEI_H__ */
+#endif /* SDEI_H */
diff --git a/include/services/secure_partition.h b/include/services/secure_partition.h
index d4aff1cc0..8b0adc80b 100644
--- a/include/services/secure_partition.h
+++ b/include/services/secure_partition.h
@@ -7,7 +7,7 @@
#ifndef __SECURE_PARTITION_H__
#define __SECURE_PARTITION_H__
-#include <types.h>
+#include <stdint.h>
#include <utils_def.h>
/*
diff --git a/lib/aarch32/armclang_printf.S b/lib/aarch32/armclang_printf.S
new file mode 100644
index 000000000..2b87bf7e0
--- /dev/null
+++ b/lib/aarch32/armclang_printf.S
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+/* Symbols needed by armclang */
+
+ .globl __0printf
+ .globl __1printf
+ .globl __2printf
+
+func __0printf
+__1printf:
+__2printf:
+ b printf
+endfunc __0printf
diff --git a/lib/aarch64/armclang_printf.S b/lib/aarch64/armclang_printf.S
new file mode 100644
index 000000000..2b87bf7e0
--- /dev/null
+++ b/lib/aarch64/armclang_printf.S
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+
+/* Symbols needed by armclang */
+
+ .globl __0printf
+ .globl __1printf
+ .globl __2printf
+
+func __0printf
+__1printf:
+__2printf:
+ b printf
+endfunc __0printf
diff --git a/lib/compiler-rt/builtins/int_lib.h b/lib/compiler-rt/builtins/int_lib.h
index 57dfc413c..787777a1b 100644
--- a/lib/compiler-rt/builtins/int_lib.h
+++ b/lib/compiler-rt/builtins/int_lib.h
@@ -14,7 +14,7 @@
*/
/*
- * Portions copyright (c) 2017, ARM Limited and Contributors.
+ * Portions copyright (c) 2017-2018, ARM Limited and Contributors.
* All rights reserved.
*/
@@ -63,9 +63,8 @@
* Kernel and boot environment can't use normal headers,
* so use the equivalent system headers.
*/
-# include <sys/limits.h>
-# include <sys/stdint.h>
-# include <sys/types.h>
+# include <limits.h>
+# include <stdint.h>
/* Include the commonly used internal type definitions. */
#include "int_types.h"
diff --git a/lib/cpus/aarch64/cortex_a55.S b/lib/cpus/aarch64/cortex_a55.S
index 741c77347..4e9bd9f6f 100644
--- a/lib/cpus/aarch64/cortex_a55.S
+++ b/lib/cpus/aarch64/cortex_a55.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,14 @@
#include <cpu_macros.S>
#include <plat_macros.S>
+func cortex_a55_reset_func
+ mov x19, x30
+#if ERRATA_DSU_936184
+ bl errata_dsu_936184_wa
+#endif
+ ret x19
+endfunc cortex_a55_reset_func
+
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
* ---------------------------------------------
@@ -27,6 +35,26 @@ func cortex_a55_core_pwr_dwn
ret
endfunc cortex_a55_core_pwr_dwn
+#if REPORT_ERRATA
+/*
+ * Errata printing function for Cortex A55. Must follow AAPCS & can use stack.
+ */
+func cortex_a55_errata_report
+ stp x8, x30, [sp, #-16]!
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision variant information is at x8, where
+ * "report_errata" is expecting it and it doesn't corrupt it.
+ */
+ report_errata ERRATA_DSU_936184, cortex_a55, dsu_936184
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc cortex_a55_errata_report
+#endif
+
/* ---------------------------------------------
* This function provides cortex_a55 specific
* register information for crash reporting.
@@ -47,5 +75,5 @@ func cortex_a55_cpu_reg_dump
endfunc cortex_a55_cpu_reg_dump
declare_cpu_ops cortex_a55, CORTEX_A55_MIDR, \
- CPU_NO_RESET_FUNC, \
+ cortex_a55_reset_func, \
cortex_a55_core_pwr_dwn
diff --git a/lib/cpus/aarch64/cortex_a75.S b/lib/cpus/aarch64/cortex_a75.S
index 73f566f4b..e121b7da8 100644
--- a/lib/cpus/aarch64/cortex_a75.S
+++ b/lib/cpus/aarch64/cortex_a75.S
@@ -11,6 +11,7 @@
#include <cpu_macros.S>
func cortex_a75_reset_func
+ mov x19, x30
#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
cpu_check_csv2 x0, 1f
adr x0, wa_cve_2017_5715_bpiall_vbar
@@ -26,6 +27,10 @@ func cortex_a75_reset_func
isb
#endif
+#if ERRATA_DSU_936184
+ bl errata_dsu_936184_wa
+#endif
+
#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
@@ -49,7 +54,7 @@ func cortex_a75_reset_func
msr CPUAMCNTENSET_EL0, x0
isb
#endif
- ret
+ ret x19
endfunc cortex_a75_reset_func
func check_errata_cve_2017_5715
@@ -106,6 +111,7 @@ func cortex_a75_errata_report
*/
report_errata WORKAROUND_CVE_2017_5715, cortex_a75, cve_2017_5715
report_errata WORKAROUND_CVE_2018_3639, cortex_a75, cve_2018_3639
+ report_errata ERRATA_DSU_936184, cortex_a75, dsu_936184
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S
index 51d0b15e3..1697c55dc 100644
--- a/lib/cpus/aarch64/cortex_a76.S
+++ b/lib/cpus/aarch64/cortex_a76.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -207,6 +207,7 @@ func cortex_a76_disable_wa_cve_2018_3639
endfunc cortex_a76_disable_wa_cve_2018_3639
func cortex_a76_reset_func
+ mov x19, x30
#if WORKAROUND_CVE_2018_3639
mrs x0, CORTEX_A76_CPUACTLR2_EL1
orr x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
@@ -224,7 +225,11 @@ func cortex_a76_reset_func
msr vbar_el3, x0
isb
#endif
- ret
+
+#if ERRATA_DSU_936184
+ bl errata_dsu_936184_wa
+#endif
+ ret x19
endfunc cortex_a76_reset_func
/* ---------------------------------------------
@@ -258,6 +263,7 @@ func cortex_a76_errata_report
* checking functions of each errata.
*/
report_errata WORKAROUND_CVE_2018_3639, cortex_a76, cve_2018_3639
+ report_errata ERRATA_DSU_936184, cortex_a76, dsu_936184
ldp x8, x30, [sp], #16
ret
diff --git a/lib/cpus/aarch64/denver.S b/lib/cpus/aarch64/denver.S
index f04dbd6c4..a981d02c7 100644
--- a/lib/cpus/aarch64/denver.S
+++ b/lib/cpus/aarch64/denver.S
@@ -189,6 +189,25 @@ func denver_disable_dco
ret
endfunc denver_disable_dco
+func check_errata_cve_2017_5715
+ mov x0, #ERRATA_MISSING
+#if WORKAROUND_CVE_2017_5715
+ /*
+ * Check if the CPU supports the special instruction
+ * required to flush the indirect branch predictor and
+ * RSB. Support for this operation can be determined by
+ * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001.
+ */
+ mrs x1, id_afr0_el1
+ mov x2, #0x10000
+ and x1, x1, x2
+ cbz x1, 1f
+ mov x0, #ERRATA_APPLIES
+1:
+#endif
+ ret
+endfunc check_errata_cve_2017_5715
+
/* -------------------------------------------------
* The CPU Ops reset function for Denver.
* -------------------------------------------------
@@ -248,6 +267,27 @@ func denver_cluster_pwr_dwn
ret
endfunc denver_cluster_pwr_dwn
+#if REPORT_ERRATA
+ /*
+ * Errata printing function for Denver. Must follow AAPCS.
+ */
+func denver_errata_report
+ stp x8, x30, [sp, #-16]!
+
+ bl cpu_get_rev_var
+ mov x8, x0
+
+ /*
+ * Report all errata. The revision-variant information is passed to
+ * checking functions of each errata.
+ */
+ report_errata WORKAROUND_CVE_2017_5715, denver, cve_2017_5715
+
+ ldp x8, x30, [sp], #16
+ ret
+endfunc denver_errata_report
+#endif
+
/* ---------------------------------------------
* This function provides Denver specific
* register information for crash reporting.
@@ -267,27 +307,37 @@ func denver_cpu_reg_dump
ret
endfunc denver_cpu_reg_dump
-declare_cpu_ops denver, DENVER_MIDR_PN0, \
+declare_cpu_ops_wa denver, DENVER_MIDR_PN0, \
denver_reset_func, \
+ check_errata_cve_2017_5715, \
+ CPU_NO_EXTRA2_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
-declare_cpu_ops denver, DENVER_MIDR_PN1, \
+declare_cpu_ops_wa denver, DENVER_MIDR_PN1, \
denver_reset_func, \
+ check_errata_cve_2017_5715, \
+ CPU_NO_EXTRA2_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
-declare_cpu_ops denver, DENVER_MIDR_PN2, \
+declare_cpu_ops_wa denver, DENVER_MIDR_PN2, \
denver_reset_func, \
+ check_errata_cve_2017_5715, \
+ CPU_NO_EXTRA2_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
-declare_cpu_ops denver, DENVER_MIDR_PN3, \
+declare_cpu_ops_wa denver, DENVER_MIDR_PN3, \
denver_reset_func, \
+ check_errata_cve_2017_5715, \
+ CPU_NO_EXTRA2_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
-declare_cpu_ops denver, DENVER_MIDR_PN4, \
+declare_cpu_ops_wa denver, DENVER_MIDR_PN4, \
denver_reset_func, \
+ check_errata_cve_2017_5715, \
+ CPU_NO_EXTRA2_FUNC, \
denver_core_pwr_dwn, \
denver_cluster_pwr_dwn
diff --git a/lib/cpus/aarch64/dsu_helpers.S b/lib/cpus/aarch64/dsu_helpers.S
new file mode 100644
index 000000000..152a3da26
--- /dev/null
+++ b/lib/cpus/aarch64/dsu_helpers.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <dsu_def.h>
+#include <errata_report.h>
+
+/* -----------------------------------------------------------------------
+ * DSU erratum 936184 check function
+ * Checks the DSU variant, revision and configuration to determine if
+ * the erratum applies. Erratum applies if ACP interface is present
+ * in the DSU and revision-variant < r2p0.
+ *
+ * The erratum was fixed in r2p0.
+ *
+ * This function is called from both assembly and C environment. So it
+ * follows AAPCS.
+ *
+ * Clobbers: x0-x3
+ * -----------------------------------------------------------------------
+ */
+ .globl check_errata_dsu_936184
+ .globl errata_dsu_936184_wa
+
+func check_errata_dsu_936184
+ mov x2, #ERRATA_NOT_APPLIES
+ mov x3, #ERRATA_APPLIES
+
+ /* Erratum applies only if DSU has the ACP interface */
+ mov x0, x2
+ mrs x1, CLUSTERCFR_EL1
+ ubfx x1, x1, #CLUSTERCFR_ACP_SHIFT, #1
+ cbz x1, 1f
+
+ /* If ACP is present, check if DSU is older than r2p0 */
+ mrs x1, CLUSTERIDR_EL1
+
+ /* DSU variant and revision bitfields in CLUSTERIDR are adjacent */
+ ubfx x0, x1, #CLUSTERIDR_REV_SHIFT,\
+ #(CLUSTERIDR_REV_BITS + CLUSTERIDR_VAR_BITS)
+ mov x1, #(0x2 << CLUSTERIDR_REV_BITS)
+ cmp x0, x1
+ csel x0, x2, x3, hs
+1:
+ ret
+endfunc check_errata_dsu_936184
+
+/* --------------------------------------------------
+ * Errata Workaround for DSU erratum #936184.
+ *
+ * Can clobber only: x0-x17
+ * --------------------------------------------------
+ */
+func errata_dsu_936184_wa
+ mov x17, x30
+ bl check_errata_dsu_936184
+ cbz x0, 1f
+
+ /* If erratum applies, we set a mask to a DSU control register */
+ mrs x0, CLUSTERACTLR_EL1
+ ldr x1, =DSU_ERRATA_936184_MASK
+ orr x0, x0, x1
+ msr CLUSTERACTLR_EL1, x0
+ isb
+1:
+ ret x17
+endfunc errata_dsu_936184_wa
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 456e3e524..40a8ac7ce 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -123,6 +123,11 @@ ERRATA_A72_859971 ?=0
# only to r0p0 and r1p0 of the Ares cpu.
ERRATA_ARES_1043202 ?=1
+# Flag to apply DSU erratum 936184. This erratum applies to DSUs containing
+# the ACP interface and revision < r2p0. Applying the workaround results in
+# higher DSU power consumption on idle.
+ERRATA_DSU_936184 ?=0
+
# Process ERRATA_A53_826319 flag
$(eval $(call assert_boolean,ERRATA_A53_826319))
$(eval $(call add_define,ERRATA_A53_826319))
@@ -187,6 +192,10 @@ $(eval $(call add_define,ERRATA_A72_859971))
$(eval $(call assert_boolean,ERRATA_ARES_1043202))
$(eval $(call add_define,ERRATA_ARES_1043202))
+# Process ERRATA_DSU_936184 flag
+$(eval $(call assert_boolean,ERRATA_DSU_936184))
+$(eval $(call add_define,ERRATA_DSU_936184))
+
# Errata build flags
ifneq (${ERRATA_A53_843419},0)
TF_LDFLAGS_aarch64 += --fix-cortex-a53-843419
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index f389368d4..ee5fe4f9d 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -12,6 +12,7 @@
#include <context.h>
#include <context_mgmt.h>
#include <interrupt_mgmt.h>
+#include <mpam.h>
#include <platform.h>
#include <platform_def.h>
#include <pubsub_events.h>
@@ -104,7 +105,7 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
if (EP_GET_ST(ep->h.attr))
scr_el3 |= SCR_ST_BIT;
-#ifndef HANDLE_EA_EL3_FIRST
+#if !HANDLE_EA_EL3_FIRST
/*
* SCR_EL3.EA: Do not route External Abort and SError Interrupt External
* to EL3 when executing at a lower EL. When executing at EL3, External
@@ -244,6 +245,10 @@ static void enable_extensions_nonsecure(int el2_unused)
#if ENABLE_SVE_FOR_NS
sve_enable(el2_unused);
#endif
+
+#if ENABLE_MPAM_FOR_LOWER_ELS
+ mpam_enable(el2_unused);
+#endif
#endif
}
diff --git a/lib/extensions/mpam/mpam.c b/lib/extensions/mpam/mpam.c
new file mode 100644
index 000000000..e628827bf
--- /dev/null
+++ b/lib/extensions/mpam/mpam.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <mpam.h>
+#include <stdbool.h>
+
+bool mpam_supported(void)
+{
+ uint64_t features = read_id_aa64dfr0_el1() >> ID_AA64PFR0_MPAM_SHIFT;
+
+ return ((features & ID_AA64PFR0_MPAM_MASK) != 0U);
+}
+
+void mpam_enable(int el2_unused)
+{
+ if (!mpam_supported())
+ return;
+
+ /*
+ * Enable MPAM, and disable trapping to EL3 when lower ELs access their
+ * own MPAM registers.
+ */
+ write_mpam3_el3(MPAM3_EL3_MPAMEN_BIT);
+
+ /*
+ * If EL2 is implemented but unused, disable trapping to EL2 when lower
+ * ELs access their own MPAM registers.
+ */
+ if (el2_unused != 0) {
+ write_mpam2_el2(0);
+
+ if ((read_mpamidr_el1() & MPAMIDR_HAS_HCR_BIT) != 0U)
+ write_mpamhcr_el2(0);
+ }
+}
diff --git a/lib/extensions/ras/ras_common.c b/lib/extensions/ras/ras_common.c
index 0335a7bcb..2e65eebb9 100644
--- a/lib/extensions/ras/ras_common.c
+++ b/lib/extensions/ras/ras_common.c
@@ -11,6 +11,7 @@
#include <platform.h>
#include <ras.h>
#include <ras_arch.h>
+#include <stdbool.h>
#ifndef PLAT_RAS_PRI
# error Platform must define RAS priority value
@@ -20,15 +21,15 @@
int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
void *handle, uint64_t flags)
{
- unsigned int i, n_handled = 0, ret;
- int probe_data;
+ unsigned int i, n_handled = 0;
+ int probe_data, ret;
struct err_record_info *info;
const struct err_handler_data err_data = {
.version = ERR_HANDLER_VERSION,
.ea_reason = ea_reason,
.interrupt = 0,
- .syndrome = syndrome,
+ .syndrome = (uint32_t) syndrome,
.flags = flags,
.cookie = cookie,
.handle = handle
@@ -39,7 +40,7 @@ int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
assert(info->handler != NULL);
/* Continue probing until the record group signals no error */
- while (1) {
+ while (true) {
if (info->probe(info, &probe_data) == 0)
break;
@@ -52,20 +53,20 @@ int ras_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie,
}
}
- return (n_handled != 0);
+ return (n_handled != 0U) ? 1 : 0;
}
#if ENABLE_ASSERTIONS
static void assert_interrupts_sorted(void)
{
unsigned int i, last;
- struct ras_interrupt *start = ras_interrupt_mapping.intrs;
+ struct ras_interrupt *start = ras_interrupt_mappings.intrs;
- if (ras_interrupt_mapping.num_intrs == 0)
+ if (ras_interrupt_mappings.num_intrs == 0UL)
return;
last = start[0].intr_number;
- for (i = 1; i < ras_interrupt_mapping.num_intrs; i++) {
+ for (i = 1; i < ras_interrupt_mappings.num_intrs; i++) {
assert(start[i].intr_number > last);
last = start[i].intr_number;
}
@@ -79,7 +80,7 @@ static void assert_interrupts_sorted(void)
static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags,
void *handle, void *cookie)
{
- struct ras_interrupt *ras_inrs = ras_interrupt_mapping.intrs;
+ struct ras_interrupt *ras_inrs = ras_interrupt_mappings.intrs;
struct ras_interrupt *selected = NULL;
int start, end, mid, probe_data, ret __unused;
@@ -91,10 +92,10 @@ static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags,
.handle = handle
};
- assert(ras_interrupt_mapping.num_intrs > 0);
+ assert(ras_interrupt_mappings.num_intrs > 0UL);
start = 0;
- end = ras_interrupt_mapping.num_intrs;
+ end = (int) ras_interrupt_mappings.num_intrs;
while (start <= end) {
mid = ((end + start) / 2);
if (intr_raw == ras_inrs[mid].intr_number) {
@@ -114,13 +115,14 @@ static int ras_interrupt_handler(uint32_t intr_raw, uint32_t flags,
panic();
}
-
- ret = selected->err_record->probe(selected->err_record, &probe_data);
- assert(ret != 0);
+ if (selected->err_record->probe != NULL) {
+ ret = selected->err_record->probe(selected->err_record, &probe_data);
+ assert(ret != 0);
+ }
/* Call error handler for the record group */
assert(selected->err_record->handler != NULL);
- selected->err_record->handler(selected->err_record, probe_data,
+ (void) selected->err_record->handler(selected->err_record, probe_data,
&err_data);
return 0;
diff --git a/lib/extensions/ras/std_err_record.c b/lib/extensions/ras/std_err_record.c
index 65c007f9e..209cb7310 100644
--- a/lib/extensions/ras/std_err_record.c
+++ b/lib/extensions/ras/std_err_record.c
@@ -13,28 +13,29 @@
*/
int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data)
{
- int num_records, num_group_regs, i;
+ unsigned int num_records, num_group_regs, i;
uint64_t gsr;
- assert(base != 0);
+ assert(base != 0UL);
/* Only 4K supported for now */
assert(size_num_k == STD_ERR_NODE_SIZE_NUM_K);
- num_records = (mmio_read_32(ERR_DEVID(base, size_num_k)) & ERR_DEVID_MASK);
+ num_records = (unsigned int)
+ (mmio_read_32(ERR_DEVID(base, size_num_k)) & ERR_DEVID_MASK);
/* A group register shows error status for 2^6 error records */
- num_group_regs = (num_records >> 6) + 1;
+ num_group_regs = (num_records >> 6U) + 1U;
/* Iterate through group registers to find a record in error */
for (i = 0; i < num_group_regs; i++) {
gsr = mmio_read_64(ERR_GSR(base, size_num_k, i));
- if (gsr == 0)
+ if (gsr == 0ULL)
continue;
/* Return the index of the record in error */
if (probe_data != NULL)
- *probe_data = ((i << 6) + __builtin_ctz(gsr));
+ *probe_data = (((int) (i << 6U)) + __builtin_ctzll(gsr));
return 1;
}
@@ -49,13 +50,14 @@ int ser_probe_memmap(uintptr_t base, unsigned int size_num_k, int *probe_data)
*/
int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_data)
{
- int i;
+ unsigned int i;
uint64_t status;
- unsigned int max_idx __unused = read_erridr_el1() & ERRIDR_MASK;
+ unsigned int max_idx __unused =
+ ((unsigned int) read_erridr_el1()) & ERRIDR_MASK;
assert(idx_start < max_idx);
- assert(check_u32_overflow(idx_start, num_idx) == 0);
- assert((idx_start + num_idx - 1) < max_idx);
+ assert(check_u32_overflow(idx_start, num_idx));
+ assert((idx_start + num_idx - 1U) < max_idx);
for (i = 0; i < num_idx; i++) {
/* Select the error record */
@@ -65,9 +67,9 @@ int ser_probe_sysreg(unsigned int idx_start, unsigned int num_idx, int *probe_da
status = read_erxstatus_el1();
/* Check for valid field in status */
- if (ERR_STATUS_GET_FIELD(status, V)) {
+ if (ERR_STATUS_GET_FIELD(status, V) != 0U) {
if (probe_data != NULL)
- *probe_data = i;
+ *probe_data = (int) i;
return 1;
}
}
diff --git a/lib/stdlib/abort.c b/lib/libc/abort.c
index 65ce4ccaf..c9d16cccc 100644
--- a/lib/stdlib/abort.c
+++ b/lib/libc/abort.c
@@ -7,10 +7,7 @@
#include <debug.h>
#include <stdlib.h>
-/*
- * This is a basic implementation. This could be improved.
- */
-void abort (void)
+void abort(void)
{
ERROR("ABORT\n");
panic();
diff --git a/lib/stdlib/assert.c b/lib/libc/assert.c
index 97fab4b0f..8fa8f7212 100644
--- a/lib/stdlib/assert.c
+++ b/lib/libc/assert.c
@@ -1,36 +1,42 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
+#include <cdefs.h>
#include <console.h>
#include <debug.h>
#include <platform.h>
+#include <stdio.h>
/*
-* Only print the output if PLAT_LOG_LEVEL_ASSERT is higher or equal to
-* LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
-*/
+ * Only print the output if PLAT_LOG_LEVEL_ASSERT is higher or equal to
+ * LOG_LEVEL_INFO, which is the default value for builds with DEBUG=1.
+ */
#if PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_VERBOSE
void __assert(const char *file, unsigned int line, const char *assertion)
{
- tf_printf("ASSERT: %s:%d:%s\n", file, line, assertion);
- console_flush();
+ printf("ASSERT: %s:%d:%s\n", file, line, assertion);
+ backtrace("assert");
+ (void)console_flush();
plat_panic_handler();
}
#elif PLAT_LOG_LEVEL_ASSERT >= LOG_LEVEL_INFO
void __assert(const char *file, unsigned int line)
{
- tf_printf("ASSERT: %s:%d\n", file, line);
- console_flush();
+ printf("ASSERT: %s:%d\n", file, line);
+ backtrace("assert");
+ (void)console_flush();
plat_panic_handler();
}
#else
void __assert(void)
{
+ backtrace("assert");
+ (void)console_flush();
plat_panic_handler();
}
#endif
diff --git a/lib/libc/exit.c b/lib/libc/exit.c
new file mode 100644
index 000000000..f4ffe27cf
--- /dev/null
+++ b/lib/libc/exit.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+static void (*exitfun)(void);
+
+void exit(int status)
+{
+ if (exitfun != NULL)
+ (*exitfun)();
+ for (;;)
+ ;
+}
+
+int atexit(void (*fun)(void))
+{
+ if (exitfun != NULL)
+ return -1;
+ exitfun = fun;
+
+ return 0;
+}
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
new file mode 100644
index 000000000..554f36bb7
--- /dev/null
+++ b/lib/libc/libc.mk
@@ -0,0 +1,27 @@
+#
+# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LIBC_SRCS := $(addprefix lib/libc/, \
+ abort.c \
+ assert.c \
+ exit.c \
+ memchr.c \
+ memcmp.c \
+ memcpy.c \
+ memmove.c \
+ memset.c \
+ printf.c \
+ putchar.c \
+ puts.c \
+ snprintf.c \
+ strchr.c \
+ strcmp.c \
+ strlen.c \
+ strncmp.c \
+ strnlen.c)
+
+INCLUDES += -Iinclude/lib/libc \
+ -Iinclude/lib/libc/$(ARCH) \
diff --git a/lib/libc/memchr.c b/lib/libc/memchr.c
new file mode 100644
index 000000000..2eba47c95
--- /dev/null
+++ b/lib/libc/memchr.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+void *memchr(const void *src, int c, size_t len)
+{
+ const char *s = src;
+
+ while (len--) {
+ if (*s == c)
+ return (void *) s;
+ s++;
+ }
+
+ return NULL;
+}
diff --git a/lib/libc/memcmp.c b/lib/libc/memcmp.c
new file mode 100644
index 000000000..a4c798b09
--- /dev/null
+++ b/lib/libc/memcmp.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+int memcmp(const void *s1, const void *s2, size_t len)
+{
+ const unsigned char *s = s1;
+ const unsigned char *d = s2;
+ unsigned char sc;
+ unsigned char dc;
+
+ while (len--) {
+ sc = *s++;
+ dc = *d++;
+ if (sc - dc)
+ return (sc - dc);
+ }
+
+ return 0;
+}
diff --git a/lib/libc/memcpy.c b/lib/libc/memcpy.c
new file mode 100644
index 000000000..fc0c9fe89
--- /dev/null
+++ b/lib/libc/memcpy.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+void *memcpy(void *dst, const void *src, size_t len)
+{
+ const char *s = src;
+ char *d = dst;
+
+ while (len--)
+ *d++ = *s++;
+
+ return dst;
+}
diff --git a/lib/libc/memmove.c b/lib/libc/memmove.c
new file mode 100644
index 000000000..63acf267f
--- /dev/null
+++ b/lib/libc/memmove.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t len)
+{
+ /*
+ * The following test makes use of unsigned arithmetic overflow to
+ * more efficiently test the condition !(src <= dst && dst < str+len).
+ * It also avoids the situation where the more explicit test would give
+ * incorrect results were the calculation str+len to overflow (though
+ * that issue is probably moot as such usage is probably undefined
+ * behaviour and a bug anyway.
+ */
+ if ((size_t)dst - (size_t)src >= len) {
+ /* destination not in source data, so can safely use memcpy */
+ return memcpy(dst, src, len);
+ } else {
+ /* copy backwards... */
+ const char *end = dst;
+ const char *s = (const char *)src + len;
+ char *d = (char *)dst + len;
+ while (d != end)
+ *--d = *--s;
+ }
+ return dst;
+}
diff --git a/lib/libc/memset.c b/lib/libc/memset.c
new file mode 100644
index 000000000..03aa80966
--- /dev/null
+++ b/lib/libc/memset.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+
+void *memset(void *dst, int val, size_t count)
+{
+ char *ptr = dst;
+
+ while (count--)
+ *ptr++ = val;
+
+ return dst;
+}
diff --git a/common/tf_printf.c b/lib/libc/printf.c
index 9d8333a6b..4480e94db 100644
--- a/common/tf_printf.c
+++ b/lib/libc/printf.c
@@ -1,59 +1,70 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <arch.h>
-#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
-#include <limits.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <stdint.h>
-/***********************************************************
- * The tf_printf implementation for all BL stages
- ***********************************************************/
+#define get_num_va_args(_args, _lcount) \
+ (((_lcount) > 1) ? va_arg(_args, long long int) : \
+ (((_lcount) == 1) ? va_arg(_args, long int) : \
+ va_arg(_args, int)))
-#define get_num_va_args(_args, _lcount) \
- (((_lcount) > 1) ? va_arg(_args, long long int) : \
- ((_lcount) ? va_arg(_args, long int) : va_arg(_args, int)))
+#define get_unum_va_args(_args, _lcount) \
+ (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \
+ (((_lcount) == 1) ? va_arg(_args, unsigned long int) : \
+ va_arg(_args, unsigned int)))
-#define get_unum_va_args(_args, _lcount) \
- (((_lcount) > 1) ? va_arg(_args, unsigned long long int) : \
- ((_lcount) ? va_arg(_args, unsigned long int) : va_arg(_args, unsigned int)))
-
-void tf_string_print(const char *str)
+static int string_print(const char *str)
{
- assert(str);
+ int count = 0;
+
+ assert(str != NULL);
+
+ for ( ; *str != '\0'; str++) {
+ (void)putchar(*str);
+ count++;
+ }
- while (*str)
- putchar(*str++);
+ return count;
}
-static void unsigned_num_print(unsigned long long int unum, unsigned int radix,
- char padc, int padn)
+static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
+ char padc, int padn)
{
/* Just need enough space to store 64 bit decimal integer */
- unsigned char num_buf[20];
- int i = 0, rem;
+ char num_buf[20];
+ int i = 0, count = 0;
+ unsigned int rem;
do {
rem = unum % radix;
if (rem < 0xa)
- num_buf[i++] = '0' + rem;
+ num_buf[i] = '0' + rem;
else
- num_buf[i++] = 'a' + (rem - 0xa);
- } while (unum /= radix);
+ num_buf[i] = 'a' + (rem - 0xa);
+ i++;
+ unum /= radix;
+ } while (unum > 0U);
if (padn > 0) {
- while (i < padn--) {
- putchar(padc);
+ while (i < padn) {
+ (void)putchar(padc);
+ count++;
+ padn--;
}
}
- while (--i >= 0)
- putchar(num_buf[i]);
+ while (--i >= 0) {
+ (void)putchar(num_buf[i]);
+ count++;
+ }
+
+ return count;
}
/*******************************************************************
@@ -76,16 +87,17 @@ static void unsigned_num_print(unsigned long long int unum, unsigned int radix,
* The print exits on all other formats specifiers other than valid
* combinations of the above specifiers.
*******************************************************************/
-void tf_vprintf(const char *fmt, va_list args)
+int vprintf(const char *fmt, va_list args)
{
int l_count;
long long int num;
unsigned long long int unum;
char *str;
- char padc = 0; /* Padding character */
+ char padc = '\0'; /* Padding character */
int padn; /* Number of characters to pad */
+ int count = 0; /* Number of printed characters */
- while (*fmt) {
+ while (*fmt != '\0') {
l_count = 0;
padn = 0;
@@ -98,33 +110,36 @@ loop:
case 'd':
num = get_num_va_args(args, l_count);
if (num < 0) {
- putchar('-');
+ (void)putchar('-');
unum = (unsigned long long int)-num;
padn--;
} else
unum = (unsigned long long int)num;
- unsigned_num_print(unum, 10, padc, padn);
+ count += unsigned_num_print(unum, 10,
+ padc, padn);
break;
case 's':
str = va_arg(args, char *);
- tf_string_print(str);
+ count += string_print(str);
break;
case 'p':
unum = (uintptr_t)va_arg(args, void *);
- if (unum) {
- tf_string_print("0x");
+ if (unum > 0U) {
+ count += string_print("0x");
padn -= 2;
}
- unsigned_num_print(unum, 16, padc, padn);
+ count += unsigned_num_print(unum, 16,
+ padc, padn);
break;
case 'x':
unum = get_unum_va_args(args, l_count);
- unsigned_num_print(unum, 16, padc, padn);
+ count += unsigned_num_print(unum, 16,
+ padc, padn);
break;
case 'z':
- if (sizeof(size_t) == 8)
+ if (sizeof(size_t) == 8U)
l_count = 2;
fmt++;
@@ -135,16 +150,17 @@ loop:
goto loop;
case 'u':
unum = get_unum_va_args(args, l_count);
- unsigned_num_print(unum, 10, padc, padn);
+ count += unsigned_num_print(unum, 10,
+ padc, padn);
break;
case '0':
padc = '0';
padn = 0;
fmt++;
- while (1) {
+ for (;;) {
char ch = *fmt;
- if (ch < '0' || ch > '9') {
+ if ((ch < '0') || (ch > '9')) {
goto loop;
}
padn = (padn * 10) + (ch - '0');
@@ -152,20 +168,27 @@ loop:
}
default:
/* Exit on any other format specifier */
- return;
+ return -1;
}
fmt++;
continue;
}
- putchar(*fmt++);
+ (void)putchar(*fmt);
+ fmt++;
+ count++;
}
+
+ return count;
}
-void tf_printf(const char *fmt, ...)
+int printf(const char *fmt, ...)
{
+ int count;
va_list va;
va_start(va, fmt);
- tf_vprintf(fmt, va);
+ count = vprintf(fmt, va);
va_end(va);
+
+ return count;
}
diff --git a/lib/libc/putchar.c b/lib/libc/putchar.c
new file mode 100644
index 000000000..0beb625b2
--- /dev/null
+++ b/lib/libc/putchar.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <console.h>
+
+int putchar(int c)
+{
+ int res;
+ if (console_putc((unsigned char)c) >= 0)
+ res = c;
+ else
+ res = EOF;
+
+ return res;
+}
diff --git a/lib/stdlib/puts.c b/lib/libc/puts.c
index 284cf8c52..2a0ca11c6 100644
--- a/lib/stdlib/puts.c
+++ b/lib/libc/puts.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,15 +9,14 @@
int puts(const char *s)
{
int count = 0;
- while(*s) {
- if (putchar(*s++) == EOF)
+
+ while (*s != '\0') {
+ if (putchar(*s) == EOF)
return EOF;
+ s++;
count++;
}
- /* According to the puts(3) manpage, the function should write a
- * trailing newline.
- */
if (putchar('\n') == EOF)
return EOF;
diff --git a/common/tf_snprintf.c b/lib/libc/snprintf.c
index a99ab7ab5..9bc07b2cb 100644
--- a/common/tf_snprintf.c
+++ b/lib/libc/snprintf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,21 +8,40 @@
#include <platform.h>
#include <stdarg.h>
+static void string_print(char **s, size_t n, size_t *chars_printed,
+ const char *str)
+{
+ while (*str != '\0') {
+ if (*chars_printed < n) {
+ *(*s) = *str;
+ (*s)++;
+ }
+
+ (*chars_printed)++;
+ str++;
+ }
+}
+
static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
unsigned int unum)
{
/* Enough for a 32-bit unsigned decimal integer (4294967295). */
- unsigned char num_buf[10];
- int i = 0, rem;
+ char num_buf[10];
+ int i = 0;
+ unsigned int rem;
do {
- rem = unum % 10;
+ rem = unum % 10U;
num_buf[i++] = '0' + rem;
- } while (unum /= 10);
+ unum /= 10U;
+ } while (unum > 0U);
while (--i >= 0) {
- if (*chars_printed < n)
- *(*s)++ = num_buf[i];
+ if (*chars_printed < n) {
+ *(*s) = num_buf[i];
+ (*s)++;
+ }
+
(*chars_printed)++;
}
}
@@ -32,6 +51,7 @@ static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
* The following type specifiers are supported:
*
* %d or %i - signed decimal format
+ * %s - string format
* %u - unsigned decimal format
*
* The function panics on all other formats specifiers.
@@ -40,24 +60,27 @@ static void unsigned_dec_print(char **s, size_t n, size_t *chars_printed,
* buffer was big enough. If it returns a value lower than n, the
* whole string has been written.
*******************************************************************/
-int tf_snprintf(char *s, size_t n, const char *fmt, ...)
+int snprintf(char *s, size_t n, const char *fmt, ...)
{
va_list args;
int num;
unsigned int unum;
- size_t chars_printed = 0;
+ char *str;
+ size_t chars_printed = 0U;
- if (n == 1) {
+ if (n == 0U) {
+ /* There isn't space for anything. */
+ } else if (n == 1U) {
/* Buffer is too small to actually write anything else. */
*s = '\0';
- n = 0;
- } else if (n >= 2) {
+ n = 0U;
+ } else {
/* Reserve space for the terminator character. */
n--;
}
va_start(args, fmt);
- while (*fmt) {
+ while (*fmt != '\0') {
if (*fmt == '%') {
fmt++;
@@ -68,8 +91,10 @@ int tf_snprintf(char *s, size_t n, const char *fmt, ...)
num = va_arg(args, int);
if (num < 0) {
- if (chars_printed < n)
- *s++ = '-';
+ if (chars_printed < n) {
+ *s = '-';
+ s++;
+ }
chars_printed++;
unum = (unsigned int)-num;
@@ -79,13 +104,17 @@ int tf_snprintf(char *s, size_t n, const char *fmt, ...)
unsigned_dec_print(&s, n, &chars_printed, unum);
break;
+ case 's':
+ str = va_arg(args, char *);
+ string_print(&s, n, &chars_printed, str);
+ break;
case 'u':
unum = va_arg(args, unsigned int);
unsigned_dec_print(&s, n, &chars_printed, unum);
break;
default:
/* Panic on any other format specifier. */
- ERROR("tf_snprintf: specifier with ASCII code '%d' not supported.",
+ ERROR("snprintf: specifier with ASCII code '%d' not supported.",
*fmt);
plat_panic_handler();
}
@@ -93,16 +122,19 @@ int tf_snprintf(char *s, size_t n, const char *fmt, ...)
continue;
}
- if (chars_printed < n)
- *s++ = *fmt;
+ if (chars_printed < n) {
+ *s = *fmt;
+ s++;
+ }
+
fmt++;
chars_printed++;
}
va_end(args);
- if (n > 0)
+ if (n > 0U)
*s = '\0';
- return chars_printed;
+ return (int)chars_printed;
}
diff --git a/lib/stdlib/strchr.c b/lib/libc/strchr.c
index 4247dcd36..d94bb9e0f 100644
--- a/lib/stdlib/strchr.c
+++ b/lib/libc/strchr.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -10,7 +12,7 @@
* 2. 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.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -28,11 +30,10 @@
*/
/*
- * Portions copyright (c) 2013-2014, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
* All rights reserved.
*/
-#include <sys/cdefs.h>
#include <stddef.h>
#include <string.h>
diff --git a/lib/stdlib/strcmp.c b/lib/libc/strcmp.c
index bb86e0f2c..b742f9b90 100644
--- a/lib/stdlib/strcmp.c
+++ b/lib/libc/strcmp.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -13,7 +15,7 @@
* 2. 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.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -31,12 +33,10 @@
*/
/*
- * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
* All rights reserved.
*/
-#include <sys/cdefs.h>
-#include <sys/ctype.h>
#include <string.h>
/*
@@ -47,20 +47,6 @@ strcmp(const char *s1, const char *s2)
{
while (*s1 == *s2++)
if (*s1++ == '\0')
- return 0;
- return *(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1);
-}
-
-int
-strcasecmp(const char *s1, const char *s2)
-{
- const unsigned char *us1 = (const unsigned char *)s1;
- const unsigned char *us2 = (const unsigned char *)s2;
-
- while (tolower(*us1) == tolower(*us2)) {
- if (*us1++ == '\0')
- return 0;
- us2++;
- }
- return tolower(*us1) - tolower(*us2);
+ return (0);
+ return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}
diff --git a/lib/libc/strlen.c b/lib/libc/strlen.c
new file mode 100644
index 000000000..3c2763006
--- /dev/null
+++ b/lib/libc/strlen.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+size_t strlen(const char *s)
+{
+ const char *cursor = s;
+
+ while (*cursor)
+ cursor++;
+
+ return cursor - s;
+}
diff --git a/lib/stdlib/strncmp.c b/lib/libc/strncmp.c
index f45f4a223..ce9e5ed4a 100644
--- a/lib/stdlib/strncmp.c
+++ b/lib/libc/strncmp.c
@@ -1,4 +1,6 @@
-/*
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -10,7 +12,7 @@
* 2. 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.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -28,11 +30,10 @@
*/
/*
- * Portions copyright (c) 2014, ARM Limited and Contributors.
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
* All rights reserved.
*/
-#include <sys/cdefs.h>
#include <string.h>
int
@@ -40,7 +41,7 @@ strncmp(const char *s1, const char *s2, size_t n)
{
if (n == 0)
- return 0;
+ return (0);
do {
if (*s1 != *s2++)
return (*(const unsigned char *)s1 -
@@ -48,5 +49,5 @@ strncmp(const char *s1, const char *s2, size_t n)
if (*s1++ == '\0')
break;
} while (--n != 0);
- return 0;
+ return (0);
}
diff --git a/lib/stdlib/strnlen.c b/lib/libc/strnlen.c
index d48502bdb..b944e95b4 100644
--- a/lib/stdlib/strnlen.c
+++ b/lib/libc/strnlen.c
@@ -1,4 +1,6 @@
/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
* All rights reserved.
*
@@ -25,11 +27,10 @@
*/
/*
- * Portions copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * All rights reserved.
*/
-#include <sys/cdefs.h>
-
#include <string.h>
size_t
diff --git a/lib/libfdt/libfdt.mk b/lib/libfdt/libfdt.mk
index d03dde204..1cbbd7852 100644
--- a/lib/libfdt/libfdt.mk
+++ b/lib/libfdt/libfdt.mk
@@ -15,3 +15,5 @@ LIBFDT_SRCS := $(addprefix lib/libfdt/, \
fdt_wip.c) \
INCLUDES += -Iinclude/lib/libfdt
+
+$(eval $(call MAKE_LIB,fdt))
diff --git a/lib/pmf/pmf_main.c b/lib/pmf/pmf_main.c
index 0208948fe..a02086008 100644
--- a/lib/pmf/pmf_main.c
+++ b/lib/pmf/pmf_main.c
@@ -178,7 +178,7 @@ int pmf_get_timestamp_smc(unsigned int tid,
*/
void __pmf_dump_timestamp(unsigned int tid, unsigned long long ts)
{
- tf_printf("PMF:cpu %u tid %u ts %llu\n",
+ printf("PMF:cpu %u tid %u ts %llu\n",
plat_my_core_pos(), tid, ts);
}
diff --git a/lib/psci/aarch32/psci_helpers.S b/lib/psci/aarch32/psci_helpers.S
index a29a29c49..63d7e7088 100644
--- a/lib/psci/aarch32/psci_helpers.S
+++ b/lib/psci/aarch32/psci_helpers.S
@@ -91,28 +91,6 @@ func psci_do_pwrup_cache_maintenance
stcopr r0, SCTLR
isb
-#if PLAT_XLAT_TABLES_DYNAMIC
- /* ---------------------------------------------
- * During warm boot the MMU is enabled with data
- * cache disabled, then the interconnect is set
- * up and finally the data cache is enabled.
- *
- * During this period, if another CPU modifies
- * the translation tables, the MMU table walker
- * may read the old entries. This is only a
- * problem for dynamic regions, the warm boot
- * code isn't affected because it is static.
- *
- * Invalidate all TLB entries loaded while the
- * CPU wasn't coherent with the rest of the
- * system.
- * ---------------------------------------------
- */
- stcopr r0, TLBIALL
- dsb ish
- isb
-#endif
-
pop {r12, pc}
endfunc psci_do_pwrup_cache_maintenance
diff --git a/lib/psci/aarch64/psci_helpers.S b/lib/psci/aarch64/psci_helpers.S
index d37ca764a..06d6636ed 100644
--- a/lib/psci/aarch64/psci_helpers.S
+++ b/lib/psci/aarch64/psci_helpers.S
@@ -115,28 +115,6 @@ func psci_do_pwrup_cache_maintenance
msr sctlr_el3, x0
isb
-#if PLAT_XLAT_TABLES_DYNAMIC
- /* ---------------------------------------------
- * During warm boot the MMU is enabled with data
- * cache disabled, then the interconnect is set
- * up and finally the data cache is enabled.
- *
- * During this period, if another CPU modifies
- * the translation tables, the MMU table walker
- * may read the old entries. This is only a
- * problem for dynamic regions, the warm boot
- * code isn't affected because it is static.
- *
- * Invalidate all TLB entries loaded while the
- * CPU wasn't coherent with the rest of the
- * system.
- * ---------------------------------------------
- */
- tlbi alle3
- dsb ish
- isb
-#endif
-
ldp x29, x30, [sp], #16
ret
endfunc psci_do_pwrup_cache_maintenance
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 2220a745c..ec74a8cdb 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -68,9 +68,9 @@ const plat_psci_ops_t *psci_plat_pm_ops;
/******************************************************************************
* Check that the maximum power level supported by the platform makes sense
*****************************************************************************/
-CASSERT(PLAT_MAX_PWR_LVL <= PSCI_MAX_PWR_LVL && \
- PLAT_MAX_PWR_LVL >= PSCI_CPU_PWR_LVL, \
- assert_platform_max_pwrlvl_check);
+CASSERT((PLAT_MAX_PWR_LVL <= PSCI_MAX_PWR_LVL) &&
+ (PLAT_MAX_PWR_LVL >= PSCI_CPU_PWR_LVL),
+ assert_platform_max_pwrlvl_check);
/*
* The plat_local_state used by the platform is one of these types: RUN,
@@ -93,17 +93,25 @@ typedef enum plat_local_state_type {
STATE_TYPE_OFF
} plat_local_state_type_t;
-/* The macro used to categorize plat_local_state. */
-#define find_local_state_type(plat_local_state) \
- ((plat_local_state) ? ((plat_local_state > PLAT_MAX_RET_STATE) \
- ? STATE_TYPE_OFF : STATE_TYPE_RETN) \
- : STATE_TYPE_RUN)
+/* Function used to categorize plat_local_state. */
+static plat_local_state_type_t find_local_state_type(plat_local_state_t state)
+{
+ if (state != 0U) {
+ if (state > PLAT_MAX_RET_STATE) {
+ return STATE_TYPE_OFF;
+ } else {
+ return STATE_TYPE_RETN;
+ }
+ } else {
+ return STATE_TYPE_RUN;
+ }
+}
/******************************************************************************
* Check that the maximum retention level supported by the platform is less
* than the maximum off level.
*****************************************************************************/
-CASSERT(PLAT_MAX_RET_STATE < PLAT_MAX_OFF_STATE, \
+CASSERT(PLAT_MAX_RET_STATE < PLAT_MAX_OFF_STATE,
assert_platform_max_off_and_retn_state_check);
/******************************************************************************
@@ -114,10 +122,10 @@ int psci_validate_power_state(unsigned int power_state,
psci_power_state_t *state_info)
{
/* Check SBZ bits in power state are zero */
- if (psci_check_power_state(power_state))
+ if (psci_check_power_state(power_state) != 0U)
return PSCI_E_INVALID_PARAMS;
- assert(psci_plat_pm_ops->validate_power_state);
+ assert(psci_plat_pm_ops->validate_power_state != NULL);
/* Validate the power_state using platform pm_ops */
return psci_plat_pm_ops->validate_power_state(power_state, state_info);
@@ -133,7 +141,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
* Assert that the required pm_ops hook is implemented to ensure that
* the capability detected during psci_setup() is valid.
*/
- assert(psci_plat_pm_ops->get_sys_suspend_power_state);
+ assert(psci_plat_pm_ops->get_sys_suspend_power_state != NULL);
/*
* Query the platform for the power_state required for system suspend
@@ -149,7 +157,7 @@ void psci_query_sys_suspend_pwrstate(psci_power_state_t *state_info)
******************************************************************************/
unsigned int psci_is_last_on_cpu(void)
{
- unsigned int cpu_idx, my_idx = plat_my_core_pos();
+ int cpu_idx, my_idx = (int) plat_my_core_pos();
for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
if (cpu_idx == my_idx) {
@@ -201,7 +209,7 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
assert(pwrlvl > PSCI_CPU_PWR_LVL);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
- psci_req_local_pwr_states[pwrlvl - 1][cpu_idx] = req_pwr_state;
+ psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
#pragma GCC diagnostic pop
}
@@ -211,8 +219,15 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
void psci_init_req_local_pwr_states(void)
{
/* Initialize the requested state of all non CPU power domains as OFF */
- memset(&psci_req_local_pwr_states, PLAT_MAX_OFF_STATE,
- sizeof(psci_req_local_pwr_states));
+ unsigned int pwrlvl;
+ int core;
+
+ for (pwrlvl = 0U; pwrlvl < PLAT_MAX_PWR_LVL; pwrlvl++) {
+ for (core = 0; core < PLATFORM_CORE_COUNT; core++) {
+ psci_req_local_pwr_states[pwrlvl][core] =
+ PLAT_MAX_OFF_STATE;
+ }
+ }
}
/******************************************************************************
@@ -224,11 +239,11 @@ void psci_init_req_local_pwr_states(void)
* assertion is added to prevent us from accessing the CPU power level.
*****************************************************************************/
static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
- unsigned int cpu_idx)
+ int cpu_idx)
{
assert(pwrlvl > PSCI_CPU_PWR_LVL);
- return &psci_req_local_pwr_states[pwrlvl - 1][cpu_idx];
+ return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
}
/*
@@ -252,7 +267,7 @@ static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
static plat_local_state_t get_non_cpu_pd_node_local_state(
unsigned int parent_idx)
{
-#if !USE_COHERENT_MEM || !HW_ASSISTED_COHERENCY
+#if !(USE_COHERENT_MEM || HW_ASSISTED_COHERENCY)
flush_dcache_range(
(uintptr_t) &psci_non_cpu_pd_nodes[parent_idx],
sizeof(psci_non_cpu_pd_nodes[parent_idx]));
@@ -268,7 +283,7 @@ static void set_non_cpu_pd_node_local_state(unsigned int parent_idx,
plat_local_state_t state)
{
psci_non_cpu_pd_nodes[parent_idx].local_state = state;
-#if !USE_COHERENT_MEM || !HW_ASSISTED_COHERENCY
+#if !(USE_COHERENT_MEM || HW_ASSISTED_COHERENCY)
flush_dcache_range(
(uintptr_t) &psci_non_cpu_pd_nodes[parent_idx],
sizeof(psci_non_cpu_pd_nodes[parent_idx]));
@@ -291,7 +306,7 @@ void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
/* Copy the local power state from node to state_info */
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
pd_state[lvl] = get_non_cpu_pd_node_local_state(parent_idx);
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
}
@@ -324,7 +339,7 @@ static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
parent_idx = psci_cpu_pd_nodes[plat_my_core_pos()].parent_node;
/* Copy the local_state from state_info */
- for (lvl = 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = 1U; lvl <= end_pwrlvl; lvl++) {
set_non_cpu_pd_node_local_state(parent_idx, pd_state[lvl]);
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
}
@@ -334,15 +349,17 @@ static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
/*******************************************************************************
* PSCI helper function to get the parent nodes corresponding to a cpu_index.
******************************************************************************/
-void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
+void psci_get_parent_pwr_domain_nodes(int cpu_idx,
unsigned int end_lvl,
- unsigned int node_index[])
+ unsigned int *node_index)
{
unsigned int parent_node = psci_cpu_pd_nodes[cpu_idx].parent_node;
unsigned int i;
+ unsigned int *node = node_index;
- for (i = PSCI_CPU_PWR_LVL + 1; i <= end_lvl; i++) {
- *node_index++ = parent_node;
+ for (i = PSCI_CPU_PWR_LVL + 1U; i <= end_lvl; i++) {
+ *node = parent_node;
+ node++;
parent_node = psci_non_cpu_pd_nodes[parent_node].parent_node;
}
}
@@ -358,7 +375,7 @@ void psci_set_pwr_domains_to_run(unsigned int end_pwrlvl)
parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
/* Reset the local_state to RUN for the non cpu power domains. */
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
set_non_cpu_pd_node_local_state(parent_idx,
PSCI_LOCAL_STATE_RUN);
psci_set_req_local_pwr_state(lvl,
@@ -398,7 +415,8 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
psci_power_state_t *state_info)
{
unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
- unsigned int start_idx, ncpus;
+ int start_idx;
+ unsigned int ncpus;
plat_local_state_t target_state, *req_states;
assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
@@ -406,7 +424,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
/* For level 0, the requested state will be equivalent
to target state */
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
/* First update the requested power state */
psci_set_req_local_pwr_state(lvl, cpu_idx,
@@ -428,7 +446,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
state_info->pwr_domain_state[lvl] = target_state;
/* Break early if the negotiated target power state is RUN */
- if (is_local_state_run(state_info->pwr_domain_state[lvl]))
+ if (is_local_state_run(state_info->pwr_domain_state[lvl]) != 0)
break;
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
@@ -440,7 +458,7 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
* We update the requested power state from state_info and then
* set the target state as RUN.
*/
- for (lvl = lvl + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = lvl + 1U; lvl <= end_pwrlvl; lvl++) {
psci_set_req_local_pwr_state(lvl, cpu_idx,
state_info->pwr_domain_state[lvl]);
state_info->pwr_domain_state[lvl] = PSCI_LOCAL_STATE_RUN;
@@ -478,7 +496,7 @@ int psci_validate_suspend_req(const psci_power_state_t *state_info,
/* All power domain levels are in a RUN state to begin with */
deepest_state_type = STATE_TYPE_RUN;
- for (i = target_lvl; i >= PSCI_CPU_PWR_LVL; i--) {
+ for (i = (int) target_lvl; i >= (int) PSCI_CPU_PWR_LVL; i--) {
state = state_info->pwr_domain_state[i];
req_state_type = find_local_state_type(state);
@@ -507,8 +525,9 @@ int psci_validate_suspend_req(const psci_power_state_t *state_info,
* has to be invalid and max retention level has to be a valid power
* level.
*/
- if (!is_power_down_state && (max_off_lvl != PSCI_INVALID_PWR_LVL ||
- max_retn_lvl == PSCI_INVALID_PWR_LVL))
+ if ((is_power_down_state == 0U) &&
+ ((max_off_lvl != PSCI_INVALID_PWR_LVL) ||
+ (max_retn_lvl == PSCI_INVALID_PWR_LVL)))
return PSCI_E_INVALID_PARAMS;
return PSCI_E_SUCCESS;
@@ -522,9 +541,9 @@ unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info)
{
int i;
- for (i = PLAT_MAX_PWR_LVL; i >= PSCI_CPU_PWR_LVL; i--) {
- if (is_local_state_off(state_info->pwr_domain_state[i]))
- return i;
+ for (i = (int) PLAT_MAX_PWR_LVL; i >= (int) PSCI_CPU_PWR_LVL; i--) {
+ if (is_local_state_off(state_info->pwr_domain_state[i]) != 0)
+ return (unsigned int) i;
}
return PSCI_INVALID_PWR_LVL;
@@ -538,9 +557,9 @@ unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info)
{
int i;
- for (i = PLAT_MAX_PWR_LVL; i >= PSCI_CPU_PWR_LVL; i--) {
- if (!is_local_state_run(state_info->pwr_domain_state[i]))
- return i;
+ for (i = (int) PLAT_MAX_PWR_LVL; i >= (int) PSCI_CPU_PWR_LVL; i--) {
+ if (is_local_state_run(state_info->pwr_domain_state[i]) == 0)
+ return (unsigned int) i;
}
return PSCI_INVALID_PWR_LVL;
@@ -551,14 +570,13 @@ unsigned int psci_find_target_suspend_lvl(const psci_power_state_t *state_info)
* tree that the operation should be applied to. It picks up locks in order of
* increasing power domain level in the range specified.
******************************************************************************/
-void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
- unsigned int cpu_idx)
+void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx)
{
unsigned int parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
unsigned int level;
/* No locking required for level 0. Hence start locking from level 1 */
- for (level = PSCI_CPU_PWR_LVL + 1; level <= end_pwrlvl; level++) {
+ for (level = PSCI_CPU_PWR_LVL + 1U; level <= end_pwrlvl; level++) {
psci_lock_get(&psci_non_cpu_pd_nodes[parent_idx]);
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
}
@@ -569,18 +587,17 @@ void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
* tree that the operation should be applied to. It releases the locks in order
* of decreasing power domain level in the range specified.
******************************************************************************/
-void psci_release_pwr_domain_locks(unsigned int end_pwrlvl,
- unsigned int cpu_idx)
+void psci_release_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx)
{
unsigned int parent_idx, parent_nodes[PLAT_MAX_PWR_LVL] = {0};
- int level;
+ unsigned int level;
/* Get the parent nodes */
psci_get_parent_pwr_domain_nodes(cpu_idx, end_pwrlvl, parent_nodes);
/* Unlock top down. No unlocking required for level 0. */
- for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1; level--) {
- parent_idx = parent_nodes[level - 1];
+ for (level = end_pwrlvl; level >= PSCI_CPU_PWR_LVL + 1U; level--) {
+ parent_idx = parent_nodes[level - 1U];
psci_lock_release(&psci_non_cpu_pd_nodes[parent_idx]);
}
}
@@ -656,11 +673,12 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep,
u_register_t ns_scr_el3 = read_scr_el3();
u_register_t ns_sctlr_el1 = read_sctlr_el1();
- sctlr = ns_scr_el3 & SCR_HCE_BIT ? read_sctlr_el2() : ns_sctlr_el1;
+ sctlr = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ?
+ read_sctlr_el2() : ns_sctlr_el1;
ee = 0;
ep_attr = NON_SECURE | EP_ST_DISABLE;
- if (sctlr & SCTLR_EE_BIT) {
+ if ((sctlr & SCTLR_EE_BIT) != 0U) {
ep_attr |= EP_EE_BIG;
ee = 1;
}
@@ -674,21 +692,22 @@ static int psci_get_ns_ep_info(entry_point_info_t *ep,
* Figure out whether the cpu enters the non-secure address space
* in aarch32 or aarch64
*/
- if (ns_scr_el3 & SCR_RW_BIT) {
+ if ((ns_scr_el3 & SCR_RW_BIT) != 0U) {
/*
* Check whether a Thumb entry point has been provided for an
* aarch64 EL
*/
- if (entrypoint & 0x1)
+ if ((entrypoint & 0x1UL) != 0UL)
return PSCI_E_INVALID_ADDRESS;
- mode = ns_scr_el3 & SCR_HCE_BIT ? MODE_EL2 : MODE_EL1;
+ mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ? MODE_EL2 : MODE_EL1;
ep->spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
} else {
- mode = ns_scr_el3 & SCR_HCE_BIT ? MODE32_hyp : MODE32_svc;
+ mode = ((ns_scr_el3 & SCR_HCE_BIT) != 0U) ?
+ MODE32_hyp : MODE32_svc;
/*
* TODO: Choose async. exception bits if HYP mode is not
@@ -715,7 +734,7 @@ int psci_validate_entry_point(entry_point_info_t *ep,
int rc;
/* Validate the entrypoint using platform psci_ops */
- if (psci_plat_pm_ops->validate_ns_entrypoint) {
+ if (psci_plat_pm_ops->validate_ns_entrypoint != NULL) {
rc = psci_plat_pm_ops->validate_ns_entrypoint(entrypoint);
if (rc != PSCI_E_SUCCESS)
return PSCI_E_INVALID_ADDRESS;
@@ -741,7 +760,8 @@ int psci_validate_entry_point(entry_point_info_t *ep,
******************************************************************************/
void psci_warmboot_entrypoint(void)
{
- unsigned int end_pwrlvl, cpu_idx = plat_my_core_pos();
+ unsigned int end_pwrlvl;
+ int cpu_idx = (int) plat_my_core_pos();
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
/*
@@ -764,8 +784,7 @@ void psci_warmboot_entrypoint(void)
* that by the time all locks are taken, the system topology is snapshot
* and state management can be done safely.
*/
- psci_acquire_pwr_domain_locks(end_pwrlvl,
- cpu_idx);
+ psci_acquire_pwr_domain_locks(end_pwrlvl, cpu_idx);
psci_get_target_local_pwr_states(end_pwrlvl, &state_info);
@@ -810,8 +829,7 @@ void psci_warmboot_entrypoint(void)
* This loop releases the lock corresponding to each power level
* in the reverse order to which they were acquired.
*/
- psci_release_pwr_domain_locks(end_pwrlvl,
- cpu_idx);
+ psci_release_pwr_domain_locks(end_pwrlvl, cpu_idx);
}
/*******************************************************************************
@@ -821,13 +839,13 @@ void psci_warmboot_entrypoint(void)
******************************************************************************/
void psci_register_spd_pm_hook(const spd_pm_ops_t *pm)
{
- assert(pm);
+ assert(pm != NULL);
psci_spd_pm = pm;
- if (pm->svc_migrate)
+ if (pm->svc_migrate != NULL)
psci_caps |= define_psci_cap(PSCI_MIG_AARCH64);
- if (pm->svc_migrate_info)
+ if (pm->svc_migrate_info != NULL)
psci_caps |= define_psci_cap(PSCI_MIG_INFO_UP_CPU_AARCH64)
| define_psci_cap(PSCI_MIG_INFO_TYPE);
}
@@ -843,13 +861,13 @@ int psci_spd_migrate_info(u_register_t *mpidr)
{
int rc;
- if (!psci_spd_pm || !psci_spd_pm->svc_migrate_info)
+ if ((psci_spd_pm == NULL) || (psci_spd_pm->svc_migrate_info == NULL))
return PSCI_E_NOT_SUPPORTED;
rc = psci_spd_pm->svc_migrate_info(mpidr);
- assert(rc == PSCI_TOS_UP_MIG_CAP || rc == PSCI_TOS_NOT_UP_MIG_CAP \
- || rc == PSCI_TOS_NOT_PRESENT_MP || rc == PSCI_E_NOT_SUPPORTED);
+ assert((rc == PSCI_TOS_UP_MIG_CAP) || (rc == PSCI_TOS_NOT_UP_MIG_CAP) ||
+ (rc == PSCI_TOS_NOT_PRESENT_MP) || (rc == PSCI_E_NOT_SUPPORTED));
return rc;
}
@@ -862,7 +880,7 @@ int psci_spd_migrate_info(u_register_t *mpidr)
void psci_print_power_domain_map(void)
{
#if LOG_LEVEL >= LOG_LEVEL_INFO
- unsigned int idx;
+ int idx;
plat_local_state_t state;
plat_local_state_type_t state_type;
@@ -908,16 +926,16 @@ void psci_print_power_domain_map(void)
*****************************************************************************/
int psci_secondaries_brought_up(void)
{
- unsigned int idx, n_valid = 0;
+ unsigned int idx, n_valid = 0U;
- for (idx = 0; idx < ARRAY_SIZE(psci_cpu_pd_nodes); idx++) {
+ for (idx = 0U; idx < ARRAY_SIZE(psci_cpu_pd_nodes); idx++) {
if (psci_cpu_pd_nodes[idx].mpidr != PSCI_INVALID_MPIDR)
n_valid++;
}
- assert(n_valid);
+ assert(n_valid > 0U);
- return (n_valid > 1);
+ return (n_valid > 1U) ? 1 : 0;
}
#if ENABLE_PLAT_COMPAT
@@ -964,8 +982,8 @@ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
return PSCI_INVALID_DATA;
/* Sanity check to verify that the CPU is in CPU_SUSPEND */
- if (psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_ON &&
- !is_local_state_run(psci_get_cpu_local_state_by_idx(cpu_idx)))
+ if ((psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_ON) &&
+ (!is_local_state_run(psci_get_cpu_local_state_by_idx(cpu_idx))))
return psci_get_pstate_id(psci_power_state_compat[cpu_idx]);
return PSCI_INVALID_DATA;
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 607d0cd50..fd822bcfd 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -83,7 +83,7 @@ int psci_cpu_suspend(unsigned int power_state,
/* Fast path for CPU standby.*/
if (is_cpu_standby_req(is_power_down_state, target_pwrlvl)) {
- if (!psci_plat_pm_ops->cpu_standby)
+ if (psci_plat_pm_ops->cpu_standby == NULL)
return PSCI_E_INVALID_PARAMS;
/*
@@ -128,7 +128,7 @@ int psci_cpu_suspend(unsigned int power_state,
* If a power down state has been requested, we need to verify entry
* point and program entry information.
*/
- if (is_power_down_state) {
+ if (is_power_down_state != 0U) {
rc = psci_validate_entry_point(&ep, entrypoint, context_id);
if (rc != PSCI_E_SUCCESS)
return rc;
@@ -156,7 +156,7 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
entry_point_info_t ep;
/* Check if the current CPU is the last ON CPU in the system */
- if (!psci_is_last_on_cpu())
+ if (psci_is_last_on_cpu() == 0U)
return PSCI_E_DENIED;
/* Validate the entry point and get the entry_point_info */
@@ -171,7 +171,8 @@ int psci_system_suspend(uintptr_t entrypoint, u_register_t context_id)
assert(psci_find_target_suspend_lvl(&state_info) == PLAT_MAX_PWR_LVL);
assert(psci_validate_suspend_req(&state_info, PSTATE_TYPE_POWERDOWN)
== PSCI_E_SUCCESS);
- assert(is_local_state_off(state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]));
+ assert(is_local_state_off(
+ state_info.pwr_domain_state[PLAT_MAX_PWR_LVL]) != 0);
/*
* Do what is needed to enter the system suspend state. This function
@@ -236,7 +237,8 @@ int psci_affinity_info(u_register_t target_affinity,
* target CPUs shutdown was not seen by the current CPU's cluster. And
* so the cache may contain stale data for the target CPU.
*/
- flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+ flush_cpu_data_by_index((unsigned int)target_idx,
+ psci_svc_cpu_data.aff_info_state);
return psci_get_aff_info_state_by_idx(target_idx);
}
@@ -263,10 +265,10 @@ int psci_migrate(u_register_t target_cpu)
if (rc != PSCI_E_SUCCESS)
return PSCI_E_INVALID_PARAMS;
- assert(psci_spd_pm && psci_spd_pm->svc_migrate);
+ assert((psci_spd_pm != NULL) && (psci_spd_pm->svc_migrate != NULL));
rc = psci_spd_pm->svc_migrate(read_mpidr_el1(), target_cpu);
- assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+ assert((rc == PSCI_E_SUCCESS) || (rc == PSCI_E_INTERN_FAIL));
return rc;
}
@@ -278,7 +280,7 @@ int psci_migrate_info_type(void)
return psci_spd_migrate_info(&resident_cpu_mpidr);
}
-long psci_migrate_info_up_cpu(void)
+u_register_t psci_migrate_info_up_cpu(void)
{
u_register_t resident_cpu_mpidr;
int rc;
@@ -288,8 +290,8 @@ long psci_migrate_info_up_cpu(void)
* psci_spd_migrate_info() returns.
*/
rc = psci_spd_migrate_info(&resident_cpu_mpidr);
- if (rc != PSCI_TOS_NOT_UP_MIG_CAP && rc != PSCI_TOS_UP_MIG_CAP)
- return PSCI_E_INVALID_PARAMS;
+ if ((rc != PSCI_TOS_NOT_UP_MIG_CAP) && (rc != PSCI_TOS_UP_MIG_CAP))
+ return (u_register_t)(register_t) PSCI_E_INVALID_PARAMS;
return resident_cpu_mpidr;
}
@@ -312,10 +314,11 @@ int psci_node_hw_state(u_register_t target_cpu,
* Dispatch this call to platform to query power controller, and pass on
* to the caller what it returns
*/
- assert(psci_plat_pm_ops->get_node_hw_state);
+ assert(psci_plat_pm_ops->get_node_hw_state != NULL);
rc = psci_plat_pm_ops->get_node_hw_state(target_cpu, power_level);
- assert((rc >= HW_ON && rc <= HW_STANDBY) || rc == PSCI_E_NOT_SUPPORTED
- || rc == PSCI_E_INVALID_PARAMS);
+ assert(((rc >= HW_ON) && (rc <= HW_STANDBY))
+ || (rc == PSCI_E_NOT_SUPPORTED)
+ || (rc == PSCI_E_INVALID_PARAMS));
return rc;
}
@@ -337,17 +340,19 @@ int psci_features(unsigned int psci_fid)
/* Check if the psci fid is supported or not */
- if (!(local_caps & define_psci_cap(psci_fid)))
+ if ((local_caps & define_psci_cap(psci_fid)) == 0U)
return PSCI_E_NOT_SUPPORTED;
/* Format the feature flags */
- if (psci_fid == PSCI_CPU_SUSPEND_AARCH32 ||
- psci_fid == PSCI_CPU_SUSPEND_AARCH64) {
+ if ((psci_fid == PSCI_CPU_SUSPEND_AARCH32) ||
+ (psci_fid == PSCI_CPU_SUSPEND_AARCH64)) {
/*
* The trusted firmware does not support OS Initiated Mode.
*/
- return (FF_PSTATE << FF_PSTATE_SHIFT) |
- ((!FF_SUPPORTS_OS_INIT_MODE) << FF_MODE_SUPPORT_SHIFT);
+ unsigned int ret = ((FF_PSTATE << FF_PSTATE_SHIFT) |
+ (((FF_SUPPORTS_OS_INIT_MODE == 1U) ? 0U : 1U)
+ << FF_MODE_SUPPORT_SHIFT));
+ return (int) ret;
}
/* Return 0 for all other fid's */
@@ -366,50 +371,62 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
+ u_register_t ret;
+
if (is_caller_secure(flags))
- return SMC_UNK;
+ return (u_register_t)SMC_UNK;
/* Check the fid against the capabilities */
- if (!(psci_caps & define_psci_cap(smc_fid)))
- return SMC_UNK;
+ if ((psci_caps & define_psci_cap(smc_fid)) == 0U)
+ return (u_register_t)SMC_UNK;
if (((smc_fid >> FUNCID_CC_SHIFT) & FUNCID_CC_MASK) == SMC_32) {
/* 32-bit PSCI function, clear top parameter bits */
- x1 = (uint32_t)x1;
- x2 = (uint32_t)x2;
- x3 = (uint32_t)x3;
+ uint32_t r1 = (uint32_t)x1;
+ uint32_t r2 = (uint32_t)x2;
+ uint32_t r3 = (uint32_t)x3;
switch (smc_fid) {
case PSCI_VERSION:
- return psci_version();
+ ret = (u_register_t)psci_version();
+ break;
case PSCI_CPU_OFF:
- return psci_cpu_off();
+ ret = (u_register_t)psci_cpu_off();
+ break;
case PSCI_CPU_SUSPEND_AARCH32:
- return psci_cpu_suspend(x1, x2, x3);
+ ret = (u_register_t)psci_cpu_suspend(r1, r2, r3);
+ break;
case PSCI_CPU_ON_AARCH32:
- return psci_cpu_on(x1, x2, x3);
+ ret = (u_register_t)psci_cpu_on(r1, r2, r3);
+ break;
case PSCI_AFFINITY_INFO_AARCH32:
- return psci_affinity_info(x1, x2);
+ ret = (u_register_t)psci_affinity_info(r1, r2);
+ break;
case PSCI_MIG_AARCH32:
- return psci_migrate(x1);
+ ret = (u_register_t)psci_migrate(r1);
+ break;
case PSCI_MIG_INFO_TYPE:
- return psci_migrate_info_type();
+ ret = (u_register_t)psci_migrate_info_type();
+ break;
case PSCI_MIG_INFO_UP_CPU_AARCH32:
- return psci_migrate_info_up_cpu();
+ ret = psci_migrate_info_up_cpu();
+ break;
case PSCI_NODE_HW_STATE_AARCH32:
- return psci_node_hw_state(x1, x2);
+ ret = (u_register_t)psci_node_hw_state(r1, r2);
+ break;
case PSCI_SYSTEM_SUSPEND_AARCH32:
- return psci_system_suspend(x1, x2);
+ ret = (u_register_t)psci_system_suspend(r1, r2);
+ break;
case PSCI_SYSTEM_OFF:
psci_system_off();
@@ -422,26 +439,34 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
break;
case PSCI_FEATURES:
- return psci_features(x1);
+ ret = (u_register_t)psci_features(r1);
+ break;
#if ENABLE_PSCI_STAT
case PSCI_STAT_RESIDENCY_AARCH32:
- return psci_stat_residency(x1, x2);
+ ret = psci_stat_residency(r1, r2);
+ break;
case PSCI_STAT_COUNT_AARCH32:
- return psci_stat_count(x1, x2);
+ ret = psci_stat_count(r1, r2);
+ break;
#endif
case PSCI_MEM_PROTECT:
- return psci_mem_protect(x1);
+ ret = psci_mem_protect(r1);
+ break;
case PSCI_MEM_CHK_RANGE_AARCH32:
- return psci_mem_chk_range(x1, x2);
+ ret = psci_mem_chk_range(r1, r2);
+ break;
case PSCI_SYSTEM_RESET2_AARCH32:
/* We should never return from psci_system_reset2() */
- return psci_system_reset2(x1, x2);
+ ret = psci_system_reset2(r1, r2);
+ break;
default:
+ WARN("Unimplemented PSCI Call: 0x%x\n", smc_fid);
+ ret = (u_register_t)SMC_UNK;
break;
}
} else {
@@ -449,46 +474,61 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
switch (smc_fid) {
case PSCI_CPU_SUSPEND_AARCH64:
- return psci_cpu_suspend(x1, x2, x3);
+ ret = (u_register_t)
+ psci_cpu_suspend((unsigned int)x1, x2, x3);
+ break;
case PSCI_CPU_ON_AARCH64:
- return psci_cpu_on(x1, x2, x3);
+ ret = (u_register_t)psci_cpu_on(x1, x2, x3);
+ break;
case PSCI_AFFINITY_INFO_AARCH64:
- return psci_affinity_info(x1, x2);
+ ret = (u_register_t)
+ psci_affinity_info(x1, (unsigned int)x2);
+ break;
case PSCI_MIG_AARCH64:
- return psci_migrate(x1);
+ ret = (u_register_t)psci_migrate(x1);
+ break;
case PSCI_MIG_INFO_UP_CPU_AARCH64:
- return psci_migrate_info_up_cpu();
+ ret = psci_migrate_info_up_cpu();
+ break;
case PSCI_NODE_HW_STATE_AARCH64:
- return psci_node_hw_state(x1, x2);
+ ret = (u_register_t)psci_node_hw_state(
+ x1, (unsigned int) x2);
+ break;
case PSCI_SYSTEM_SUSPEND_AARCH64:
- return psci_system_suspend(x1, x2);
+ ret = (u_register_t)psci_system_suspend(x1, x2);
+ break;
#if ENABLE_PSCI_STAT
case PSCI_STAT_RESIDENCY_AARCH64:
- return psci_stat_residency(x1, x2);
+ ret = psci_stat_residency(x1, (unsigned int) x2);
+ break;
case PSCI_STAT_COUNT_AARCH64:
- return psci_stat_count(x1, x2);
+ ret = psci_stat_count(x1, (unsigned int) x2);
+ break;
#endif
case PSCI_MEM_CHK_RANGE_AARCH64:
- return psci_mem_chk_range(x1, x2);
+ ret = psci_mem_chk_range(x1, x2);
+ break;
case PSCI_SYSTEM_RESET2_AARCH64:
/* We should never return from psci_system_reset2() */
- return psci_system_reset2(x1, x2);
+ ret = psci_system_reset2((uint32_t) x1, x2);
+ break;
default:
+ WARN("Unimplemented PSCI Call: 0x%x\n", smc_fid);
+ ret = (u_register_t)SMC_UNK;
break;
}
}
- WARN("Unimplemented PSCI Call: 0x%x \n", smc_fid);
- return SMC_UNK;
+ return ret;
}
diff --git a/lib/psci/psci_mem_protect.c b/lib/psci/psci_mem_protect.c
index fca84e905..857146b67 100644
--- a/lib/psci/psci_mem_protect.c
+++ b/lib/psci/psci_mem_protect.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,30 +9,31 @@
#include <utils.h>
#include "psci_private.h"
-int psci_mem_protect(unsigned int enable)
+u_register_t psci_mem_protect(unsigned int enable)
{
int val;
- assert(psci_plat_pm_ops->read_mem_protect);
- assert(psci_plat_pm_ops->write_mem_protect);
+ assert(psci_plat_pm_ops->read_mem_protect != NULL);
+ assert(psci_plat_pm_ops->write_mem_protect != NULL);
if (psci_plat_pm_ops->read_mem_protect(&val) < 0)
- return PSCI_E_NOT_SUPPORTED;
+ return (u_register_t) PSCI_E_NOT_SUPPORTED;
if (psci_plat_pm_ops->write_mem_protect(enable) < 0)
- return PSCI_E_NOT_SUPPORTED;
+ return (u_register_t) PSCI_E_NOT_SUPPORTED;
- return val != 0;
+ return (val != 0) ? 1U : 0U;
}
-int psci_mem_chk_range(uintptr_t base, u_register_t length)
+u_register_t psci_mem_chk_range(uintptr_t base, u_register_t length)
{
int ret;
- assert(psci_plat_pm_ops->mem_protect_chk);
+ assert(psci_plat_pm_ops->mem_protect_chk != NULL);
- if (length == 0 || check_uptr_overflow(base, length-1))
- return PSCI_E_DENIED;
+ if ((length == 0U) || check_uptr_overflow(base, length - 1U))
+ return (u_register_t) PSCI_E_DENIED;
ret = psci_plat_pm_ops->mem_protect_chk(base, length);
- return (ret < 0) ? PSCI_E_DENIED : PSCI_E_SUCCESS;
+ return (ret < 0) ?
+ (u_register_t) PSCI_E_DENIED : (u_register_t) PSCI_E_SUCCESS;
}
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index 231deea2d..944f8bff9 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -40,14 +40,15 @@ static void psci_set_power_off_state(psci_power_state_t *state_info)
******************************************************************************/
int psci_do_cpu_off(unsigned int end_pwrlvl)
{
- int rc = PSCI_E_SUCCESS, idx = plat_my_core_pos();
+ int rc = PSCI_E_SUCCESS;
+ int idx = (int) plat_my_core_pos();
psci_power_state_t state_info;
/*
* This function must only be called on platforms where the
* CPU_OFF platform hooks have been implemented.
*/
- assert(psci_plat_pm_ops->pwr_domain_off);
+ assert(psci_plat_pm_ops->pwr_domain_off != NULL);
/* Construct the psci_power_state for CPU_OFF */
psci_set_power_off_state(&state_info);
@@ -57,17 +58,16 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
* level so that by the time all locks are taken, the system topology
* is snapshot and state management can be done safely.
*/
- psci_acquire_pwr_domain_locks(end_pwrlvl,
- idx);
+ psci_acquire_pwr_domain_locks(end_pwrlvl, idx);
/*
* Call the cpu off handler registered by the Secure Payload Dispatcher
* to let it do any bookkeeping. Assume that the SPD always reports an
* E_DENIED error if SP refuse to power down
*/
- if (psci_spd_pm && psci_spd_pm->svc_off) {
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_off != NULL)) {
rc = psci_spd_pm->svc_off(0);
- if (rc)
+ if (rc != 0)
goto exit;
}
@@ -120,8 +120,7 @@ exit:
* Release the locks corresponding to each power level in the
* reverse order to which they were acquired.
*/
- psci_release_pwr_domain_locks(end_pwrlvl,
- idx);
+ psci_release_pwr_domain_locks(end_pwrlvl, idx);
/*
* Check if all actions needed to safely power down this cpu have
@@ -154,7 +153,7 @@ exit:
PMF_NO_CACHE_MAINT);
#endif
- if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi) {
+ if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi != NULL) {
/* This function must not return */
psci_plat_pm_ops->pwr_domain_pwr_down_wfi(&state_info);
} else {
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 53b044ecf..f38900cf5 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,6 +15,19 @@
#include <stddef.h>
#include "psci_private.h"
+/*
+ * Helper functions for the CPU level spinlocks
+ */
+static inline void psci_spin_lock_cpu(int idx)
+{
+ spin_lock(&psci_cpu_pd_nodes[idx].cpu_lock);
+}
+
+static inline void psci_spin_unlock_cpu(int idx)
+{
+ spin_unlock(&psci_cpu_pd_nodes[idx].cpu_lock);
+}
+
/*******************************************************************************
* This function checks whether a cpu which has been requested to be turned on
* is OFF to begin with.
@@ -42,22 +55,22 @@ static int cpu_on_validate_state(aff_info_state_t aff_state)
* platform handler as it can return error.
******************************************************************************/
int psci_cpu_on_start(u_register_t target_cpu,
- entry_point_info_t *ep)
+ const entry_point_info_t *ep)
{
int rc;
- unsigned int target_idx = plat_core_pos_by_mpidr(target_cpu);
aff_info_state_t target_aff_state;
+ int target_idx = plat_core_pos_by_mpidr(target_cpu);
/* Calling function must supply valid input arguments */
- assert((int) target_idx >= 0);
+ assert(target_idx >= 0);
assert(ep != NULL);
/*
* This function must only be called on platforms where the
* CPU_ON platform hooks have been implemented.
*/
- assert(psci_plat_pm_ops->pwr_domain_on &&
- psci_plat_pm_ops->pwr_domain_on_finish);
+ assert((psci_plat_pm_ops->pwr_domain_on != NULL) &&
+ (psci_plat_pm_ops->pwr_domain_on_finish != NULL));
/* Protect against multiple CPUs trying to turn ON the same target CPU */
psci_spin_lock_cpu(target_idx);
@@ -78,7 +91,8 @@ int psci_cpu_on_start(u_register_t target_cpu,
* target CPUs shutdown was not seen by the current CPU's cluster. And
* so the cache may contain stale data for the target CPU.
*/
- flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+ flush_cpu_data_by_index((unsigned int)target_idx,
+ psci_svc_cpu_data.aff_info_state);
rc = cpu_on_validate_state(psci_get_aff_info_state_by_idx(target_idx));
if (rc != PSCI_E_SUCCESS)
goto exit;
@@ -88,7 +102,7 @@ int psci_cpu_on_start(u_register_t target_cpu,
* to let it do any bookeeping. If the handler encounters an error, it's
* expected to assert within
*/
- if (psci_spd_pm && psci_spd_pm->svc_on)
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_on != NULL))
psci_spd_pm->svc_on(target_cpu);
/*
@@ -97,7 +111,8 @@ int psci_cpu_on_start(u_register_t target_cpu,
* turned OFF.
*/
psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
- flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+ flush_cpu_data_by_index((unsigned int)target_idx,
+ psci_svc_cpu_data.aff_info_state);
/*
* The cache line invalidation by the target CPU after setting the
@@ -109,9 +124,11 @@ int psci_cpu_on_start(u_register_t target_cpu,
if (target_aff_state != AFF_STATE_ON_PENDING) {
assert(target_aff_state == AFF_STATE_OFF);
psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_ON_PENDING);
- flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+ flush_cpu_data_by_index((unsigned int)target_idx,
+ psci_svc_cpu_data.aff_info_state);
- assert(psci_get_aff_info_state_by_idx(target_idx) == AFF_STATE_ON_PENDING);
+ assert(psci_get_aff_info_state_by_idx(target_idx) ==
+ AFF_STATE_ON_PENDING);
}
/*
@@ -123,15 +140,16 @@ int psci_cpu_on_start(u_register_t target_cpu,
* steps to power on.
*/
rc = psci_plat_pm_ops->pwr_domain_on(target_cpu);
- assert(rc == PSCI_E_SUCCESS || rc == PSCI_E_INTERN_FAIL);
+ assert((rc == PSCI_E_SUCCESS) || (rc == PSCI_E_INTERN_FAIL));
if (rc == PSCI_E_SUCCESS)
/* Store the re-entry information for the non-secure world. */
- cm_init_context_by_index(target_idx, ep);
+ cm_init_context_by_index((unsigned int)target_idx, ep);
else {
/* Restore the state on error. */
psci_set_aff_info_state_by_idx(target_idx, AFF_STATE_OFF);
- flush_cpu_data_by_index(target_idx, psci_svc_cpu_data.aff_info_state);
+ flush_cpu_data_by_index((unsigned int)target_idx,
+ psci_svc_cpu_data.aff_info_state);
}
exit:
@@ -144,8 +162,7 @@ exit:
* are called by the common finisher routine in psci_common.c. The `state_info`
* is the psci_power_state from which this CPU has woken up from.
******************************************************************************/
-void psci_cpu_on_finish(unsigned int cpu_idx,
- psci_power_state_t *state_info)
+void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info)
{
/*
* Plat. management: Perform the platform specific actions
@@ -186,7 +203,7 @@ void psci_cpu_on_finish(unsigned int cpu_idx,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (psci_spd_pm && psci_spd_pm->svc_on_finish)
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_on_finish != NULL))
psci_spd_pm->svc_on_finish(0);
PUBLISH_EVENT(psci_cpu_on_finish);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index d452e2ae0..82b951db6 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -4,69 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PSCI_PRIVATE_H__
-#define __PSCI_PRIVATE_H__
+#ifndef PSCI_PRIVATE_H
+#define PSCI_PRIVATE_H
#include <arch.h>
+#include <arch_helpers.h>
#include <bakery_lock.h>
#include <bl_common.h>
#include <cpu_data.h>
#include <psci.h>
#include <spinlock.h>
-
-#if HW_ASSISTED_COHERENCY
-
-/*
- * On systems with hardware-assisted coherency, make PSCI cache operations NOP,
- * as PSCI participants are cache-coherent, and there's no need for explicit
- * cache maintenance operations or barriers to coordinate their state.
- */
-#define psci_flush_dcache_range(addr, size)
-#define psci_flush_cpu_data(member)
-#define psci_inv_cpu_data(member)
-
-#define psci_dsbish()
-
-/*
- * On systems where participant CPUs are cache-coherent, we can use spinlocks
- * instead of bakery locks.
- */
-#define DEFINE_PSCI_LOCK(_name) spinlock_t _name
-#define DECLARE_PSCI_LOCK(_name) extern DEFINE_PSCI_LOCK(_name)
-
-#define psci_lock_get(non_cpu_pd_node) \
- spin_lock(&psci_locks[(non_cpu_pd_node)->lock_index])
-#define psci_lock_release(non_cpu_pd_node) \
- spin_unlock(&psci_locks[(non_cpu_pd_node)->lock_index])
-
-#else
-
-/*
- * If not all PSCI participants are cache-coherent, perform cache maintenance
- * and issue barriers wherever required to coordinate state.
- */
-#define psci_flush_dcache_range(addr, size) flush_dcache_range(addr, size)
-#define psci_flush_cpu_data(member) flush_cpu_data(member)
-#define psci_inv_cpu_data(member) inv_cpu_data(member)
-
-#define psci_dsbish() dsbish()
-
-/*
- * Use bakery locks for state coordination as not all PSCI participants are
- * cache coherent.
- */
-#define DEFINE_PSCI_LOCK(_name) DEFINE_BAKERY_LOCK(_name)
-#define DECLARE_PSCI_LOCK(_name) DECLARE_BAKERY_LOCK(_name)
-
-#define psci_lock_get(non_cpu_pd_node) \
- bakery_lock_get(&psci_locks[(non_cpu_pd_node)->lock_index])
-#define psci_lock_release(non_cpu_pd_node) \
- bakery_lock_release(&psci_locks[(non_cpu_pd_node)->lock_index])
-
-#endif
-
-#define psci_lock_init(_non_cpu_pd_node, _idx) \
- ((_non_cpu_pd_node)[(_idx)].lock_index = (_idx))
+#include <stdbool.h>
/*
* The PSCI capability which are provided by the generic code but does not
@@ -94,37 +42,63 @@
define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64))
/*
- * Helper macros to get/set the fields of PSCI per-cpu data.
- */
-#define psci_set_aff_info_state(_aff_state) \
- set_cpu_data(psci_svc_cpu_data.aff_info_state, _aff_state)
-#define psci_get_aff_info_state() \
- get_cpu_data(psci_svc_cpu_data.aff_info_state)
-#define psci_get_aff_info_state_by_idx(_idx) \
- get_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state)
-#define psci_set_aff_info_state_by_idx(_idx, _aff_state) \
- set_cpu_data_by_index(_idx, psci_svc_cpu_data.aff_info_state,\
- _aff_state)
-#define psci_get_suspend_pwrlvl() \
- get_cpu_data(psci_svc_cpu_data.target_pwrlvl)
-#define psci_set_suspend_pwrlvl(_target_lvl) \
- set_cpu_data(psci_svc_cpu_data.target_pwrlvl, _target_lvl)
-#define psci_set_cpu_local_state(_state) \
- set_cpu_data(psci_svc_cpu_data.local_state, _state)
-#define psci_get_cpu_local_state() \
- get_cpu_data(psci_svc_cpu_data.local_state)
-#define psci_get_cpu_local_state_by_idx(_idx) \
- get_cpu_data_by_index(_idx, psci_svc_cpu_data.local_state)
-
-/*
- * Helper macros for the CPU level spinlocks
+ * Helper functions to get/set the fields of PSCI per-cpu data.
*/
-#define psci_spin_lock_cpu(_idx) spin_lock(&psci_cpu_pd_nodes[_idx].cpu_lock)
-#define psci_spin_unlock_cpu(_idx) spin_unlock(&psci_cpu_pd_nodes[_idx].cpu_lock)
-
-/* Helper macro to identify a CPU standby request in PSCI Suspend call */
-#define is_cpu_standby_req(_is_power_down_state, _retn_lvl) \
- (((!(_is_power_down_state)) && ((_retn_lvl) == 0)) ? 1 : 0)
+static inline void psci_set_aff_info_state(aff_info_state_t aff_state)
+{
+ set_cpu_data(psci_svc_cpu_data.aff_info_state, aff_state);
+}
+
+static inline aff_info_state_t psci_get_aff_info_state(void)
+{
+ return get_cpu_data(psci_svc_cpu_data.aff_info_state);
+}
+
+static inline aff_info_state_t psci_get_aff_info_state_by_idx(int idx)
+{
+ return get_cpu_data_by_index((unsigned int)idx,
+ psci_svc_cpu_data.aff_info_state);
+}
+
+static inline void psci_set_aff_info_state_by_idx(int idx,
+ aff_info_state_t aff_state)
+{
+ set_cpu_data_by_index((unsigned int)idx,
+ psci_svc_cpu_data.aff_info_state, aff_state);
+}
+
+static inline unsigned int psci_get_suspend_pwrlvl(void)
+{
+ return get_cpu_data(psci_svc_cpu_data.target_pwrlvl);
+}
+
+static inline void psci_set_suspend_pwrlvl(unsigned int target_lvl)
+{
+ set_cpu_data(psci_svc_cpu_data.target_pwrlvl, target_lvl);
+}
+
+static inline void psci_set_cpu_local_state(plat_local_state_t state)
+{
+ set_cpu_data(psci_svc_cpu_data.local_state, state);
+}
+
+static inline plat_local_state_t psci_get_cpu_local_state(void)
+{
+ return get_cpu_data(psci_svc_cpu_data.local_state);
+}
+
+static inline plat_local_state_t psci_get_cpu_local_state_by_idx(int idx)
+{
+ return get_cpu_data_by_index((unsigned int)idx,
+ psci_svc_cpu_data.local_state);
+}
+
+/* Helper function to identify a CPU standby request in PSCI Suspend call */
+static inline bool is_cpu_standby_req(unsigned int is_power_down_state,
+ unsigned int retn_lvl)
+{
+ return (is_power_down_state == 0U) && (retn_lvl == 0U);
+}
/*******************************************************************************
* The following two data structures implement the power domain tree. The tree
@@ -138,7 +112,7 @@ typedef struct non_cpu_pwr_domain_node {
* Index of the first CPU power domain node level 0 which has this node
* as its parent.
*/
- unsigned int cpu_start_idx;
+ int cpu_start_idx;
/*
* Number of CPU power domains which are siblings of the domain indexed
@@ -180,6 +154,95 @@ typedef struct cpu_pwr_domain_node {
} cpu_pd_node_t;
/*******************************************************************************
+ * The following are helpers and declarations of locks.
+ ******************************************************************************/
+#if HW_ASSISTED_COHERENCY
+/*
+ * On systems where participant CPUs are cache-coherent, we can use spinlocks
+ * instead of bakery locks.
+ */
+#define DEFINE_PSCI_LOCK(_name) spinlock_t _name
+#define DECLARE_PSCI_LOCK(_name) extern DEFINE_PSCI_LOCK(_name)
+
+/* One lock is required per non-CPU power domain node */
+DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
+/*
+ * On systems with hardware-assisted coherency, make PSCI cache operations NOP,
+ * as PSCI participants are cache-coherent, and there's no need for explicit
+ * cache maintenance operations or barriers to coordinate their state.
+ */
+static inline void psci_flush_dcache_range(uintptr_t __unused addr,
+ size_t __unused size)
+{
+ /* Empty */
+}
+
+#define psci_flush_cpu_data(member)
+#define psci_inv_cpu_data(member)
+
+static inline void psci_dsbish(void)
+{
+ /* Empty */
+}
+
+static inline void psci_lock_get(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+ spin_lock(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+static inline void psci_lock_release(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+ spin_unlock(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+#else /* if HW_ASSISTED_COHERENCY == 0 */
+/*
+ * Use bakery locks for state coordination as not all PSCI participants are
+ * cache coherent.
+ */
+#define DEFINE_PSCI_LOCK(_name) DEFINE_BAKERY_LOCK(_name)
+#define DECLARE_PSCI_LOCK(_name) DECLARE_BAKERY_LOCK(_name)
+
+/* One lock is required per non-CPU power domain node */
+DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
+
+/*
+ * If not all PSCI participants are cache-coherent, perform cache maintenance
+ * and issue barriers wherever required to coordinate state.
+ */
+static inline void psci_flush_dcache_range(uintptr_t addr, size_t size)
+{
+ flush_dcache_range(addr, size);
+}
+
+#define psci_flush_cpu_data(member) flush_cpu_data(member)
+#define psci_inv_cpu_data(member) inv_cpu_data(member)
+
+static inline void psci_dsbish(void)
+{
+ dsbish();
+}
+
+static inline void psci_lock_get(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+ bakery_lock_get(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+static inline void psci_lock_release(non_cpu_pd_node_t *non_cpu_pd_node)
+{
+ bakery_lock_release(&psci_locks[non_cpu_pd_node->lock_index]);
+}
+
+#endif /* HW_ASSISTED_COHERENCY */
+
+static inline void psci_lock_init(non_cpu_pd_node_t *non_cpu_pd_node,
+ unsigned char idx)
+{
+ non_cpu_pd_node[idx].lock_index = idx;
+}
+
+/*******************************************************************************
* Data prototypes
******************************************************************************/
extern const plat_psci_ops_t *psci_plat_pm_ops;
@@ -187,9 +250,6 @@ extern non_cpu_pd_node_t psci_non_cpu_pd_nodes[PSCI_NUM_NON_CPU_PWR_DOMAINS];
extern cpu_pd_node_t psci_cpu_pd_nodes[PLATFORM_CORE_COUNT];
extern unsigned int psci_caps;
-/* One lock is required per non-CPU power domain node */
-DECLARE_PSCI_LOCK(psci_locks[PSCI_NUM_NON_CPU_PWR_DOMAINS]);
-
/*******************************************************************************
* SPD's power management hooks registered with PSCI
******************************************************************************/
@@ -208,15 +268,13 @@ void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
psci_power_state_t *target_state);
int psci_validate_entry_point(entry_point_info_t *ep,
uintptr_t entrypoint, u_register_t context_id);
-void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
+void psci_get_parent_pwr_domain_nodes(int cpu_idx,
unsigned int end_lvl,
- unsigned int node_index[]);
+ unsigned int *node_index);
void psci_do_state_coordination(unsigned int end_pwrlvl,
psci_power_state_t *state_info);
-void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl,
- unsigned int cpu_idx);
-void psci_release_pwr_domain_locks(unsigned int end_pwrlvl,
- unsigned int cpu_idx);
+void psci_acquire_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx);
+void psci_release_pwr_domain_locks(unsigned int end_pwrlvl, int cpu_idx);
int psci_validate_suspend_req(const psci_power_state_t *state_info,
unsigned int is_power_down_state);
unsigned int psci_find_max_off_lvl(const psci_power_state_t *state_info);
@@ -236,22 +294,20 @@ void prepare_cpu_pwr_dwn(unsigned int power_level);
/* Private exported functions from psci_on.c */
int psci_cpu_on_start(u_register_t target_cpu,
- entry_point_info_t *ep);
+ const entry_point_info_t *ep);
-void psci_cpu_on_finish(unsigned int cpu_idx,
- psci_power_state_t *state_info);
+void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info);
/* Private exported functions from psci_off.c */
int psci_do_cpu_off(unsigned int end_pwrlvl);
/* Private exported functions from psci_suspend.c */
-void psci_cpu_suspend_start(entry_point_info_t *ep,
+void psci_cpu_suspend_start(const entry_point_info_t *ep,
unsigned int end_pwrlvl,
psci_power_state_t *state_info,
unsigned int is_power_down_state);
-void psci_cpu_suspend_finish(unsigned int cpu_idx,
- psci_power_state_t *state_info);
+void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info);
/* Private exported functions from psci_helpers.S */
void psci_do_pwrdown_cache_maintenance(unsigned int pwr_level);
@@ -260,7 +316,7 @@ void psci_do_pwrup_cache_maintenance(void);
/* Private exported functions from psci_system_off.c */
void __dead2 psci_system_off(void);
void __dead2 psci_system_reset(void);
-int psci_system_reset2(uint32_t reset_type, u_register_t cookie);
+u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie);
/* Private exported functions from psci_stat.c */
void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
@@ -273,7 +329,7 @@ u_register_t psci_stat_count(u_register_t target_cpu,
unsigned int power_state);
/* Private exported functions from psci_mem_protect.c */
-int psci_mem_protect(unsigned int enable);
-int psci_mem_chk_range(uintptr_t base, u_register_t length);
+u_register_t psci_mem_protect(unsigned int enable);
+u_register_t psci_mem_chk_range(uintptr_t base, u_register_t length);
-#endif /* __PSCI_PRIVATE_H__ */
+#endif /* PSCI_PRIVATE_H */
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index c00bd94ac..e59e163ea 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,9 +32,9 @@ unsigned int psci_caps;
* Function which initializes the 'psci_non_cpu_pd_nodes' or the
* 'psci_cpu_pd_nodes' corresponding to the power level.
******************************************************************************/
-static void psci_init_pwr_domain_node(unsigned int node_idx,
+static void psci_init_pwr_domain_node(unsigned char node_idx,
unsigned int parent_idx,
- unsigned int level)
+ unsigned char level)
{
if (level > PSCI_CPU_PWR_LVL) {
psci_non_cpu_pd_nodes[node_idx].level = level;
@@ -82,15 +82,15 @@ static void psci_init_pwr_domain_node(unsigned int node_idx,
*******************************************************************************/
static void psci_update_pwrlvl_limits(void)
{
- int j;
+ int j, cpu_idx;
unsigned int nodes_idx[PLAT_MAX_PWR_LVL] = {0};
- unsigned int temp_index[PLAT_MAX_PWR_LVL], cpu_idx;
+ unsigned int temp_index[PLAT_MAX_PWR_LVL];
for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
psci_get_parent_pwr_domain_nodes(cpu_idx,
- PLAT_MAX_PWR_LVL,
+ (unsigned int)PLAT_MAX_PWR_LVL,
temp_index);
- for (j = PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
+ for (j = (int) PLAT_MAX_PWR_LVL - 1; j >= 0; j--) {
if (temp_index[j] != nodes_idx[j]) {
nodes_idx[j] = temp_index[j];
psci_non_cpu_pd_nodes[nodes_idx[j]].cpu_start_idx
@@ -109,9 +109,10 @@ static void psci_update_pwrlvl_limits(void)
******************************************************************************/
static void populate_power_domain_tree(const unsigned char *topology)
{
- unsigned int i, j = 0, num_nodes_at_lvl = 1, num_nodes_at_next_lvl;
- unsigned int node_index = 0, parent_node_index = 0, num_children;
- int level = PLAT_MAX_PWR_LVL;
+ unsigned int i, j = 0U, num_nodes_at_lvl = 1U, num_nodes_at_next_lvl;
+ unsigned int node_index = 0U, num_children;
+ int parent_node_index = 0;
+ int level = (int) PLAT_MAX_PWR_LVL;
/*
* For each level the inputs are:
@@ -122,8 +123,8 @@ static void populate_power_domain_tree(const unsigned char *topology)
* - Index of first free entry in psci_non_cpu_pd_nodes[] or
* psci_cpu_pd_nodes[] i.e. node_index depending upon the level.
*/
- while (level >= PSCI_CPU_PWR_LVL) {
- num_nodes_at_next_lvl = 0;
+ while (level >= (int) PSCI_CPU_PWR_LVL) {
+ num_nodes_at_next_lvl = 0U;
/*
* For each entry (parent node) at this level in the plat_array:
* - Find the number of children
@@ -132,16 +133,16 @@ static void populate_power_domain_tree(const unsigned char *topology)
* - Increment parent_node_index to point to the next parent
* - Accumulate the number of children at next level.
*/
- for (i = 0; i < num_nodes_at_lvl; i++) {
+ for (i = 0U; i < num_nodes_at_lvl; i++) {
assert(parent_node_index <=
PSCI_NUM_NON_CPU_PWR_DOMAINS);
num_children = topology[parent_node_index];
for (j = node_index;
- j < node_index + num_children; j++)
- psci_init_pwr_domain_node(j,
+ j < (node_index + num_children); j++)
+ psci_init_pwr_domain_node((unsigned char)j,
parent_node_index - 1,
- level);
+ (unsigned char)level);
node_index = j;
num_nodes_at_next_lvl += num_children;
@@ -152,12 +153,12 @@ static void populate_power_domain_tree(const unsigned char *topology)
level--;
/* Reset the index for the cpu power domain array */
- if (level == PSCI_CPU_PWR_LVL)
+ if (level == (int) PSCI_CPU_PWR_LVL)
node_index = 0;
}
/* Validate the sanity of array exported by the platform */
- assert(j == PLATFORM_CORE_COUNT);
+ assert((int) j == PLATFORM_CORE_COUNT);
}
/*******************************************************************************
@@ -213,8 +214,9 @@ int psci_setup(const psci_lib_args_t *lib_args)
*/
psci_set_pwr_domains_to_run(PLAT_MAX_PWR_LVL);
- plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep, &psci_plat_pm_ops);
- assert(psci_plat_pm_ops);
+ (void) plat_setup_psci_ops((uintptr_t)lib_args->mailbox_ep,
+ &psci_plat_pm_ops);
+ assert(psci_plat_pm_ops != NULL);
/*
* Flush `psci_plat_pm_ops` as it will be accessed by secondary CPUs
@@ -226,29 +228,29 @@ int psci_setup(const psci_lib_args_t *lib_args)
/* Initialize the psci capability */
psci_caps = PSCI_GENERIC_CAP;
- if (psci_plat_pm_ops->pwr_domain_off)
+ if (psci_plat_pm_ops->pwr_domain_off != NULL)
psci_caps |= define_psci_cap(PSCI_CPU_OFF);
- if (psci_plat_pm_ops->pwr_domain_on &&
- psci_plat_pm_ops->pwr_domain_on_finish)
+ if ((psci_plat_pm_ops->pwr_domain_on != NULL) &&
+ (psci_plat_pm_ops->pwr_domain_on_finish != NULL))
psci_caps |= define_psci_cap(PSCI_CPU_ON_AARCH64);
- if (psci_plat_pm_ops->pwr_domain_suspend &&
- psci_plat_pm_ops->pwr_domain_suspend_finish) {
+ if ((psci_plat_pm_ops->pwr_domain_suspend != NULL) &&
+ (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL)) {
psci_caps |= define_psci_cap(PSCI_CPU_SUSPEND_AARCH64);
- if (psci_plat_pm_ops->get_sys_suspend_power_state)
+ if (psci_plat_pm_ops->get_sys_suspend_power_state != NULL)
psci_caps |= define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64);
}
- if (psci_plat_pm_ops->system_off)
+ if (psci_plat_pm_ops->system_off != NULL)
psci_caps |= define_psci_cap(PSCI_SYSTEM_OFF);
- if (psci_plat_pm_ops->system_reset)
+ if (psci_plat_pm_ops->system_reset != NULL)
psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET);
- if (psci_plat_pm_ops->get_node_hw_state)
+ if (psci_plat_pm_ops->get_node_hw_state != NULL)
psci_caps |= define_psci_cap(PSCI_NODE_HW_STATE_AARCH64);
- if (psci_plat_pm_ops->read_mem_protect &&
- psci_plat_pm_ops->write_mem_protect)
+ if ((psci_plat_pm_ops->read_mem_protect != NULL) &&
+ (psci_plat_pm_ops->write_mem_protect != NULL))
psci_caps |= define_psci_cap(PSCI_MEM_PROTECT);
- if (psci_plat_pm_ops->mem_protect_chk)
+ if (psci_plat_pm_ops->mem_protect_chk != NULL)
psci_caps |= define_psci_cap(PSCI_MEM_CHK_RANGE_AARCH64);
- if (psci_plat_pm_ops->system_reset2)
+ if (psci_plat_pm_ops->system_reset2 != NULL)
psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET2_AARCH64);
#if ENABLE_PSCI_STAT
@@ -266,7 +268,7 @@ int psci_setup(const psci_lib_args_t *lib_args)
******************************************************************************/
void psci_arch_setup(void)
{
-#if ARM_ARCH_MAJOR > 7 || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
+#if (ARM_ARCH_MAJOR > 7) || defined(ARMV7_SUPPORTS_GENERIC_TIMER)
/* Program the counter frequency */
write_cntfrq_el0(plat_get_syscnt_freq2());
#endif
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index e925d34ed..421db4430 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
#include "psci_private.h"
#ifndef PLAT_MAX_PWR_LVL_STATES
-#define PLAT_MAX_PWR_LVL_STATES 2
+#define PLAT_MAX_PWR_LVL_STATES 2U
#endif
/* Following structure is used for PSCI STAT */
@@ -25,7 +25,7 @@ typedef struct psci_stat {
* that goes to power down in non cpu power domains.
*/
static int last_cpu_in_non_cpu_pd[PSCI_NUM_NON_CPU_PWR_DOMAINS] = {
- [0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS-1] = -1};
+ [0 ... PSCI_NUM_NON_CPU_PWR_DOMAINS - 1] = -1};
/*
* Following are used to store PSCI STAT values for
@@ -41,21 +41,21 @@ static psci_stat_t psci_non_cpu_stat[PSCI_NUM_NON_CPU_PWR_DOMAINS]
* local power state and power domain level. If the platform implements the
* `get_pwr_lvl_state_idx` pm hook, then that will be used to return the index.
*/
-static int get_stat_idx(plat_local_state_t local_state, int pwr_lvl)
+static int get_stat_idx(plat_local_state_t local_state, unsigned int pwr_lvl)
{
int idx;
if (psci_plat_pm_ops->get_pwr_lvl_state_idx == NULL) {
- assert(PLAT_MAX_PWR_LVL_STATES == 2);
- if (is_local_state_retn(local_state))
+ assert(PLAT_MAX_PWR_LVL_STATES == 2U);
+ if (is_local_state_retn(local_state) != 0)
return 0;
- assert(is_local_state_off(local_state));
+ assert(is_local_state_off(local_state) != 0);
return 1;
}
idx = psci_plat_pm_ops->get_pwr_lvl_state_idx(local_state, pwr_lvl);
- assert((idx >= 0) && (idx < PLAT_MAX_PWR_LVL_STATES));
+ assert((idx >= 0) && (idx < (int) PLAT_MAX_PWR_LVL_STATES));
return idx;
}
@@ -73,17 +73,18 @@ static int get_stat_idx(plat_local_state_t local_state, int pwr_lvl)
void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
- unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+ unsigned int lvl, parent_idx;
+ int cpu_idx = (int) plat_my_core_pos();
assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
- assert(state_info);
+ assert(state_info != NULL);
parent_idx = psci_cpu_pd_nodes[cpu_idx].parent_node;
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
/* Break early if the target power state is RUN */
- if (is_local_state_run(state_info->pwr_domain_state[lvl]))
+ if (is_local_state_run(state_info->pwr_domain_state[lvl]) != 0)
break;
/*
@@ -105,13 +106,14 @@ void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
- unsigned int lvl, parent_idx, cpu_idx = plat_my_core_pos();
+ unsigned int lvl, parent_idx;
+ int cpu_idx = (int) plat_my_core_pos();
int stat_idx;
plat_local_state_t local_state;
u_register_t residency;
assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
- assert(state_info);
+ assert(state_info != NULL);
/* Get the index into the stats array */
local_state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
@@ -134,9 +136,9 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
if (last_cpu_in_non_cpu_pd[parent_idx] == -1)
return;
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl <= end_pwrlvl; lvl++) {
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl <= end_pwrlvl; lvl++) {
local_state = state_info->pwr_domain_state[lvl];
- if (is_local_state_run(local_state)) {
+ if (is_local_state_run(local_state) != 0) {
/* Break early */
break;
}
@@ -145,7 +147,7 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
/* Call into platform interface to calculate residency. */
residency = plat_psci_stat_get_residency(lvl, state_info,
- last_cpu_in_non_cpu_pd[parent_idx]);
+ last_cpu_in_non_cpu_pd[parent_idx]);
/* Initialize back to reset value */
last_cpu_in_non_cpu_pd[parent_idx] = -1;
@@ -171,17 +173,18 @@ static int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
psci_stat_t *psci_stat)
{
int rc;
- unsigned int pwrlvl, lvl, parent_idx, stat_idx, target_idx;
+ unsigned int pwrlvl, lvl, parent_idx, target_idx;
+ int stat_idx;
psci_power_state_t state_info = { {PSCI_LOCAL_STATE_RUN} };
plat_local_state_t local_state;
/* Validate the target_cpu parameter and determine the cpu index */
- target_idx = plat_core_pos_by_mpidr(target_cpu);
- if (target_idx == -1)
+ target_idx = (unsigned int) plat_core_pos_by_mpidr(target_cpu);
+ if (target_idx == (unsigned int) -1)
return PSCI_E_INVALID_PARAMS;
/* Validate the power_state parameter */
- if (!psci_plat_pm_ops->translate_power_state_by_mpidr)
+ if (psci_plat_pm_ops->translate_power_state_by_mpidr == NULL)
rc = psci_validate_power_state(power_state, &state_info);
else
rc = psci_plat_pm_ops->translate_power_state_by_mpidr(
@@ -204,7 +207,7 @@ static int psci_get_stat(u_register_t target_cpu, unsigned int power_state,
if (pwrlvl > PSCI_CPU_PWR_LVL) {
/* Get the power domain index */
parent_idx = psci_cpu_pd_nodes[target_idx].parent_node;
- for (lvl = PSCI_CPU_PWR_LVL + 1; lvl < pwrlvl; lvl++)
+ for (lvl = PSCI_CPU_PWR_LVL + 1U; lvl < pwrlvl; lvl++)
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
/* Get the non cpu power domain stats */
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index a77972d38..e00819de7 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,7 +23,7 @@
* This function does generic and platform specific operations after a wake-up
* from standby/retention states at multiple power levels.
******************************************************************************/
-static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
+static void psci_suspend_to_standby_finisher(int cpu_idx,
unsigned int end_pwrlvl)
{
psci_power_state_t state_info;
@@ -64,8 +64,8 @@ static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
* operations.
******************************************************************************/
static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
- entry_point_info_t *ep,
- psci_power_state_t *state_info)
+ const entry_point_info_t *ep,
+ const psci_power_state_t *state_info)
{
unsigned int max_off_lvl = psci_find_max_off_lvl(state_info);
@@ -85,7 +85,7 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* Dispatcher to let it do any book-keeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (psci_spd_pm && psci_spd_pm->svc_suspend)
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_suspend != NULL))
psci_spd_pm->svc_suspend(max_off_lvl);
#if !HW_ASSISTED_COHERENCY
@@ -95,7 +95,7 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* HW_ASSISTED_COHERENCY = 0 platforms that can safely perform these
* actions with data caches enabled.
*/
- if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early)
+ if (psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early != NULL)
psci_plat_pm_ops->pwr_domain_suspend_pwrdown_early(state_info);
#endif
@@ -147,20 +147,20 @@ static void psci_suspend_to_pwrdown_start(unsigned int end_pwrlvl,
* the state transition has been done, no further error is expected and it is
* not possible to undo any of the actions taken beyond that point.
******************************************************************************/
-void psci_cpu_suspend_start(entry_point_info_t *ep,
+void psci_cpu_suspend_start(const entry_point_info_t *ep,
unsigned int end_pwrlvl,
psci_power_state_t *state_info,
unsigned int is_power_down_state)
{
int skip_wfi = 0;
- unsigned int idx = plat_my_core_pos();
+ int idx = (int) plat_my_core_pos();
/*
* This function must only be called on platforms where the
* CPU_SUSPEND platform hooks have been implemented.
*/
- assert(psci_plat_pm_ops->pwr_domain_suspend &&
- psci_plat_pm_ops->pwr_domain_suspend_finish);
+ assert((psci_plat_pm_ops->pwr_domain_suspend != NULL) &&
+ (psci_plat_pm_ops->pwr_domain_suspend_finish != NULL));
/*
* This function acquires the lock corresponding to each power
@@ -175,7 +175,7 @@ void psci_cpu_suspend_start(entry_point_info_t *ep,
* introduced by lock contention to increase the chances of early
* detection that a wake-up interrupt has fired.
*/
- if (read_isr_el1()) {
+ if (read_isr_el1() != 0U) {
skip_wfi = 1;
goto exit;
}
@@ -192,7 +192,7 @@ void psci_cpu_suspend_start(entry_point_info_t *ep,
psci_stats_update_pwr_down(end_pwrlvl, state_info);
#endif
- if (is_power_down_state)
+ if (is_power_down_state != 0U)
psci_suspend_to_pwrdown_start(end_pwrlvl, ep, state_info);
/*
@@ -214,10 +214,10 @@ exit:
*/
psci_release_pwr_domain_locks(end_pwrlvl,
idx);
- if (skip_wfi)
+ if (skip_wfi == 1)
return;
- if (is_power_down_state) {
+ if (is_power_down_state != 0U) {
#if ENABLE_RUNTIME_INSTRUMENTATION
/*
@@ -232,7 +232,7 @@ exit:
#endif
/* The function calls below must not return */
- if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi)
+ if (psci_plat_pm_ops->pwr_domain_pwr_down_wfi != NULL)
psci_plat_pm_ops->pwr_domain_pwr_down_wfi(state_info);
else
psci_power_down_wfi();
@@ -269,15 +269,15 @@ exit:
* are called by the common finisher routine in psci_common.c. The `state_info`
* is the psci_power_state from which this CPU has woken up from.
******************************************************************************/
-void psci_cpu_suspend_finish(unsigned int cpu_idx,
- psci_power_state_t *state_info)
+void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info)
{
unsigned int counter_freq;
unsigned int max_off_lvl;
/* Ensure we have been woken up from a suspended state */
- assert(psci_get_aff_info_state() == AFF_STATE_ON && is_local_state_off(\
- state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]));
+ assert((psci_get_aff_info_state() == AFF_STATE_ON) &&
+ (is_local_state_off(
+ state_info->pwr_domain_state[PSCI_CPU_PWR_LVL]) != 0));
/*
* Plat. management: Perform the platform specific actions
@@ -302,9 +302,9 @@ void psci_cpu_suspend_finish(unsigned int cpu_idx,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (psci_spd_pm && psci_spd_pm->svc_suspend_finish) {
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_suspend_finish != NULL)) {
max_off_lvl = psci_find_max_off_lvl(state_info);
- assert (max_off_lvl != PSCI_INVALID_PWR_LVL);
+ assert(max_off_lvl != PSCI_INVALID_PWR_LVL);
psci_spd_pm->svc_suspend_finish(max_off_lvl);
}
diff --git a/lib/psci/psci_system_off.c b/lib/psci/psci_system_off.c
index 13e9f4aae..7cac4e937 100644
--- a/lib/psci/psci_system_off.c
+++ b/lib/psci/psci_system_off.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,14 +16,14 @@ void __dead2 psci_system_off(void)
{
psci_print_power_domain_map();
- assert(psci_plat_pm_ops->system_off);
+ assert(psci_plat_pm_ops->system_off != NULL);
/* Notify the Secure Payload Dispatcher */
- if (psci_spd_pm && psci_spd_pm->svc_system_off) {
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_off != NULL)) {
psci_spd_pm->svc_system_off();
}
- console_flush();
+ (void) console_flush();
/* Call the platform specific hook */
psci_plat_pm_ops->system_off();
@@ -35,14 +35,14 @@ void __dead2 psci_system_reset(void)
{
psci_print_power_domain_map();
- assert(psci_plat_pm_ops->system_reset);
+ assert(psci_plat_pm_ops->system_reset != NULL);
/* Notify the Secure Payload Dispatcher */
- if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
psci_spd_pm->svc_system_reset();
}
- console_flush();
+ (void) console_flush();
/* Call the platform specific hook */
psci_plat_pm_ops->system_reset();
@@ -50,32 +50,34 @@ void __dead2 psci_system_reset(void)
/* This function does not return. We should never get here */
}
-int psci_system_reset2(uint32_t reset_type, u_register_t cookie)
+u_register_t psci_system_reset2(uint32_t reset_type, u_register_t cookie)
{
- int is_vendor;
+ unsigned int is_vendor;
psci_print_power_domain_map();
- assert(psci_plat_pm_ops->system_reset2);
+ assert(psci_plat_pm_ops->system_reset2 != NULL);
- is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1;
- if (!is_vendor) {
+ is_vendor = (reset_type >> PSCI_RESET2_TYPE_VENDOR_SHIFT) & 1U;
+ if (is_vendor == 0U) {
/*
* Only WARM_RESET is allowed for architectural type resets.
*/
if (reset_type != PSCI_RESET2_SYSTEM_WARM_RESET)
- return PSCI_E_INVALID_PARAMS;
- if (psci_plat_pm_ops->write_mem_protect &&
- psci_plat_pm_ops->write_mem_protect(0) < 0) {
- return PSCI_E_NOT_SUPPORTED;
+ return (u_register_t) PSCI_E_INVALID_PARAMS;
+ if ((psci_plat_pm_ops->write_mem_protect != NULL) &&
+ (psci_plat_pm_ops->write_mem_protect(0) < 0)) {
+ return (u_register_t) PSCI_E_NOT_SUPPORTED;
}
}
/* Notify the Secure Payload Dispatcher */
- if (psci_spd_pm && psci_spd_pm->svc_system_reset) {
+ if ((psci_spd_pm != NULL) && (psci_spd_pm->svc_system_reset != NULL)) {
psci_spd_pm->svc_system_reset();
}
- console_flush();
+ (void) console_flush();
- return psci_plat_pm_ops->system_reset2(is_vendor, reset_type, cookie);
+ return (u_register_t)
+ psci_plat_pm_ops->system_reset2((int) is_vendor, reset_type,
+ cookie);
}
diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile
new file mode 100644
index 000000000..46b920682
--- /dev/null
+++ b/lib/romlib/Makefile
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+AS = $(CROSS_COMPILE)as
+LD = $(CROSS_COMPILE)ld
+OC = $(CROSS_COMPILE)objcopy
+CPP = $(CROSS_COMPILE)cpp
+BUILD_DIR = ../../$(BUILD_PLAT)/romlib
+LIB_DIR = ../../$(BUILD_PLAT)/lib
+WRAPPER_DIR = ../../$(BUILD_PLAT)/libwrapper
+LIBS = -lmbedtls -lfdt -lc
+INC = $(INCLUDES:-I%=-I../../%)
+PPFLAGS = $(INC) $(DEFINES) -P -D__ASSEMBLY__ -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld
+OBJS = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o
+
+V ?= 0
+ifeq ($(V),0)
+ Q := @
+else
+ Q :=
+endif
+
+ifeq ($(DEBUG),1)
+ CFLAGS := -g
+ LDFLAGS := -g
+endif
+
+
+.PHONY: all clean distclean
+
+all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a
+
+%.o: %.s
+ @echo " AS $@"
+ $(Q)$(AS) $(ASFLAGS) -o $@ $<
+
+$(BUILD_DIR)/%.o: %.s
+ @echo " AS $@"
+ $(Q)$(AS) $(ASFLAGS) -o $@ $<
+
+$(BUILD_DIR)/romlib.ld: romlib.ld.S
+ @echo " PP $@"
+ $(Q)$(CPP) $(PPFLAGS) -o $@ romlib.ld.S
+
+$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld
+ @echo " LD $@"
+ $(Q)$(LD) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf
+ @echo " BIN $@"
+ $(Q)$(OC) -O binary $(BUILD_DIR)/romlib.elf $@
+
+$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf
+ @echo " VAR $@"
+ $(Q)./genvar.sh -o $@ $(BUILD_DIR)/romlib.elf
+
+$(LIB_DIR)/libwrappers.a: jmptbl.i $(WRAPPER_DIR)/jmpvar.o
+ @echo " AR $@"
+ $(Q)./genwrappers.sh -b $(WRAPPER_DIR) -o $@ jmptbl.i
+
+$(BUILD_DIR)/jmptbl.s: jmptbl.i
+ @echo " TBL $@"
+ $(Q)./gentbl.sh -o $@ jmptbl.i
+
+clean:
+ @rm -f $(BUILD_DIR)/*
+
+-include $(BUILD_DIR)/romlib.d
diff --git a/lib/romlib/gentbl.sh b/lib/romlib/gentbl.sh
new file mode 100755
index 000000000..0695f6e4f
--- /dev/null
+++ b/lib/romlib/gentbl.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+output=jmptbl.s
+
+for i
+do
+ case $i in
+ -o)
+ output=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ echo usage: gentbl.sh [-o output] file ... >&2
+ exit 1
+ ;;
+ esac
+done
+
+tmp=`mktemp`
+trap "rm -f $tmp" EXIT INT QUIT
+
+rm -f $output
+
+awk -v OFS="\n" '
+BEGIN {print "\t.text",
+ "\t.globl\tjmptbl",
+ "jmptbl:"}
+ {sub(/[:blank:]*#.*/,"")}
+!/^$/ {print "\tb\t" $3}' "$@" > $tmp
+
+mv $tmp $output
diff --git a/lib/romlib/genvar.sh b/lib/romlib/genvar.sh
new file mode 100755
index 000000000..a3e2cdf69
--- /dev/null
+++ b/lib/romlib/genvar.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+output=jmpvar.s
+for i
+do
+ case $i in
+ -o)
+ output=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ echo usage: genvar.sh [-o output] file... >&2
+ ;;
+ esac
+done
+
+tmp=`mktemp`
+trap "rm -f $tmp" EXIT INT QUIT
+
+nm -a "$@" |
+awk -v OFS="\n" '
+$3 == ".text" {print "\t.data",
+ "\t.globl\tjmptbl",
+ "\t.align\t4",
+ "jmptbl:\t.quad\t0x" $1}' > $tmp
+
+mv $tmp $output
diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh
new file mode 100755
index 000000000..bcf670b98
--- /dev/null
+++ b/lib/romlib/genwrappers.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+set -e
+
+build=.
+out=output.a
+
+for i
+do
+ case $i in
+ -o)
+ out=$2
+ shift 2
+ ;;
+ -b)
+ build=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ -*)
+ echo usage: genwrappers.sh [-o output] [-b dir] file ... >&2
+ exit 1
+ ;;
+ esac
+done
+
+awk '{sub(/[:blank:]*#.*/,"")}
+!/^$/ {print $1*4, $2, $3}' "$@" |
+while read idx lib sym
+do
+ file=$build/${lib}_$sym
+
+ cat <<EOF > $file.s
+ .globl $sym
+$sym:
+ ldr x17, =jmptbl
+ ldr x17, [x17]
+ mov x16, $idx
+ add x16, x16, x17
+ br x16
+EOF
+
+ ${CROSS_COMPILE}as -o $file.o $file.s
+done
+
+${CROSS_COMPILE}ar -rc $out $build/*.o
diff --git a/lib/romlib/init.s b/lib/romlib/init.s
new file mode 100644
index 000000000..5cf2aca04
--- /dev/null
+++ b/lib/romlib/init.s
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .globl rom_lib_init
+ .extern __DATA_RAM_START__, __DATA_ROM_START__, __DATA_SIZE__
+ .extern memset, memcpy
+
+rom_lib_init:
+ cmp w0, #1
+ mov w0, #0
+ b.le 1f
+ ret
+
+1: stp x29, x30, [sp, #-16]!
+ adrp x0, __DATA_RAM_START__
+ ldr x1,= __DATA_ROM_START__
+ ldr x2, =__DATA_SIZE__
+ bl memcpy
+
+ ldr x0, =__BSS_START__
+ mov x1, #0
+ ldr x2, =__BSS_SIZE__
+ bl memset
+ ldp x29, x30, [sp], #16
+
+ mov w0, #1
+ ret
diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i
new file mode 100644
index 000000000..338cd8a71
--- /dev/null
+++ b/lib/romlib/jmptbl.i
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+0 rom rom_lib_init
+1 fdt fdt_getprop_namelen
+2 fdt fdt_setprop_inplace
+3 fdt fdt_check_header
+4 fdt fdt_node_offset_by_compatible
+5 mbedtls mbedtls_asn1_get_alg
+6 mbedtls mbedtls_asn1_get_alg_null
+7 mbedtls mbedtls_asn1_get_bitstring_null
+8 mbedtls mbedtls_asn1_get_bool
+9 mbedtls mbedtls_asn1_get_int
+10 mbedtls mbedtls_asn1_get_tag
+11 mbedtls mbedtls_free
+12 mbedtls mbedtls_md
+13 mbedtls mbedtls_md_get_size
+14 mbedtls mbedtls_memory_buffer_alloc_init
+15 mbedtls mbedtls_oid_get_md_alg
+16 mbedtls mbedtls_oid_get_numeric_string
+17 mbedtls mbedtls_oid_get_pk_alg
+18 mbedtls mbedtls_oid_get_sig_alg
+19 mbedtls mbedtls_pk_free
+20 mbedtls mbedtls_pk_init
+21 mbedtls mbedtls_pk_parse_subpubkey
+22 mbedtls mbedtls_pk_verify_ext
+23 mbedtls mbedtls_platform_set_snprintf
+24 mbedtls mbedtls_x509_get_rsassa_pss_params
+25 mbedtls mbedtls_x509_get_sig_alg
+26 mbedtls mbedtls_md_info_from_type
+27 c exit
+28 c atexit
diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S
new file mode 100644
index 000000000..8f0bc62bc
--- /dev/null
+++ b/lib/romlib/romlib.ld.S
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <xlat_tables_defs.h>
+
+MEMORY {
+ ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE
+ RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE
+}
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(jmptbl)
+
+SECTIONS
+{
+ . = ROMLIB_RO_BASE;
+ .text : {
+ *jmptbl.o(.text)
+ *(.text*)
+ *(.rodata*)
+ } >ROM
+
+ __DATA_ROM_START__ = LOADADDR(.data);
+
+ .data : {
+ __DATA_RAM_START__ = .;
+ *(.data*)
+ __DATA_RAM_END__ = .;
+ } >RAM AT>ROM
+
+ __DATA_SIZE__ = SIZEOF(.data);
+
+ .bss : {
+ __BSS_START__ = .;
+ *(.bss*)
+ __BSS_END__ = .;
+ } >RAM
+ __BSS_SIZE__ = SIZEOF(.bss);
+}
diff --git a/lib/stdlib/exit.c b/lib/stdlib/exit.c
deleted file mode 100644
index afc3f9343..000000000
--- a/lib/stdlib/exit.c
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <debug.h>
-#include <stdlib.h>
-
-void exit(int v)
-{
- ERROR("EXIT\n");
- panic();
-}
diff --git a/lib/stdlib/mem.c b/lib/stdlib/mem.c
deleted file mode 100644
index 65b62fde6..000000000
--- a/lib/stdlib/mem.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h> /* size_t */
-
-/*
- * Fill @count bytes of memory pointed to by @dst with @val
- */
-void *memset(void *dst, int val, size_t count)
-{
- char *ptr = dst;
-
- while (count--)
- *ptr++ = val;
-
- return dst;
-}
-
-/*
- * Compare @len bytes of @s1 and @s2
- */
-int memcmp(const void *s1, const void *s2, size_t len)
-{
- const unsigned char *s = s1;
- const unsigned char *d = s2;
- unsigned char sc;
- unsigned char dc;
-
- while (len--) {
- sc = *s++;
- dc = *d++;
- if (sc - dc)
- return (sc - dc);
- }
-
- return 0;
-}
-
-/*
- * Copy @len bytes from @src to @dst
- */
-void *memcpy(void *dst, const void *src, size_t len)
-{
- const char *s = src;
- char *d = dst;
-
- while (len--)
- *d++ = *s++;
-
- return dst;
-}
-
-/*
- * Move @len bytes from @src to @dst
- */
-void *memmove(void *dst, const void *src, size_t len)
-{
- /*
- * The following test makes use of unsigned arithmetic overflow to
- * more efficiently test the condition !(src <= dst && dst < str+len).
- * It also avoids the situation where the more explicit test would give
- * incorrect results were the calculation str+len to overflow (though
- * that issue is probably moot as such usage is probably undefined
- * behaviour and a bug anyway.
- */
- if ((size_t)dst - (size_t)src >= len) {
- /* destination not in source data, so can safely use memcpy */
- return memcpy(dst, src, len);
- } else {
- /* copy backwards... */
- const char *end = dst;
- const char *s = (const char *)src + len;
- char *d = (char *)dst + len;
- while (d != end)
- *--d = *--s;
- }
- return dst;
-}
-
-/*
- * Scan @len bytes of @src for value @c
- */
-void *memchr(const void *src, int c, size_t len)
-{
- const char *s = src;
-
- while (len--) {
- if (*s == c)
- return (void *) s;
- s++;
- }
-
- return NULL;
-}
diff --git a/lib/stdlib/printf.c b/lib/stdlib/printf.c
deleted file mode 100644
index f61564140..000000000
--- a/lib/stdlib/printf.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdio.h>
-#include <stdarg.h>
-
-/* Choose max of 128 chars for now. */
-#define PRINT_BUFFER_SIZE 128
-int printf(const char *fmt, ...)
-{
- va_list args;
- char buf[PRINT_BUFFER_SIZE];
- int count;
-
- va_start(args, fmt);
- vsnprintf(buf, sizeof(buf) - 1, fmt, args);
- va_end(args);
-
- /* Use putchar directly as 'puts()' adds a newline. */
- buf[PRINT_BUFFER_SIZE - 1] = '\0';
- count = 0;
- while (buf[count])
- {
- if (putchar(buf[count]) != EOF) {
- count++;
- } else {
- count = EOF;
- break;
- }
- }
-
- return count;
-}
diff --git a/lib/stdlib/putchar.c b/lib/stdlib/putchar.c
deleted file mode 100644
index 8265667b1..000000000
--- a/lib/stdlib/putchar.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdio.h>
-#include <console.h>
-
-/* Putchar() should either return the character printed or EOF in case of error.
- * Our current console_putc() function assumes success and returns the
- * character. Write all other printing functions in terms of putchar(), if
- * possible, so they all benefit when this is improved.
- */
-int putchar(int c)
-{
- int res;
- if (console_putc((unsigned char)c) >= 0)
- res = c;
- else
- res = EOF;
-
- return res;
-}
diff --git a/lib/stdlib/sscanf.c b/lib/stdlib/sscanf.c
deleted file mode 100644
index a5876cff3..000000000
--- a/lib/stdlib/sscanf.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stdio.h>
-#include <sys/cdefs.h>
-
-/*
- * TODO: This is not a real implementation of the sscanf() function. It just
- * returns the number of expected arguments based on the number of '%' found
- * in the format string.
- */
-int
-sscanf(const char *__restrict str, char const *__restrict fmt, ...)
-{
- int ret = 0;
-
- while (*fmt != '\0') {
- if (*fmt++ == '%') {
- ret++;
- }
- }
-
- return ret;
-}
diff --git a/lib/stdlib/stdlib.mk b/lib/stdlib/stdlib.mk
deleted file mode 100644
index 821162354..000000000
--- a/lib/stdlib/stdlib.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-STDLIB_SRCS := $(addprefix lib/stdlib/, \
- abort.c \
- assert.c \
- exit.c \
- mem.c \
- printf.c \
- putchar.c \
- puts.c \
- sscanf.c \
- strchr.c \
- strcmp.c \
- strlen.c \
- strncmp.c \
- strnlen.c \
- subr_prf.c \
- timingsafe_bcmp.c)
-
-INCLUDES += -Iinclude/lib/stdlib \
- -Iinclude/lib/stdlib/sys
diff --git a/lib/stdlib/strlen.c b/lib/stdlib/strlen.c
deleted file mode 100644
index 23c3d3929..000000000
--- a/lib/stdlib/strlen.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- */
-
-/*
- * Portions copyright (c) 2009-2014, ARM Limited and Contributors. All rights reserved.
- */
-
-#include <stddef.h>
-
-size_t
-strlen(str)
- const char *str;
-{
- register const char *s;
-
- for (s = str; *s; ++s);
- return(s - str);
-}
diff --git a/lib/stdlib/subr_prf.c b/lib/stdlib/subr_prf.c
deleted file mode 100644
index c1035624e..000000000
--- a/lib/stdlib/subr_prf.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*-
- * Copyright (c) 1986, 1988, 1991, 1993
- * The Regents of the University of California. All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
- *
- * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94
- */
-
-/*
- * Portions copyright (c) 2009-2014, ARM Limited and Contributors.
- * All rights reserved.
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-
-typedef unsigned char u_char;
-typedef unsigned int u_int;
-typedef int64_t quad_t;
-typedef uint64_t u_quad_t;
-typedef unsigned long u_long;
-typedef unsigned short u_short;
-
-static inline int imax(int a, int b) { return (a > b ? a : b); }
-
-/*
- * Note that stdarg.h and the ANSI style va_start macro is used for both
- * ANSI and traditional C compilers.
- */
-
-#define TOCONS 0x01
-#define TOTTY 0x02
-#define TOLOG 0x04
-
-/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
-#define MAXNBUF (sizeof(intmax_t) * 8 + 1)
-
-struct putchar_arg {
- int flags;
- int pri;
- struct tty *tty;
- char *p_bufr;
- size_t n_bufr;
- char *p_next;
- size_t remain;
-};
-
-struct snprintf_arg {
- char *str;
- size_t remain;
-};
-
-extern int log_open;
-
-static char *ksprintn(char *nbuf, uintmax_t num, int base, int *len, int upper);
-static void snprintf_func(int ch, void *arg);
-static int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap);
-
-int vsnprintf(char *str, size_t size, const char *format, va_list ap);
-
-static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-#define hex2ascii(hex) (hex2ascii_data[hex])
-
-/*
- * Scaled down version of sprintf(3).
- */
-int
-sprintf(char *buf, const char *cfmt, ...)
-{
- int retval;
- va_list ap;
-
- va_start(ap, cfmt);
- retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
- buf[retval] = '\0';
- va_end(ap);
- return (retval);
-}
-
-/*
- * Scaled down version of vsprintf(3).
- */
-int
-vsprintf(char *buf, const char *cfmt, va_list ap)
-{
- int retval;
-
- retval = kvprintf(cfmt, NULL, (void *)buf, 10, ap);
- buf[retval] = '\0';
- return (retval);
-}
-
-/*
- * Scaled down version of snprintf(3).
- */
-int
-snprintf(char *str, size_t size, const char *format, ...)
-{
- int retval;
- va_list ap;
-
- va_start(ap, format);
- retval = vsnprintf(str, size, format, ap);
- va_end(ap);
- return(retval);
-}
-
-/*
- * Scaled down version of vsnprintf(3).
- */
-int
-vsnprintf(char *str, size_t size, const char *format, va_list ap)
-{
- struct snprintf_arg info;
- int retval;
-
- info.str = str;
- info.remain = size;
- retval = kvprintf(format, snprintf_func, &info, 10, ap);
- if (info.remain >= 1)
- *info.str++ = '\0';
- return (retval);
-}
-
-static void
-snprintf_func(int ch, void *arg)
-{
- struct snprintf_arg *const info = arg;
-
- if (info->remain >= 2) {
- *info->str++ = ch;
- info->remain--;
- }
-}
-
-
-/*
- * Kernel version which takes radix argument vsnprintf(3).
- */
-int
-vsnrprintf(char *str, size_t size, int radix, const char *format, va_list ap)
-{
- struct snprintf_arg info;
- int retval;
-
- info.str = str;
- info.remain = size;
- retval = kvprintf(format, snprintf_func, &info, radix, ap);
- if (info.remain >= 1)
- *info.str++ = '\0';
- return (retval);
-}
-
-
-/*
- * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
- * order; return an optional length and a pointer to the last character
- * written in the buffer (i.e., the first character of the string).
- * The buffer pointed to by `nbuf' must have length >= MAXNBUF.
- */
-static char *
-ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper)
-{
- char *p, c;
-
- p = nbuf;
- *p = '\0';
- do {
- c = hex2ascii(num % base);
- *++p = upper ? toupper(c) : c;
- } while (num /= base);
- if (lenp)
- *lenp = p - nbuf;
- return (p);
-}
-
-/*
- * Scaled down version of printf(3).
- *
- * Two additional formats:
- *
- * The format %b is supported to decode error registers.
- * Its usage is:
- *
- * printf("reg=%b\n", regval, "<base><arg>*");
- *
- * where <base> is the output base expressed as a control character, e.g.
- * \10 gives octal; \20 gives hex. Each arg is a sequence of characters,
- * the first of which gives the bit number to be inspected (origin 1), and
- * the next characters (up to a control character, i.e. a character <= 32),
- * give the name of the register. Thus:
- *
- * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n");
- *
- * would produce output:
- *
- * reg=3<BITTWO,BITONE>
- *
- * XXX: %D -- Hexdump, takes pointer and separator string:
- * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX
- * ("%*D", len, ptr, " " -> XX XX XX XX ...
- */
-int
-kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap)
-{
-#define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; }
- char nbuf[MAXNBUF];
- char *d;
- const char *p, *percent, *q;
- u_char *up;
- int ch, n;
- uintmax_t num;
- int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot;
- int cflag, hflag, jflag, tflag, zflag;
- int dwidth, upper;
- char padc;
- int stop = 0, retval = 0;
-
- num = 0;
- if (!func)
- d = (char *) arg;
- else
- d = NULL;
-
- if (fmt == NULL)
- fmt = "(fmt null)\n";
-
- if (radix < 2 || radix > 36)
- radix = 10;
-
- for (;;) {
- padc = ' ';
- width = 0;
- while ((ch = (u_char)*fmt++) != '%' || stop) {
- if (ch == '\0')
- return (retval);
- PCHAR(ch);
- }
- percent = fmt - 1;
- qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0;
- sign = 0; dot = 0; dwidth = 0; upper = 0;
- cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0;
-reswitch: switch (ch = (u_char)*fmt++) {
- case '.':
- dot = 1;
- goto reswitch;
- case '#':
- sharpflag = 1;
- goto reswitch;
- case '+':
- sign = 1;
- goto reswitch;
- case '-':
- ladjust = 1;
- goto reswitch;
- case '%':
- PCHAR(ch);
- break;
- case '*':
- if (!dot) {
- width = va_arg(ap, int);
- if (width < 0) {
- ladjust = !ladjust;
- width = -width;
- }
- } else {
- dwidth = va_arg(ap, int);
- }
- goto reswitch;
- case '0':
- if (!dot) {
- padc = '0';
- goto reswitch;
- }
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- for (n = 0;; ++fmt) {
- n = n * 10 + ch - '0';
- ch = *fmt;
- if (ch < '0' || ch > '9')
- break;
- }
- if (dot)
- dwidth = n;
- else
- width = n;
- goto reswitch;
- case 'b':
- num = (u_int)va_arg(ap, int);
- p = va_arg(ap, char *);
- for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;)
- PCHAR(*q--);
-
- if (num == 0)
- break;
-
- for (tmp = 0; *p;) {
- n = *p++;
- if (num & (1 << (n - 1))) {
- PCHAR(tmp ? ',' : '<');
- for (; (n = *p) > ' '; ++p)
- PCHAR(n);
- tmp = 1;
- } else
- for (; *p > ' '; ++p)
- continue;
- }
- if (tmp)
- PCHAR('>');
- break;
- case 'c':
- PCHAR(va_arg(ap, int));
- break;
- case 'D':
- up = va_arg(ap, u_char *);
- p = va_arg(ap, char *);
- if (!width)
- width = 16;
- while(width--) {
- PCHAR(hex2ascii(*up >> 4));
- PCHAR(hex2ascii(*up & 0x0f));
- up++;
- if (width)
- for (q=p;*q;q++)
- PCHAR(*q);
- }
- break;
- case 'd':
- case 'i':
- base = 10;
- sign = 1;
- goto handle_sign;
- case 'h':
- if (hflag) {
- hflag = 0;
- cflag = 1;
- } else
- hflag = 1;
- goto reswitch;
- case 'j':
- jflag = 1;
- goto reswitch;
- case 'l':
- if (lflag) {
- lflag = 0;
- qflag = 1;
- } else
- lflag = 1;
- goto reswitch;
- case 'n':
- if (jflag)
- *(va_arg(ap, intmax_t *)) = retval;
- else if (qflag)
- *(va_arg(ap, quad_t *)) = retval;
- else if (lflag)
- *(va_arg(ap, long *)) = retval;
- else if (zflag)
- *(va_arg(ap, size_t *)) = retval;
- else if (hflag)
- *(va_arg(ap, short *)) = retval;
- else if (cflag)
- *(va_arg(ap, char *)) = retval;
- else
- *(va_arg(ap, int *)) = retval;
- break;
- case 'o':
- base = 8;
- goto handle_nosign;
- case 'p':
- base = 16;
- sharpflag = (width == 0);
- sign = 0;
- num = (uintptr_t)va_arg(ap, void *);
- goto number;
- case 'q':
- qflag = 1;
- goto reswitch;
- case 'r':
- base = radix;
- if (sign)
- goto handle_sign;
- goto handle_nosign;
- case 's':
- p = va_arg(ap, char *);
- if (p == NULL)
- p = "(null)";
- if (!dot)
- n = strlen (p);
- else
- for (n = 0; n < dwidth && p[n]; n++)
- continue;
-
- width -= n;
-
- if (!ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- while (n--)
- PCHAR(*p++);
- if (ladjust && width > 0)
- while (width--)
- PCHAR(padc);
- break;
- case 't':
- tflag = 1;
- goto reswitch;
- case 'u':
- base = 10;
- goto handle_nosign;
- case 'X':
- upper = 1;
- case 'x':
- base = 16;
- goto handle_nosign;
- case 'y':
- base = 16;
- sign = 1;
- goto handle_sign;
- case 'z':
- zflag = 1;
- goto reswitch;
-handle_nosign:
- sign = 0;
- if (jflag)
- num = va_arg(ap, uintmax_t);
- else if (qflag)
- num = va_arg(ap, u_quad_t);
- else if (tflag)
- num = va_arg(ap, ptrdiff_t);
- else if (lflag)
- num = va_arg(ap, u_long);
- else if (zflag)
- num = va_arg(ap, size_t);
- else if (hflag)
- num = (u_short)va_arg(ap, int);
- else if (cflag)
- num = (u_char)va_arg(ap, int);
- else
- num = va_arg(ap, u_int);
- goto number;
-handle_sign:
- if (jflag)
- num = va_arg(ap, intmax_t);
- else if (qflag)
- num = va_arg(ap, quad_t);
- else if (tflag)
- num = va_arg(ap, ptrdiff_t);
- else if (lflag)
- num = va_arg(ap, long);
- else if (zflag)
- num = va_arg(ap, ssize_t);
- else if (hflag)
- num = (short)va_arg(ap, int);
- else if (cflag)
- num = (char)va_arg(ap, int);
- else
- num = va_arg(ap, int);
-number:
- if (sign && (intmax_t)num < 0) {
- neg = 1;
- num = -(intmax_t)num;
- }
- p = ksprintn(nbuf, num, base, &n, upper);
- tmp = 0;
- if (sharpflag && num != 0) {
- if (base == 8)
- tmp++;
- else if (base == 16)
- tmp += 2;
- }
- if (neg)
- tmp++;
-
- if (!ladjust && padc == '0')
- dwidth = width - tmp;
- width -= tmp + imax(dwidth, n);
- dwidth -= n;
- if (!ladjust)
- while (width-- > 0)
- PCHAR(' ');
- if (neg)
- PCHAR('-');
- if (sharpflag && num != 0) {
- if (base == 8) {
- PCHAR('0');
- } else if (base == 16) {
- PCHAR('0');
- PCHAR('x');
- }
- }
- while (dwidth-- > 0)
- PCHAR('0');
-
- while (*p)
- PCHAR(*p--);
-
- if (ladjust)
- while (width-- > 0)
- PCHAR(' ');
-
- break;
- default:
- while (percent < fmt)
- PCHAR(*percent++);
- /*
- * Since we ignore an formatting argument it is no
- * longer safe to obey the remaining formatting
- * arguments as the arguments will no longer match
- * the format specs.
- */
- stop = 1;
- break;
- }
- }
-#undef PCHAR
-}
diff --git a/lib/stdlib/timingsafe_bcmp.c b/lib/stdlib/timingsafe_bcmp.c
deleted file mode 100644
index d09815805..000000000
--- a/lib/stdlib/timingsafe_bcmp.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
-/*
- * Copyright (c) 2010 Damien Miller. All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <string.h>
-
-int __timingsafe_bcmp(const void *, const void *, size_t);
-
-int
-__timingsafe_bcmp(const void *b1, const void *b2, size_t n)
-{
- const unsigned char *p1 = b1, *p2 = b2;
- int ret = 0;
-
- for (; n > 0; n--)
- ret |= *p1++ ^ *p2++;
- return (ret != 0);
-}
-
-__weak_reference(__timingsafe_bcmp, timingsafe_bcmp);
diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c
index dd639397a..033e2375f 100644
--- a/lib/xlat_tables/aarch32/xlat_tables.c
+++ b/lib/xlat_tables/aarch32/xlat_tables.c
@@ -13,7 +13,7 @@
#include <xlat_tables.h>
#include "../xlat_tables_private.h"
-#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#if (ARM_ARCH_MAJOR == 7) && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
#error ARMv7 target does not support LPAE MMU descriptors
#endif
@@ -34,16 +34,16 @@ static unsigned long long get_max_supported_pa(void)
}
#endif /* ENABLE_ASSERTIONS */
-int xlat_arch_current_el(void)
+unsigned int xlat_arch_current_el(void)
{
/*
* If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System,
* SVC, Abort, UND, IRQ and FIQ modes) execute at EL3.
*/
- return 3;
+ return 3U;
}
-uint64_t xlat_arch_get_xn_desc(int el __unused)
+uint64_t xlat_arch_get_xn_desc(unsigned int el __unused)
{
return UPPER_ATTRS(XN);
}
@@ -53,25 +53,37 @@ void init_xlat_tables(void)
unsigned long long max_pa;
uintptr_t max_va;
print_mmap();
- init_xlation_table(0, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
+ init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);
- assert(max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1);
- assert(max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1);
- assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= get_max_supported_pa());
+ assert(max_va <= (PLAT_VIRT_ADDR_SPACE_SIZE - 1U));
+ assert(max_pa <= (PLAT_PHY_ADDR_SPACE_SIZE - 1U));
+ assert((PLAT_PHY_ADDR_SPACE_SIZE - 1U) <= get_max_supported_pa());
}
/*******************************************************************************
* Function for enabling the MMU in Secure PL1, assuming that the
* page-tables have already been created.
******************************************************************************/
+#if !ERROR_DEPRECATED
void enable_mmu_secure(unsigned int flags)
{
+ enable_mmu_svc_mon(flags);
+}
+
+void enable_mmu_direct(unsigned int flags)
+{
+ enable_mmu_direct_svc_mon(flags);
+}
+#endif
+
+void enable_mmu_svc_mon(unsigned int flags)
+{
unsigned int mair0, ttbcr, sctlr;
uint64_t ttbr0;
assert(IS_IN_SECURE());
- assert((read_sctlr() & SCTLR_M_BIT) == 0);
+ assert((read_sctlr() & SCTLR_M_BIT) == 0U);
/* Set attributes in the right indices of the MAIR */
mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
@@ -87,18 +99,18 @@ void enable_mmu_secure(unsigned int flags)
/*
* Set TTBCR bits as well. Set TTBR0 table properties. Disable TTBR1.
*/
- if (flags & XLAT_TABLE_NC) {
+ int t0sz = 32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE);
+
+ if ((flags & XLAT_TABLE_NC) != 0U) {
/* Inner & outer non-cacheable non-shareable. */
ttbcr = TTBCR_EAE_BIT |
TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
- TTBCR_RGN0_INNER_NC |
- (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
+ TTBCR_RGN0_INNER_NC | (uint32_t) t0sz;
} else {
/* Inner & outer WBWA & shareable. */
ttbcr = TTBCR_EAE_BIT |
TTBCR_SH0_INNER_SHAREABLE | TTBCR_RGN0_OUTER_WBA |
- TTBCR_RGN0_INNER_WBA |
- (32 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));
+ TTBCR_RGN0_INNER_WBA | (uint32_t) t0sz;
}
ttbcr |= TTBCR_EPD1_BIT;
write_ttbcr(ttbcr);
@@ -106,7 +118,7 @@ void enable_mmu_secure(unsigned int flags)
/* Set TTBR0 bits as well */
ttbr0 = (uintptr_t) base_xlation_table;
write64_ttbr0(ttbr0);
- write64_ttbr1(0);
+ write64_ttbr1(0U);
/*
* Ensure all translation table writes have drained
@@ -120,7 +132,7 @@ void enable_mmu_secure(unsigned int flags)
sctlr = read_sctlr();
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT;
- if (flags & DISABLE_DCACHE)
+ if ((flags & DISABLE_DCACHE) != 0U)
sctlr &= ~SCTLR_C_BIT;
else
sctlr |= SCTLR_C_BIT;
@@ -131,7 +143,7 @@ void enable_mmu_secure(unsigned int flags)
isb();
}
-void enable_mmu_direct(unsigned int flags)
+void enable_mmu_direct_svc_mon(unsigned int flags)
{
- enable_mmu_secure(flags);
+ enable_mmu_svc_mon(flags);
}
diff --git a/lib/xlat_tables/aarch64/xlat_tables.c b/lib/xlat_tables/aarch64/xlat_tables.c
index 5717516a4..4afdeed06 100644
--- a/lib/xlat_tables/aarch64/xlat_tables.c
+++ b/lib/xlat_tables/aarch64/xlat_tables.c
@@ -10,7 +10,7 @@
#include <bl_common.h>
#include <common_def.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include <utils.h>
#include <xlat_tables.h>
#include <xlat_tables_arch.h>
@@ -31,26 +31,26 @@ static unsigned long long calc_physical_addr_size_bits(
unsigned long long max_addr)
{
/* Physical address can't exceed 48 bits */
- assert((max_addr & ADDR_MASK_48_TO_63) == 0);
+ assert((max_addr & ADDR_MASK_48_TO_63) == 0U);
/* 48 bits address */
- if (max_addr & ADDR_MASK_44_TO_47)
+ if ((max_addr & ADDR_MASK_44_TO_47) != 0U)
return TCR_PS_BITS_256TB;
/* 44 bits address */
- if (max_addr & ADDR_MASK_42_TO_43)
+ if ((max_addr & ADDR_MASK_42_TO_43) != 0U)
return TCR_PS_BITS_16TB;
/* 42 bits address */
- if (max_addr & ADDR_MASK_40_TO_41)
+ if ((max_addr & ADDR_MASK_40_TO_41) != 0U)
return TCR_PS_BITS_4TB;
/* 40 bits address */
- if (max_addr & ADDR_MASK_36_TO_39)
+ if ((max_addr & ADDR_MASK_36_TO_39) != 0U)
return TCR_PS_BITS_1TB;
/* 36 bits address */
- if (max_addr & ADDR_MASK_32_TO_35)
+ if ((max_addr & ADDR_MASK_32_TO_35) != 0U)
return TCR_PS_BITS_64GB;
return TCR_PS_BITS_4GB;
@@ -78,21 +78,21 @@ static unsigned long long get_max_supported_pa(void)
}
#endif /* ENABLE_ASSERTIONS */
-int xlat_arch_current_el(void)
+unsigned int xlat_arch_current_el(void)
{
- int el = GET_EL(read_CurrentEl());
+ unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
- assert(el > 0);
+ assert(el > 0U);
return el;
}
-uint64_t xlat_arch_get_xn_desc(int el)
+uint64_t xlat_arch_get_xn_desc(unsigned int el)
{
- if (el == 3) {
+ if (el == 3U) {
return UPPER_ATTRS(XN);
} else {
- assert(el == 1);
+ assert(el == 1U);
return UPPER_ATTRS(PXN);
}
}
@@ -102,12 +102,12 @@ void init_xlat_tables(void)
unsigned long long max_pa;
uintptr_t max_va;
print_mmap();
- init_xlation_table(0, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
+ init_xlation_table(0U, base_xlation_table, XLAT_TABLE_LEVEL_BASE,
&max_va, &max_pa);
- assert(max_va <= PLAT_VIRT_ADDR_SPACE_SIZE - 1);
- assert(max_pa <= PLAT_PHY_ADDR_SPACE_SIZE - 1);
- assert((PLAT_PHY_ADDR_SPACE_SIZE - 1) <= get_max_supported_pa());
+ assert(max_va <= (PLAT_VIRT_ADDR_SPACE_SIZE - 1U));
+ assert(max_pa <= (PLAT_PHY_ADDR_SPACE_SIZE - 1U));
+ assert((PLAT_PHY_ADDR_SPACE_SIZE - 1U) <= get_max_supported_pa());
tcr_ps_bits = calc_physical_addr_size_bits(max_pa);
}
@@ -129,7 +129,7 @@ void init_xlat_tables(void)
uint32_t sctlr; \
\
assert(IS_IN_EL(_el)); \
- assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0); \
+ assert((read_sctlr_el##_el() & SCTLR_M_BIT) == 0U); \
\
/* Set attributes in the right indices of the MAIR */ \
mair = MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); \
@@ -144,16 +144,18 @@ void init_xlat_tables(void)
\
/* Set TCR bits as well. */ \
/* Set T0SZ to (64 - width of virtual address space) */ \
- if (flags & XLAT_TABLE_NC) { \
+ int t0sz = 64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE);\
+ \
+ if ((flags & XLAT_TABLE_NC) != 0U) { \
/* Inner & outer non-cacheable non-shareable. */\
tcr = TCR_SH_NON_SHAREABLE | \
TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC | \
- (64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
+ (uint64_t) t0sz; \
} else { \
/* Inner & outer WBWA & shareable. */ \
tcr = TCR_SH_INNER_SHAREABLE | \
TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA | \
- (64 - __builtin_ctzll(PLAT_VIRT_ADDR_SPACE_SIZE));\
+ (uint64_t) t0sz; \
} \
tcr |= _tcr_extra; \
write_tcr_el##_el(tcr); \
@@ -172,7 +174,7 @@ void init_xlat_tables(void)
sctlr = read_sctlr_el##_el(); \
sctlr |= SCTLR_WXN_BIT | SCTLR_M_BIT; \
\
- if (flags & DISABLE_DCACHE) \
+ if ((flags & DISABLE_DCACHE) != 0U) \
sctlr &= ~SCTLR_C_BIT; \
else \
sctlr |= SCTLR_C_BIT; \
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index b42cd6814..ca67f2a09 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -11,8 +11,9 @@
#include <common_def.h>
#include <debug.h>
#include <platform_def.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
-#include <types.h>
#include <utils.h>
#include <xlat_tables.h>
#include "xlat_tables_private.h"
@@ -26,12 +27,13 @@
(((level) == U(0)) ? LVL0_SPACER : \
(((level) == U(1)) ? LVL1_SPACER : \
(((level) == U(2)) ? LVL2_SPACER : LVL3_SPACER)))
-#define debug_print(...) tf_printf(__VA_ARGS__)
+#define debug_print(...) printf(__VA_ARGS__)
#else
#define debug_print(...) ((void)0)
#endif
#define UNSET_DESC ~0ULL
+#define MT_UNKNOWN ~0U
static uint64_t xlat_tables[MAX_XLAT_TABLES][XLAT_TABLE_ENTRIES]
__aligned(XLAT_TABLE_SIZE) __section("xlat_table");
@@ -55,7 +57,7 @@ void print_mmap(void)
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
debug_print("mmap:\n");
mmap_region_t *mm = mmap;
- while (mm->size) {
+ while (mm->size != 0U) {
debug_print(" VA:%p PA:0x%llx size:0x%zx attr:0x%x\n",
(void *)mm->base_va, mm->base_pa,
mm->size, mm->attr);
@@ -69,37 +71,37 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
size_t size, unsigned int attr)
{
mmap_region_t *mm = mmap;
- mmap_region_t *mm_last = mm + ARRAY_SIZE(mmap) - 1;
- unsigned long long end_pa = base_pa + size - 1;
- uintptr_t end_va = base_va + size - 1;
+ const mmap_region_t *mm_last = mm + ARRAY_SIZE(mmap) - 1U;
+ unsigned long long end_pa = base_pa + size - 1U;
+ uintptr_t end_va = base_va + size - 1U;
assert(IS_PAGE_ALIGNED(base_pa));
assert(IS_PAGE_ALIGNED(base_va));
assert(IS_PAGE_ALIGNED(size));
- if (!size)
+ if (size == 0U)
return;
assert(base_pa < end_pa); /* Check for overflows */
assert(base_va < end_va);
assert((base_va + (uintptr_t)size - (uintptr_t)1) <=
- (PLAT_VIRT_ADDR_SPACE_SIZE - 1));
+ (PLAT_VIRT_ADDR_SPACE_SIZE - 1U));
assert((base_pa + (unsigned long long)size - 1ULL) <=
- (PLAT_PHY_ADDR_SPACE_SIZE - 1));
+ (PLAT_PHY_ADDR_SPACE_SIZE - 1U));
#if ENABLE_ASSERTIONS
/* Check for PAs and VAs overlaps with all other regions */
for (mm = mmap; mm->size; ++mm) {
- uintptr_t mm_end_va = mm->base_va + mm->size - 1;
+ uintptr_t mm_end_va = mm->base_va + mm->size - 1U;
/*
* Check if one of the regions is completely inside the other
* one.
*/
- int fully_overlapped_va =
+ bool fully_overlapped_va =
((base_va >= mm->base_va) && (end_va <= mm_end_va)) ||
((mm->base_va >= base_va) && (mm_end_va <= end_va));
@@ -122,10 +124,10 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
unsigned long long mm_end_pa =
mm->base_pa + mm->size - 1;
- int separated_pa =
- (end_pa < mm->base_pa) || (base_pa > mm_end_pa);
- int separated_va =
- (end_va < mm->base_va) || (base_va > mm_end_va);
+ bool separated_pa = (end_pa < mm->base_pa) ||
+ (base_pa > mm_end_pa);
+ bool separated_va = (end_va < mm->base_va) ||
+ (base_va > mm_end_va);
assert(separated_va && separated_pa);
}
@@ -136,7 +138,7 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
#endif /* ENABLE_ASSERTIONS */
/* Find correct place in mmap to insert new region */
- while (mm->base_va < base_va && mm->size)
+ while ((mm->base_va < base_va) && (mm->size != 0U))
++mm;
/*
@@ -154,10 +156,10 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
++mm;
/* Make room for new region by moving other regions up by one place */
- memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
+ (void)memmove(mm + 1, mm, (uintptr_t)mm_last - (uintptr_t)mm);
/* Check we haven't lost the empty sentinal from the end of the array */
- assert(mm_last->size == 0);
+ assert(mm_last->size == 0U);
mm->base_pa = base_pa;
mm->base_va = base_va;
@@ -172,9 +174,12 @@ void mmap_add_region(unsigned long long base_pa, uintptr_t base_va,
void mmap_add(const mmap_region_t *mm)
{
- while (mm->size) {
- mmap_add_region(mm->base_pa, mm->base_va, mm->size, mm->attr);
- ++mm;
+ const mmap_region_t *mm_cursor = mm;
+
+ while (mm_cursor->size != 0U) {
+ mmap_add_region(mm_cursor->base_pa, mm_cursor->base_va,
+ mm_cursor->size, mm_cursor->attr);
+ mm_cursor++;
}
}
@@ -185,7 +190,7 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
int mem_type;
/* Make sure that the granularity is fine enough to map this address. */
- assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0);
+ assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0U);
desc = addr_pa;
/*
@@ -193,8 +198,12 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
* rest.
*/
desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
- desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0;
- desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
+ desc |= ((attr & MT_NS) != 0U) ? LOWER_ATTRS(NS) : 0U;
+ desc |= ((attr & MT_RW) != 0U) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
+ /*
+ * Always set the access flag, as this library assumes access flag
+ * faults aren't managed.
+ */
desc |= LOWER_ATTRS(ACCESS_FLAG);
desc |= ap1_mask;
@@ -222,9 +231,10 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
} else { /* Normal memory */
/*
* Always map read-write normal memory as execute-never.
- * (Trusted Firmware doesn't self-modify its code, therefore
- * R/W memory is reserved for data storage, which must not be
- * executable.)
+ * This library assumes that it is used by software that does
+ * not self-modify its code, therefore R/W memory is reserved
+ * for data storage, which must not be executable.
+ *
* Note that setting the XN bit here is for consistency only.
* The function that enables the MMU sets the SCTLR_ELx.WXN bit,
* which makes any writable memory region to be treated as
@@ -234,7 +244,7 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
* For read-only memory, rely on the MT_EXECUTE/MT_EXECUTE_NEVER
* attribute to figure out the value of the XN bit.
*/
- if ((attr & MT_RW) || (attr & MT_EXECUTE_NEVER)) {
+ if (((attr & MT_RW) != 0U) || ((attr & MT_EXECUTE_NEVER) != 0U)) {
desc |= execute_never_mask;
}
@@ -248,9 +258,9 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
debug_print((mem_type == MT_MEMORY) ? "MEM" :
((mem_type == MT_NON_CACHEABLE) ? "NC" : "DEV"));
- debug_print(attr & MT_RW ? "-RW" : "-RO");
- debug_print(attr & MT_NS ? "-NS" : "-S");
- debug_print(attr & MT_EXECUTE_NEVER ? "-XN" : "-EXEC");
+ debug_print(((attr & MT_RW) != 0U) ? "-RW" : "-RO");
+ debug_print(((attr & MT_NS) != 0U) ? "-NS" : "-S");
+ debug_print(((attr & MT_EXECUTE_NEVER) != 0U) ? "-XN" : "-EXEC");
return desc;
}
@@ -260,14 +270,14 @@ static uint64_t mmap_desc(unsigned int attr, unsigned long long addr_pa,
*
* On success, this function returns 0.
* If there are partial overlaps (meaning that a smaller size is needed) or if
- * the region can't be found in the given area, it returns -1. In this case the
- * value pointed by attr should be ignored by the caller.
+ * the region can't be found in the given area, it returns MT_UNKNOWN. In this
+ * case the value pointed by attr should be ignored by the caller.
*/
-static int mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
- size_t size, unsigned int *attr)
+static unsigned int mmap_region_attr(const mmap_region_t *mm, uintptr_t base_va,
+ size_t size, unsigned int *attr)
{
/* Don't assume that the area is contained in the first region */
- int ret = -1;
+ unsigned int ret = MT_UNKNOWN;
/*
* Get attributes from last (innermost) region that contains the
@@ -284,26 +294,26 @@ static int mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
* in region 2. The loop shouldn't stop at region 2 as inner regions
* have priority over outer regions, it should stop at region 5.
*/
- for (;; ++mm) {
+ for ( ; ; ++mm) {
- if (!mm->size)
+ if (mm->size == 0U)
return ret; /* Reached end of list */
- if (mm->base_va > base_va + size - 1)
+ if (mm->base_va > (base_va + size - 1U))
return ret; /* Next region is after area so end */
- if (mm->base_va + mm->size - 1 < base_va)
+ if ((mm->base_va + mm->size - 1U) < base_va)
continue; /* Next region has already been overtaken */
- if (!ret && mm->attr == *attr)
+ if ((ret == 0U) && (mm->attr == *attr))
continue; /* Region doesn't override attribs so skip */
- if (mm->base_va > base_va ||
- mm->base_va + mm->size - 1 < base_va + size - 1)
- return -1; /* Region doesn't fully cover our area */
+ if ((mm->base_va > base_va) ||
+ ((mm->base_va + mm->size - 1U) < (base_va + size - 1U)))
+ return MT_UNKNOWN; /* Region doesn't fully cover area */
*attr = mm->attr;
- ret = 0;
+ ret = 0U;
}
return ret;
}
@@ -313,7 +323,8 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
uint64_t *table,
unsigned int level)
{
- assert(level >= XLAT_TABLE_LEVEL_MIN && level <= XLAT_TABLE_LEVEL_MAX);
+ assert((level >= XLAT_TABLE_LEVEL_MIN) &&
+ (level <= XLAT_TABLE_LEVEL_MAX));
unsigned int level_size_shift =
L0_XLAT_ADDRESS_SHIFT - level * XLAT_TABLE_ENTRIES_SHIFT;
@@ -326,10 +337,10 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
do {
uint64_t desc = UNSET_DESC;
- if (!mm->size) {
+ if (mm->size == 0U) {
/* Done mapping regions; finish zeroing the table */
desc = INVALID_DESC;
- } else if (mm->base_va + mm->size - 1 < base_va) {
+ } else if ((mm->base_va + mm->size - 1U) < base_va) {
/* This area is after the region so get next region */
++mm;
continue;
@@ -338,7 +349,7 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
debug_print("%s VA:%p size:0x%llx ", get_level_spacer(level),
(void *)base_va, (unsigned long long)level_size);
- if (mm->base_va > base_va + level_size - 1) {
+ if (mm->base_va > (base_va + level_size - 1U)) {
/* Next region is after this area. Nothing to map yet */
desc = INVALID_DESC;
/* Make sure that the current level allows block descriptors */
@@ -349,9 +360,10 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
* it will return the innermost region's attributes.
*/
unsigned int attr;
- int r = mmap_region_attr(mm, base_va, level_size, &attr);
+ unsigned int r = mmap_region_attr(mm, base_va,
+ level_size, &attr);
- if (!r) {
+ if (r == 0U) {
desc = mmap_desc(attr,
base_va - mm->base_va + mm->base_pa,
level);
@@ -360,13 +372,15 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
if (desc == UNSET_DESC) {
/* Area not covered by a region so need finer table */
- uint64_t *new_table = xlat_tables[next_xlat++];
+ uint64_t *new_table = xlat_tables[next_xlat];
+
+ next_xlat++;
assert(next_xlat <= MAX_XLAT_TABLES);
desc = TABLE_DESC | (uintptr_t)new_table;
/* Recurse to fill in new table */
mm = init_xlation_table_inner(mm, base_va,
- new_table, level+1);
+ new_table, level + 1U);
}
debug_print("\n");
@@ -374,7 +388,7 @@ static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
*table++ = desc;
base_va += level_size;
} while ((base_va & level_index_mask) &&
- (base_va - 1 < PLAT_VIRT_ADDR_SPACE_SIZE - 1));
+ ((base_va - 1U) < (PLAT_VIRT_ADDR_SPACE_SIZE - 1U)));
return mm;
}
@@ -383,15 +397,15 @@ void init_xlation_table(uintptr_t base_va, uint64_t *table,
unsigned int level, uintptr_t *max_va,
unsigned long long *max_pa)
{
- int el = xlat_arch_current_el();
+ unsigned int el = xlat_arch_current_el();
execute_never_mask = xlat_arch_get_xn_desc(el);
- if (el == 3) {
+ if (el == 3U) {
ap1_mask = LOWER_ATTRS(AP_ONE_VA_RANGE_RES1);
} else {
- assert(el == 1);
- ap1_mask = 0;
+ assert(el == 1U);
+ ap1_mask = 0ULL;
}
init_xlation_table_inner(mmap, base_va, table, level);
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index 810c48e1a..f882f7efb 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_PRIVATE_H__
-#define __XLAT_TABLES_PRIVATE_H__
+#ifndef XLAT_TABLES_PRIVATE_H
+#define XLAT_TABLES_PRIVATE_H
#include <cassert.h>
#include <platform_def.h>
@@ -44,17 +44,17 @@ CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(PLAT_PHY_ADDR_SPACE_SIZE),
void print_mmap(void);
/* Returns the current Exception Level. The returned EL must be 1 or higher. */
-int xlat_arch_current_el(void);
+unsigned int xlat_arch_current_el(void);
/*
* Returns the bit mask that has to be ORed to the rest of a translation table
* descriptor so that execution of code is prohibited at the given Exception
* Level.
*/
-uint64_t xlat_arch_get_xn_desc(int el);
+uint64_t xlat_arch_get_xn_desc(unsigned int el);
void init_xlation_table(uintptr_t base_va, uint64_t *table,
unsigned int level, uintptr_t *max_va,
unsigned long long *max_pa);
-#endif /* __XLAT_TABLES_PRIVATE_H__ */
+#endif /* XLAT_TABLES_PRIVATE_H */
diff --git a/lib/xlat_tables_v2/aarch32/enable_mmu.S b/lib/xlat_tables_v2/aarch32/enable_mmu.S
index 97cdde751..4a4ac30f5 100644
--- a/lib/xlat_tables_v2/aarch32/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch32/enable_mmu.S
@@ -8,9 +8,11 @@
#include <assert_macros.S>
#include <xlat_tables_v2.h>
- .global enable_mmu_direct
+ .global enable_mmu_direct_svc_mon
+ .global enable_mmu_direct_hyp
-func enable_mmu_direct
+ /* void enable_mmu_direct_svc_mon(unsigned int flags) */
+func enable_mmu_direct_svc_mon
/* Assert that MMU is turned off */
#if ENABLE_ASSERTIONS
ldcopr r1, SCTLR
@@ -24,17 +26,17 @@ func enable_mmu_direct
mov r3, r0
ldr r0, =mmu_cfg_params
- /* MAIR0 */
- ldr r1, [r0, #(MMU_CFG_MAIR0 << 2)]
+ /* MAIR0. Only the lower 32 bits are used. */
+ ldr r1, [r0, #(MMU_CFG_MAIR << 3)]
stcopr r1, MAIR0
- /* TTBCR */
- ldr r2, [r0, #(MMU_CFG_TCR << 2)]
+ /* TTBCR. Only the lower 32 bits are used. */
+ ldr r2, [r0, #(MMU_CFG_TCR << 3)]
stcopr r2, TTBCR
/* TTBR0 */
- ldr r1, [r0, #(MMU_CFG_TTBR0_LO << 2)]
- ldr r2, [r0, #(MMU_CFG_TTBR0_HI << 2)]
+ ldr r1, [r0, #(MMU_CFG_TTBR0 << 3)]
+ ldr r2, [r0, #((MMU_CFG_TTBR0 << 3) + 4)]
stcopr16 r1, r2, TTBR0_64
/* TTBR1 is unused right now; set it to 0. */
@@ -63,4 +65,56 @@ func enable_mmu_direct
isb
bx lr
-endfunc enable_mmu_direct
+endfunc enable_mmu_direct_svc_mon
+
+
+ /* void enable_mmu_direct_hyp(unsigned int flags) */
+func enable_mmu_direct_hyp
+ /* Assert that MMU is turned off */
+#if ENABLE_ASSERTIONS
+ ldcopr r1, HSCTLR
+ tst r1, #HSCTLR_M_BIT
+ ASM_ASSERT(eq)
+#endif
+
+ /* Invalidate TLB entries */
+ TLB_INVALIDATE(r0, TLBIALL)
+
+ mov r3, r0
+ ldr r0, =mmu_cfg_params
+
+ /* HMAIR0 */
+ ldr r1, [r0, #(MMU_CFG_MAIR << 3)]
+ stcopr r1, HMAIR0
+
+ /* HTCR */
+ ldr r2, [r0, #(MMU_CFG_TCR << 3)]
+ stcopr r2, HTCR
+
+ /* HTTBR */
+ ldr r1, [r0, #(MMU_CFG_TTBR0 << 3)]
+ ldr r2, [r0, #((MMU_CFG_TTBR0 << 3) + 4)]
+ stcopr16 r1, r2, HTTBR_64
+
+ /*
+ * Ensure all translation table writes have drained into memory, the TLB
+ * invalidation is complete, and translation register writes are
+ * committed before enabling the MMU
+ */
+ dsb ish
+ isb
+
+ /* Enable enable MMU by honoring flags */
+ ldcopr r1, HSCTLR
+ ldr r2, =(HSCTLR_WXN_BIT | HSCTLR_C_BIT | HSCTLR_M_BIT)
+ orr r1, r1, r2
+
+ /* Clear C bit if requested */
+ tst r3, #DISABLE_DCACHE
+ bicne r1, r1, #HSCTLR_C_BIT
+
+ stcopr r1, HSCTLR
+ isb
+
+ bx lr
+endfunc enable_mmu_direct_hyp
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
index 6e9719258..66938e5f1 100644
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c
@@ -9,32 +9,30 @@
#include <assert.h>
#include <cassert.h>
#include <platform_def.h>
-#include <utils.h>
+#include <stdbool.h>
#include <utils_def.h>
#include <xlat_tables_v2.h>
#include "../xlat_tables_private.h"
-#if ARM_ARCH_MAJOR == 7 && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
+#if (ARM_ARCH_MAJOR == 7) && !defined(ARMV7_SUPPORTS_LARGE_PAGE_ADDRESSING)
#error ARMv7 target does not support LPAE MMU descriptors
#endif
-uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/*
- * Returns 1 if the provided granule size is supported, 0 otherwise.
+ * Returns true if the provided granule size is supported, false otherwise.
*/
-int xlat_arch_is_granule_size_supported(size_t size)
+bool xlat_arch_is_granule_size_supported(size_t size)
{
/*
- * The Trusted Firmware uses long descriptor translation table format,
- * which supports 4 KiB pages only.
+ * The library uses the long descriptor translation table format, which
+ * supports 4 KiB pages only.
*/
- return (size == (4U * 1024U));
+ return size == PAGE_SIZE_4KB;
}
size_t xlat_arch_get_max_supported_granule_size(void)
{
- return 4U * 1024U;
+ return PAGE_SIZE_4KB;
}
#if ENABLE_ASSERTIONS
@@ -45,23 +43,38 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
}
#endif /* ENABLE_ASSERTIONS*/
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused)
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
{
- return (read_sctlr() & SCTLR_M_BIT) != 0;
+ if (ctx->xlat_regime == EL1_EL0_REGIME) {
+ assert(xlat_arch_current_el() == 1U);
+ return (read_sctlr() & SCTLR_M_BIT) != 0U;
+ } else {
+ assert(ctx->xlat_regime == EL2_REGIME);
+ assert(xlat_arch_current_el() == 2U);
+ return (read_hsctlr() & HSCTLR_M_BIT) != 0U;
+ }
}
-void xlat_arch_tlbi_va(uintptr_t va)
+bool is_dcache_enabled(void)
{
- /*
- * Ensure the translation table write has drained into memory before
- * invalidating the TLB entry.
- */
- dsbishst();
+ if (IS_IN_EL2()) {
+ return (read_hsctlr() & HSCTLR_C_BIT) != 0U;
+ } else {
+ return (read_sctlr() & SCTLR_C_BIT) != 0U;
+ }
+}
- tlbimvaais(TLBI_ADDR(va));
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime)
+{
+ if (xlat_regime == EL1_EL0_REGIME) {
+ return UPPER_ATTRS(XN) | UPPER_ATTRS(PXN);
+ } else {
+ assert(xlat_regime == EL2_REGIME);
+ return UPPER_ATTRS(XN);
+ }
}
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime __unused)
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime)
{
/*
* Ensure the translation table write has drained into memory before
@@ -69,7 +82,12 @@ void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime __unused)
*/
dsbishst();
- tlbimvaais(TLBI_ADDR(va));
+ if (xlat_regime == EL1_EL0_REGIME) {
+ tlbimvaais(TLBI_ADDR(va));
+ } else {
+ assert(xlat_regime == EL2_REGIME);
+ tlbimvahis(TLBI_ADDR(va));
+ }
}
void xlat_arch_tlbi_va_sync(void)
@@ -98,49 +116,70 @@ void xlat_arch_tlbi_va_sync(void)
isb();
}
-int xlat_arch_current_el(void)
+unsigned int xlat_arch_current_el(void)
{
- /*
- * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System,
- * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3.
- */
- return 3;
+ if (IS_IN_HYP()) {
+ return 2U;
+ } else {
+ assert(IS_IN_SVC() || IS_IN_MON());
+ /*
+ * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor,
+ * System, SVC, Abort, UND, IRQ and FIQ modes) execute at EL3.
+ *
+ * The PL1&0 translation regime in AArch32 behaves like the
+ * EL1&0 regime in AArch64 except for the XN bits, but we set
+ * and unset them at the same time, so there's no difference in
+ * practice.
+ */
+ return 1U;
+ }
}
/*******************************************************************************
- * Function for enabling the MMU in Secure PL1, assuming that the page tables
+ * Function for enabling the MMU in PL1 or PL2, assuming that the page tables
* have already been created.
******************************************************************************/
-void setup_mmu_cfg(unsigned int flags,
- const uint64_t *base_table,
- unsigned long long max_pa,
- uintptr_t max_va)
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, __unused int xlat_regime)
{
- u_register_t mair0, ttbcr;
- uint64_t ttbr0;
-
- assert(IS_IN_SECURE());
+ uint64_t mair, ttbr0;
+ uint32_t ttbcr;
/* Set attributes in the right indices of the MAIR */
- mair0 = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
- mair0 |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
+ mair = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX);
+ mair |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR,
ATTR_IWBWA_OWBWA_NTR_INDEX);
- mair0 |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
+ mair |= MAIR0_ATTR_SET(ATTR_NON_CACHEABLE,
ATTR_NON_CACHEABLE_INDEX);
/*
- * Configure the control register for stage 1 of the PL1&0 translation
- * regime.
+ * Configure the control register for stage 1 of the PL1&0 or EL2
+ * translation regimes.
*/
/* Use the Long-descriptor translation table format. */
ttbcr = TTBCR_EAE_BIT;
- /*
- * Disable translation table walk for addresses that are translated
- * using TTBR1. Therefore, only TTBR0 is used.
- */
- ttbcr |= TTBCR_EPD1_BIT;
+ if (xlat_regime == EL1_EL0_REGIME) {
+ assert(IS_IN_SVC() || IS_IN_MON());
+ /*
+ * Disable translation table walk for addresses that are
+ * translated using TTBR1. Therefore, only TTBR0 is used.
+ */
+ ttbcr |= TTBCR_EPD1_BIT;
+ } else {
+ assert(xlat_regime == EL2_REGIME);
+ assert(IS_IN_HYP());
+
+ /*
+ * Set HTCR bits as well. Set HTTBR table properties
+ * as Inner & outer WBWA & shareable.
+ */
+ ttbcr |= HTCR_RES1 |
+ HTCR_SH0_INNER_SHAREABLE | HTCR_RGN0_OUTER_WBA |
+ HTCR_RGN0_INNER_WBA;
+ }
/*
* Limit the input address ranges and memory region sizes translated
@@ -148,20 +187,23 @@ void setup_mmu_cfg(unsigned int flags,
* 32 bits.
*/
if (max_va != UINT32_MAX) {
- uintptr_t virtual_addr_space_size = max_va + 1;
+ uintptr_t virtual_addr_space_size = max_va + 1U;
+
assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed
* that virtual_addr_space_size is in the range [1, UINT32_MAX].
*/
- ttbcr |= 32 - __builtin_ctzll(virtual_addr_space_size);
+ int t0sz = 32 - __builtin_ctzll(virtual_addr_space_size);
+
+ ttbcr |= (uint32_t) t0sz;
}
/*
* Set the cacheability and shareability attributes for memory
* associated with translation table walks using TTBR0.
*/
- if (flags & XLAT_TABLE_NC) {
+ if ((flags & XLAT_TABLE_NC) != 0U) {
/* Inner & outer non-cacheable non-shareable. */
ttbcr |= TTBCR_SH0_NON_SHAREABLE | TTBCR_RGN0_OUTER_NC |
TTBCR_RGN0_INNER_NC;
@@ -173,17 +215,17 @@ void setup_mmu_cfg(unsigned int flags,
/* Set TTBR0 bits as well */
ttbr0 = (uint64_t)(uintptr_t) base_table;
+
#if ARM_ARCH_AT_LEAST(8, 2)
/*
- * Enable CnP bit so as to share page tables with all PEs.
- * Mandatory for ARMv8.2 implementations.
+ * Enable CnP bit so as to share page tables with all PEs. This
+ * is mandatory for ARMv8.2 implementations.
*/
ttbr0 |= TTBR_CNP_BIT;
#endif
/* Now populate MMU configuration */
- mmu_cfg_params[MMU_CFG_MAIR0] = mair0;
- mmu_cfg_params[MMU_CFG_TCR] = ttbcr;
- mmu_cfg_params[MMU_CFG_TTBR0_LO] = (uint32_t) ttbr0;
- mmu_cfg_params[MMU_CFG_TTBR0_HI] = ttbr0 >> 32;
+ params[MMU_CFG_MAIR] = mair;
+ params[MMU_CFG_TCR] = (uint64_t) ttbcr;
+ params[MMU_CFG_TTBR0] = ttbr0;
}
diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h b/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h
deleted file mode 100644
index 9b41f4df2..000000000
--- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch_private.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_PRIVATE_H__
-#define __XLAT_TABLES_ARCH_PRIVATE_H__
-
-#include <xlat_tables_defs.h>
-#include <xlat_tables_v2.h>
-
-/*
- * Return the execute-never mask that will prevent instruction fetch at the
- * given translation regime.
- */
-static inline uint64_t xlat_arch_regime_get_xn_desc(int regime __unused)
-{
- return UPPER_ATTRS(XN);
-}
-
-#endif /* __XLAT_TABLES_ARCH_PRIVATE_H__ */
diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S
index a72c7fae5..21717d28a 100644
--- a/lib/xlat_tables_v2/aarch64/enable_mmu.S
+++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S
@@ -9,6 +9,7 @@
#include <xlat_tables_v2.h>
.global enable_mmu_direct_el1
+ .global enable_mmu_direct_el2
.global enable_mmu_direct_el3
/* Macros to read and write to system register for a given EL. */
@@ -20,6 +21,19 @@
mrs \gp_reg, \reg_name\()_el\()\el
.endm
+ .macro tlbi_invalidate_all el
+ .if \el == 1
+ TLB_INVALIDATE(vmalle1)
+ .elseif \el == 2
+ TLB_INVALIDATE(alle2)
+ .elseif \el == 3
+ TLB_INVALIDATE(alle3)
+ .else
+ .error "EL must be 1, 2 or 3"
+ .endif
+ .endm
+
+ /* void enable_mmu_direct_el<x>(unsigned int flags) */
.macro define_mmu_enable_func el
func enable_mmu_direct_\()el\el
#if ENABLE_ASSERTIONS
@@ -27,33 +41,22 @@
tst x1, #SCTLR_M_BIT
ASM_ASSERT(eq)
#endif
-
- /* Invalidate TLB entries */
- .if \el == 1
- TLB_INVALIDATE(vmalle1)
- .else
- .if \el == 3
- TLB_INVALIDATE(alle3)
- .else
- .error "EL must be 1 or 3"
- .endif
- .endif
+ /* Invalidate all TLB entries */
+ tlbi_invalidate_all \el
mov x7, x0
ldr x0, =mmu_cfg_params
/* MAIR */
- ldr w1, [x0, #(MMU_CFG_MAIR0 << 2)]
+ ldr x1, [x0, #(MMU_CFG_MAIR << 3)]
_msr mair, \el, x1
/* TCR */
- ldr w2, [x0, #(MMU_CFG_TCR << 2)]
+ ldr x2, [x0, #(MMU_CFG_TCR << 3)]
_msr tcr, \el, x2
/* TTBR */
- ldr w3, [x0, #(MMU_CFG_TTBR0_LO << 2)]
- ldr w4, [x0, #(MMU_CFG_TTBR0_HI << 2)]
- orr x3, x3, x4, lsl #32
+ ldr x3, [x0, #(MMU_CFG_TTBR0 << 3)]
_msr ttbr0, \el, x3
/*
@@ -88,4 +91,5 @@
* enable_mmu_direct_el3
*/
define_mmu_enable_func 1
+ define_mmu_enable_func 2
define_mmu_enable_func 3
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
index 4bbbe5443..269adc7ef 100644
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
+++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c
@@ -8,72 +8,71 @@
#include <arch_helpers.h>
#include <assert.h>
#include <cassert.h>
-#include <sys/types.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <utils_def.h>
#include <xlat_tables_v2.h>
#include "../xlat_tables_private.h"
-uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
/*
- * Returns 1 if the provided granule size is supported, 0 otherwise.
+ * Returns true if the provided granule size is supported, false otherwise.
*/
-int xlat_arch_is_granule_size_supported(size_t size)
+bool xlat_arch_is_granule_size_supported(size_t size)
{
u_register_t id_aa64mmfr0_el1 = read_id_aa64mmfr0_el1();
- if (size == (4U * 1024U)) {
+ if (size == PAGE_SIZE_4KB) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN4_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN4_MASK) ==
ID_AA64MMFR0_EL1_TGRAN4_SUPPORTED;
- } else if (size == (16U * 1024U)) {
+ } else if (size == PAGE_SIZE_16KB) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN16_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN16_MASK) ==
ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED;
- } else if (size == (64U * 1024U)) {
+ } else if (size == PAGE_SIZE_64KB) {
return ((id_aa64mmfr0_el1 >> ID_AA64MMFR0_EL1_TGRAN64_SHIFT) &
ID_AA64MMFR0_EL1_TGRAN64_MASK) ==
ID_AA64MMFR0_EL1_TGRAN64_SUPPORTED;
+ } else {
+ return 0;
}
-
- return 0;
}
size_t xlat_arch_get_max_supported_granule_size(void)
{
- if (xlat_arch_is_granule_size_supported(64U * 1024U)) {
- return 64U * 1024U;
- } else if (xlat_arch_is_granule_size_supported(16U * 1024U)) {
- return 16U * 1024U;
+ if (xlat_arch_is_granule_size_supported(PAGE_SIZE_64KB)) {
+ return PAGE_SIZE_64KB;
+ } else if (xlat_arch_is_granule_size_supported(PAGE_SIZE_16KB)) {
+ return PAGE_SIZE_16KB;
} else {
- assert(xlat_arch_is_granule_size_supported(4U * 1024U));
- return 4U * 1024U;
+ assert(xlat_arch_is_granule_size_supported(PAGE_SIZE_4KB));
+ return PAGE_SIZE_4KB;
}
}
unsigned long long tcr_physical_addr_size_bits(unsigned long long max_addr)
{
/* Physical address can't exceed 48 bits */
- assert((max_addr & ADDR_MASK_48_TO_63) == 0);
+ assert((max_addr & ADDR_MASK_48_TO_63) == 0U);
/* 48 bits address */
- if (max_addr & ADDR_MASK_44_TO_47)
+ if ((max_addr & ADDR_MASK_44_TO_47) != 0U)
return TCR_PS_BITS_256TB;
/* 44 bits address */
- if (max_addr & ADDR_MASK_42_TO_43)
+ if ((max_addr & ADDR_MASK_42_TO_43) != 0U)
return TCR_PS_BITS_16TB;
/* 42 bits address */
- if (max_addr & ADDR_MASK_40_TO_41)
+ if ((max_addr & ADDR_MASK_40_TO_41) != 0U)
return TCR_PS_BITS_4TB;
/* 40 bits address */
- if (max_addr & ADDR_MASK_36_TO_39)
+ if ((max_addr & ADDR_MASK_36_TO_39) != 0U)
return TCR_PS_BITS_1TB;
/* 36 bits address */
- if (max_addr & ADDR_MASK_32_TO_35)
+ if ((max_addr & ADDR_MASK_32_TO_35) != 0U)
return TCR_PS_BITS_64GB;
return TCR_PS_BITS_4GB;
@@ -101,31 +100,46 @@ unsigned long long xlat_arch_get_max_supported_pa(void)
}
#endif /* ENABLE_ASSERTIONS*/
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx)
{
if (ctx->xlat_regime == EL1_EL0_REGIME) {
- assert(xlat_arch_current_el() >= 1);
- return (read_sctlr_el1() & SCTLR_M_BIT) != 0;
+ assert(xlat_arch_current_el() >= 1U);
+ return (read_sctlr_el1() & SCTLR_M_BIT) != 0U;
+ } else if (ctx->xlat_regime == EL2_REGIME) {
+ assert(xlat_arch_current_el() >= 2U);
+ return (read_sctlr_el2() & SCTLR_M_BIT) != 0U;
} else {
assert(ctx->xlat_regime == EL3_REGIME);
- assert(xlat_arch_current_el() >= 3);
- return (read_sctlr_el3() & SCTLR_M_BIT) != 0;
+ assert(xlat_arch_current_el() >= 3U);
+ return (read_sctlr_el3() & SCTLR_M_BIT) != 0U;
}
}
+bool is_dcache_enabled(void)
+{
+ unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
+
+ if (el == 1U) {
+ return (read_sctlr_el1() & SCTLR_C_BIT) != 0U;
+ } else if (el == 2U) {
+ return (read_sctlr_el2() & SCTLR_C_BIT) != 0U;
+ } else {
+ return (read_sctlr_el3() & SCTLR_C_BIT) != 0U;
+ }
+}
-void xlat_arch_tlbi_va(uintptr_t va)
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime)
{
-#if IMAGE_EL == 1
- assert(IS_IN_EL(1));
- xlat_arch_tlbi_va_regime(va, EL1_EL0_REGIME);
-#elif IMAGE_EL == 3
- assert(IS_IN_EL(3));
- xlat_arch_tlbi_va_regime(va, EL3_REGIME);
-#endif
+ if (xlat_regime == EL1_EL0_REGIME) {
+ return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN);
+ } else {
+ assert((xlat_regime == EL2_REGIME) ||
+ (xlat_regime == EL3_REGIME));
+ return UPPER_ATTRS(XN);
+ }
}
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime)
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime)
{
/*
* Ensure the translation table write has drained into memory before
@@ -141,11 +155,14 @@ void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime)
* exception level (see section D4.9.2 of the ARM ARM rev B.a).
*/
if (xlat_regime == EL1_EL0_REGIME) {
- assert(xlat_arch_current_el() >= 1);
+ assert(xlat_arch_current_el() >= 1U);
tlbivaae1is(TLBI_ADDR(va));
+ } else if (xlat_regime == EL2_REGIME) {
+ assert(xlat_arch_current_el() >= 2U);
+ tlbivae2is(TLBI_ADDR(va));
} else {
assert(xlat_regime == EL3_REGIME);
- assert(xlat_arch_current_el() >= 3);
+ assert(xlat_arch_current_el() >= 3U);
tlbivae3is(TLBI_ADDR(va));
}
}
@@ -173,21 +190,20 @@ void xlat_arch_tlbi_va_sync(void)
isb();
}
-int xlat_arch_current_el(void)
+unsigned int xlat_arch_current_el(void)
{
- int el = GET_EL(read_CurrentEl());
+ unsigned int el = (unsigned int)GET_EL(read_CurrentEl());
- assert(el > 0);
+ assert(el > 0U);
return el;
}
-void setup_mmu_cfg(unsigned int flags,
- const uint64_t *base_table,
- unsigned long long max_pa,
- uintptr_t max_va)
+void setup_mmu_cfg(uint64_t *params, unsigned int flags,
+ const uint64_t *base_table, unsigned long long max_pa,
+ uintptr_t max_va, int xlat_regime)
{
- uint64_t mair, ttbr, tcr;
+ uint64_t mair, ttbr0, tcr;
uintptr_t virtual_addr_space_size;
/* Set attributes in the right indices of the MAIR. */
@@ -195,28 +211,28 @@ void setup_mmu_cfg(unsigned int flags,
mair |= MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX);
mair |= MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
- ttbr = (uint64_t) base_table;
-
/*
* Limit the input address ranges and memory region sizes translated
* using TTBR0 to the given virtual address space size.
*/
- assert(max_va < ((uint64_t) UINTPTR_MAX));
+ assert(max_va < ((uint64_t)UINTPTR_MAX));
- virtual_addr_space_size = max_va + 1;
+ virtual_addr_space_size = (uintptr_t)max_va + 1U;
assert(CHECK_VIRT_ADDR_SPACE_SIZE(virtual_addr_space_size));
/*
* __builtin_ctzll(0) is undefined but here we are guaranteed that
* virtual_addr_space_size is in the range [1,UINTPTR_MAX].
*/
- tcr = (uint64_t) 64 - __builtin_ctzll(virtual_addr_space_size);
+ int t0sz = 64 - __builtin_ctzll(virtual_addr_space_size);
+
+ tcr = (uint64_t) t0sz;
/*
* Set the cacheability and shareability attributes for memory
* associated with translation table walks.
*/
- if ((flags & XLAT_TABLE_NC) != 0) {
+ if ((flags & XLAT_TABLE_NC) != 0U) {
/* Inner & outer non-cacheable non-shareable. */
tcr |= TCR_SH_NON_SHAREABLE |
TCR_RGN_OUTER_NC | TCR_RGN_INNER_NC;
@@ -232,30 +248,31 @@ void setup_mmu_cfg(unsigned int flags,
*/
unsigned long long tcr_ps_bits = tcr_physical_addr_size_bits(max_pa);
-#if IMAGE_EL == 1
- assert(IS_IN_EL(1));
- /*
- * TCR_EL1.EPD1: Disable translation table walk for addresses that are
- * translated using TTBR1_EL1.
- */
- tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT);
-#elif IMAGE_EL == 3
- assert(IS_IN_EL(3));
- tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
-#endif
-
- mmu_cfg_params[MMU_CFG_MAIR0] = (uint32_t) mair;
- mmu_cfg_params[MMU_CFG_TCR] = (uint32_t) tcr;
-
- /* Set TTBR bits as well */
- if (ARM_ARCH_AT_LEAST(8, 2)) {
+ if (xlat_regime == EL1_EL0_REGIME) {
/*
- * Enable CnP bit so as to share page tables with all PEs. This
- * is mandatory for ARMv8.2 implementations.
+ * TCR_EL1.EPD1: Disable translation table walk for addresses
+ * that are translated using TTBR1_EL1.
*/
- ttbr |= TTBR_CNP_BIT;
+ tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT);
+ } else if (xlat_regime == EL2_REGIME) {
+ tcr |= TCR_EL2_RES1 | (tcr_ps_bits << TCR_EL2_PS_SHIFT);
+ } else {
+ assert(xlat_regime == EL3_REGIME);
+ tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT);
}
- mmu_cfg_params[MMU_CFG_TTBR0_LO] = (uint32_t) ttbr;
- mmu_cfg_params[MMU_CFG_TTBR0_HI] = (uint32_t) (ttbr >> 32);
+ /* Set TTBR bits as well */
+ ttbr0 = (uint64_t) base_table;
+
+#if ARM_ARCH_AT_LEAST(8, 2)
+ /*
+ * Enable CnP bit so as to share page tables with all PEs. This
+ * is mandatory for ARMv8.2 implementations.
+ */
+ ttbr0 |= TTBR_CNP_BIT;
+#endif
+
+ params[MMU_CFG_MAIR] = mair;
+ params[MMU_CFG_TCR] = tcr;
+ params[MMU_CFG_TTBR0] = ttbr0;
}
diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h b/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h
deleted file mode 100644
index 39b0a653a..000000000
--- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch_private.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __XLAT_TABLES_ARCH_PRIVATE_H__
-#define __XLAT_TABLES_ARCH_PRIVATE_H__
-
-#include <assert.h>
-#include <xlat_tables_defs.h>
-#include <xlat_tables_v2.h>
-
-/*
- * Return the execute-never mask that will prevent instruction fetch at all ELs
- * that are part of the given translation regime.
- */
-static inline uint64_t xlat_arch_regime_get_xn_desc(int regime)
-{
- if (regime == EL1_EL0_REGIME) {
- return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN);
- } else {
- assert(regime == EL3_REGIME);
- return UPPER_ATTRS(XN);
- }
-}
-
-#endif /* __XLAT_TABLES_ARCH_PRIVATE_H__ */
diff --git a/lib/xlat_tables_v2/xlat_tables.mk b/lib/xlat_tables_v2/xlat_tables.mk
index b25c805cf..9507ad715 100644
--- a/lib/xlat_tables_v2/xlat_tables.mk
+++ b/lib/xlat_tables_v2/xlat_tables.mk
@@ -10,5 +10,3 @@ XLAT_TABLES_LIB_SRCS := $(addprefix lib/xlat_tables_v2/, \
xlat_tables_context.c \
xlat_tables_core.c \
xlat_tables_utils.c)
-
-INCLUDES += -Ilib/xlat_tables_v2/${ARCH}
diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c
index 0964b49b2..bf0cc9f5d 100644
--- a/lib/xlat_tables_v2/xlat_tables_context.c
+++ b/lib/xlat_tables_v2/xlat_tables_context.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <debug.h>
#include <platform_def.h>
#include <xlat_tables_defs.h>
@@ -12,6 +13,12 @@
#include "xlat_tables_private.h"
/*
+ * MMU configuration register values for the active translation context. Used
+ * from the MMU assembly helpers.
+ */
+uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+/*
* Each platform can define the size of its physical and virtual address spaces.
* If the platform hasn't defined one or both of them, default to
* ADDR_SPACE_SIZE. The latter is deprecated, though.
@@ -69,9 +76,32 @@ int mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
void init_xlat_tables(void)
{
+ assert(tf_xlat_ctx.xlat_regime == EL_REGIME_INVALID);
+
+ unsigned int current_el = xlat_arch_current_el();
+
+ if (current_el == 1U) {
+ tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME;
+ } else if (current_el == 2U) {
+ tf_xlat_ctx.xlat_regime = EL2_REGIME;
+ } else {
+ assert(current_el == 3U);
+ tf_xlat_ctx.xlat_regime = EL3_REGIME;
+ }
+
init_xlat_tables_ctx(&tf_xlat_ctx);
}
+int xlat_get_mem_attributes(uintptr_t base_va, uint32_t *attr)
+{
+ return xlat_get_mem_attributes_ctx(&tf_xlat_ctx, base_va, attr);
+}
+
+int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr)
+{
+ return xlat_change_mem_attributes_ctx(&tf_xlat_ctx, base_va, size, attr);
+}
+
/*
* If dynamic allocation of new regions is disabled then by the time we call the
* function enabling the MMU, we'll have registered all the memory regions to
@@ -91,26 +121,57 @@ void init_xlat_tables(void)
#ifdef AARCH32
+#if !ERROR_DEPRECATED
void enable_mmu_secure(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
- enable_mmu_direct(flags);
+ enable_mmu_svc_mon(flags);
+}
+
+void enable_mmu_direct(unsigned int flags)
+{
+ enable_mmu_direct_svc_mon(flags);
+}
+#endif
+
+void enable_mmu_svc_mon(unsigned int flags)
+{
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL1_EL0_REGIME);
+ enable_mmu_direct_svc_mon(flags);
+}
+
+void enable_mmu_hyp(unsigned int flags)
+{
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL2_REGIME);
+ enable_mmu_direct_hyp(flags);
}
#else
void enable_mmu_el1(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL1_EL0_REGIME);
enable_mmu_direct_el1(flags);
}
+void enable_mmu_el2(unsigned int flags)
+{
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL2_REGIME);
+ enable_mmu_direct_el2(flags);
+}
+
void enable_mmu_el3(unsigned int flags)
{
- setup_mmu_cfg(flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
- tf_xlat_ctx.va_max_address);
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags,
+ tf_xlat_ctx.base_table, MAX_PHYS_ADDR,
+ tf_xlat_ctx.va_max_address, EL3_REGIME);
enable_mmu_direct_el3(flags);
}
diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c
index f555524a9..003718e76 100644
--- a/lib/xlat_tables_v2/xlat_tables_core.c
+++ b/lib/xlat_tables_v2/xlat_tables_core.c
@@ -9,15 +9,22 @@
#include <debug.h>
#include <errno.h>
#include <platform_def.h>
+#include <stdbool.h>
+#include <stdint.h>
#include <string.h>
-#include <types.h>
#include <utils_def.h>
-#include <xlat_tables_arch_private.h>
#include <xlat_tables_defs.h>
#include <xlat_tables_v2.h>
#include "xlat_tables_private.h"
+/* Helper function that cleans the data cache only if it is enabled. */
+static inline void xlat_clean_dcache_range(uintptr_t addr, size_t size)
+{
+ if (is_dcache_enabled())
+ clean_dcache_range(addr, size);
+}
+
#if PLAT_XLAT_TABLES_DYNAMIC
/*
@@ -30,9 +37,9 @@
* Returns the index of the array corresponding to the specified translation
* table.
*/
-static int xlat_table_get_index(xlat_ctx_t *ctx, const uint64_t *table)
+static int xlat_table_get_index(const xlat_ctx_t *ctx, const uint64_t *table)
{
- for (unsigned int i = 0; i < ctx->tables_num; i++)
+ for (int i = 0; i < ctx->tables_num; i++)
if (ctx->tables[i] == table)
return i;
@@ -40,15 +47,15 @@ static int xlat_table_get_index(xlat_ctx_t *ctx, const uint64_t *table)
* Maybe we were asked to get the index of the base level table, which
* should never happen.
*/
- assert(0);
+ assert(false);
return -1;
}
/* Returns a pointer to an empty translation table. */
-static uint64_t *xlat_table_get_empty(xlat_ctx_t *ctx)
+static uint64_t *xlat_table_get_empty(const xlat_ctx_t *ctx)
{
- for (unsigned int i = 0; i < ctx->tables_num; i++)
+ for (int i = 0; i < ctx->tables_num; i++)
if (ctx->tables_mapped_regions[i] == 0)
return ctx->tables[i];
@@ -56,21 +63,27 @@ static uint64_t *xlat_table_get_empty(xlat_ctx_t *ctx)
}
/* Increments region count for a given table. */
-static void xlat_table_inc_regions_count(xlat_ctx_t *ctx, const uint64_t *table)
+static void xlat_table_inc_regions_count(const xlat_ctx_t *ctx,
+ const uint64_t *table)
{
- ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)]++;
+ int idx = xlat_table_get_index(ctx, table);
+
+ ctx->tables_mapped_regions[idx]++;
}
/* Decrements region count for a given table. */
-static void xlat_table_dec_regions_count(xlat_ctx_t *ctx, const uint64_t *table)
+static void xlat_table_dec_regions_count(const xlat_ctx_t *ctx,
+ const uint64_t *table)
{
- ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)]--;
+ int idx = xlat_table_get_index(ctx, table);
+
+ ctx->tables_mapped_regions[idx]--;
}
/* Returns 0 if the specified table isn't empty, otherwise 1. */
-static int xlat_table_is_empty(xlat_ctx_t *ctx, const uint64_t *table)
+static bool xlat_table_is_empty(const xlat_ctx_t *ctx, const uint64_t *table)
{
- return !ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)];
+ return ctx->tables_mapped_regions[xlat_table_get_index(ctx, table)] == 0;
}
#else /* PLAT_XLAT_TABLES_DYNAMIC */
@@ -89,13 +102,13 @@ static uint64_t *xlat_table_get_empty(xlat_ctx_t *ctx)
* Returns a block/page table descriptor for the given level and attributes.
*/
uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
- unsigned long long addr_pa, int level)
+ unsigned long long addr_pa, unsigned int level)
{
uint64_t desc;
- int mem_type;
+ uint32_t mem_type;
/* Make sure that the granularity is fine enough to map this address. */
- assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0);
+ assert((addr_pa & XLAT_BLOCK_MASK(level)) == 0U);
desc = addr_pa;
/*
@@ -104,14 +117,16 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
*/
desc |= (level == XLAT_TABLE_LEVEL_MAX) ? PAGE_DESC : BLOCK_DESC;
/*
- * Always set the access flag, as TF doesn't manage access flag faults.
+ * Always set the access flag, as this library assumes access flag
+ * faults aren't managed.
+ */
+ desc |= LOWER_ATTRS(ACCESS_FLAG);
+ /*
* Deduce other fields of the descriptor based on the MT_NS and MT_RW
* memory region attributes.
*/
- desc |= LOWER_ATTRS(ACCESS_FLAG);
-
- desc |= (attr & MT_NS) ? LOWER_ATTRS(NS) : 0;
- desc |= (attr & MT_RW) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
+ desc |= ((attr & MT_NS) != 0U) ? LOWER_ATTRS(NS) : 0U;
+ desc |= ((attr & MT_RW) != 0U) ? LOWER_ATTRS(AP_RW) : LOWER_ATTRS(AP_RO);
/*
* Do not allow unprivileged access when the mapping is for a privileged
@@ -119,7 +134,7 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
* lower exception levels, set AP[2] to AP_NO_ACCESS_UNPRIVILEGED.
*/
if (ctx->xlat_regime == EL1_EL0_REGIME) {
- if (attr & MT_USER) {
+ if ((attr & MT_USER) != 0U) {
/* EL0 mapping requested, so we give User access */
desc |= LOWER_ATTRS(AP_ACCESS_UNPRIVILEGED);
} else {
@@ -127,7 +142,8 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
desc |= LOWER_ATTRS(AP_NO_ACCESS_UNPRIVILEGED);
}
} else {
- assert(ctx->xlat_regime == EL3_REGIME);
+ assert((ctx->xlat_regime == EL2_REGIME) ||
+ (ctx->xlat_regime == EL3_REGIME));
desc |= LOWER_ATTRS(AP_ONE_VA_RANGE_RES1);
}
@@ -155,9 +171,10 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
} else { /* Normal memory */
/*
* Always map read-write normal memory as execute-never.
- * (Trusted Firmware doesn't self-modify its code, therefore
- * R/W memory is reserved for data storage, which must not be
- * executable.)
+ * This library assumes that it is used by software that does
+ * not self-modify its code, therefore R/W memory is reserved
+ * for data storage, which must not be executable.
+ *
* Note that setting the XN bit here is for consistency only.
* The function that enables the MMU sets the SCTLR_ELx.WXN bit,
* which makes any writable memory region to be treated as
@@ -170,7 +187,7 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
* translation regime and the policy applied in
* xlat_arch_regime_get_xn_desc().
*/
- if ((attr & MT_RW) || (attr & MT_EXECUTE_NEVER)) {
+ if (((attr & MT_RW) != 0U) || ((attr & MT_EXECUTE_NEVER) != 0U)) {
desc |= xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
}
@@ -221,10 +238,10 @@ typedef enum {
static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
const uintptr_t table_base_va,
uint64_t *const table_base,
- const int table_entries,
+ const unsigned int table_entries,
const unsigned int level)
{
- assert(level >= ctx->base_level && level <= XLAT_TABLE_LEVEL_MAX);
+ assert((level >= ctx->base_level) && (level <= XLAT_TABLE_LEVEL_MAX));
uint64_t *subtable;
uint64_t desc;
@@ -232,16 +249,16 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
uintptr_t table_idx_va;
uintptr_t table_idx_end_va; /* End VA of this entry */
- uintptr_t region_end_va = mm->base_va + mm->size - 1;
+ uintptr_t region_end_va = mm->base_va + mm->size - 1U;
- int table_idx;
+ unsigned int table_idx;
if (mm->base_va > table_base_va) {
/* Find the first index of the table affected by the region. */
table_idx_va = mm->base_va & ~XLAT_BLOCK_MASK(level);
- table_idx = (table_idx_va - table_base_va) >>
- XLAT_ADDR_SHIFT(level);
+ table_idx = (unsigned int)((table_idx_va - table_base_va) >>
+ XLAT_ADDR_SHIFT(level));
assert(table_idx < table_entries);
} else {
@@ -252,19 +269,18 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
while (table_idx < table_entries) {
- table_idx_end_va = table_idx_va + XLAT_BLOCK_SIZE(level) - 1;
+ table_idx_end_va = table_idx_va + XLAT_BLOCK_SIZE(level) - 1U;
desc = table_base[table_idx];
uint64_t desc_type = desc & DESC_MASK;
- action_t action = ACTION_NONE;
+ action_t action;
if ((mm->base_va <= table_idx_va) &&
(region_end_va >= table_idx_end_va)) {
-
/* Region covers all block */
- if (level == 3) {
+ if (level == 3U) {
/*
* Last level, only page descriptors allowed,
* erase it.
@@ -291,7 +307,6 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
} else if ((mm->base_va <= table_idx_end_va) ||
(region_end_va >= table_idx_va)) {
-
/*
* Region partially covers block.
*
@@ -300,18 +315,19 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
* There must be a table descriptor here, if not there
* was a problem when mapping the region.
*/
-
- assert(level < 3);
-
+ assert(level < 3U);
assert(desc_type == TABLE_DESC);
action = ACTION_RECURSE_INTO_TABLE;
+ } else {
+ /* The region doesn't cover the block at all */
+ action = ACTION_NONE;
}
if (action == ACTION_WRITE_BLOCK_ENTRY) {
table_base[table_idx] = INVALID_DESC;
- xlat_arch_tlbi_va_regime(table_idx_va, ctx->xlat_regime);
+ xlat_arch_tlbi_va(table_idx_va, ctx->xlat_regime);
} else if (action == ACTION_RECURSE_INTO_TABLE) {
@@ -320,15 +336,18 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
/* Recurse to write into subtable */
xlat_tables_unmap_region(ctx, mm, table_idx_va,
subtable, XLAT_TABLE_ENTRIES,
- level + 1);
-
+ level + 1U);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)subtable,
+ XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
/*
* If the subtable is now empty, remove its reference.
*/
if (xlat_table_is_empty(ctx, subtable)) {
table_base[table_idx] = INVALID_DESC;
- xlat_arch_tlbi_va_regime(table_idx_va,
- ctx->xlat_regime);
+ xlat_arch_tlbi_va(table_idx_va,
+ ctx->xlat_regime);
}
} else {
@@ -354,12 +373,12 @@ static void xlat_tables_unmap_region(xlat_ctx_t *ctx, mmap_region_t *mm,
* specified region.
*/
static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
- const int desc_type, const unsigned long long dest_pa,
- const uintptr_t table_entry_base_va, const unsigned int level)
+ unsigned int desc_type, unsigned long long dest_pa,
+ uintptr_t table_entry_base_va, unsigned int level)
{
- uintptr_t mm_end_va = mm->base_va + mm->size - 1;
+ uintptr_t mm_end_va = mm->base_va + mm->size - 1U;
uintptr_t table_entry_end_va =
- table_entry_base_va + XLAT_BLOCK_SIZE(level) - 1;
+ table_entry_base_va + XLAT_BLOCK_SIZE(level) - 1U;
/*
* The descriptor types allowed depend on the current table level.
@@ -376,7 +395,7 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
* translation with this granularity in principle.
*/
- if (level == 3) {
+ if (level == 3U) {
/*
* Last level, only page descriptors are allowed.
*/
@@ -414,8 +433,8 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
* Also, check if the current level allows block
* descriptors. If not, create a table instead.
*/
- if ((dest_pa & XLAT_BLOCK_MASK(level)) ||
- (level < MIN_LVL_BLOCK_DESC) ||
+ if (((dest_pa & XLAT_BLOCK_MASK(level)) != 0U)
+ || (level < MIN_LVL_BLOCK_DESC) ||
(mm->granularity < XLAT_BLOCK_SIZE(level)))
return ACTION_CREATE_NEW_TABLE;
else
@@ -447,7 +466,7 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
* mmap region failed to detect that PA and VA must at least be
* aligned to PAGE_SIZE.
*/
- assert(level < 3);
+ assert(level < 3U);
if (desc_type == INVALID_DESC) {
/*
@@ -470,13 +489,14 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
*/
return ACTION_RECURSE_INTO_TABLE;
}
- }
+ } else {
- /*
- * This table entry is outside of the region specified in the arguments,
- * don't write anything to it.
- */
- return ACTION_NONE;
+ /*
+ * This table entry is outside of the region specified in the
+ * arguments, don't write anything to it.
+ */
+ return ACTION_NONE;
+ }
}
/*
@@ -486,14 +506,14 @@ static action_t xlat_tables_map_region_action(const mmap_region_t *mm,
* should have been mapped.
*/
static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
- const uintptr_t table_base_va,
+ uintptr_t table_base_va,
uint64_t *const table_base,
- const int table_entries,
- const unsigned int level)
+ unsigned int table_entries,
+ unsigned int level)
{
- assert(level >= ctx->base_level && level <= XLAT_TABLE_LEVEL_MAX);
+ assert((level >= ctx->base_level) && (level <= XLAT_TABLE_LEVEL_MAX));
- uintptr_t mm_end_va = mm->base_va + mm->size - 1;
+ uintptr_t mm_end_va = mm->base_va + mm->size - 1U;
uintptr_t table_idx_va;
unsigned long long table_idx_pa;
@@ -501,20 +521,20 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
uint64_t *subtable;
uint64_t desc;
- int table_idx;
+ unsigned int table_idx;
if (mm->base_va > table_base_va) {
/* Find the first index of the table affected by the region. */
table_idx_va = mm->base_va & ~XLAT_BLOCK_MASK(level);
- table_idx = (table_idx_va - table_base_va) >>
- XLAT_ADDR_SHIFT(level);
+ table_idx = (unsigned int)((table_idx_va - table_base_va) >>
+ XLAT_ADDR_SHIFT(level));
assert(table_idx < table_entries);
} else {
/* Start from the beginning of the table. */
table_idx_va = table_base_va;
- table_idx = 0;
+ table_idx = 0U;
}
#if PLAT_XLAT_TABLES_DYNAMIC
@@ -529,7 +549,8 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
table_idx_pa = mm->base_pa + table_idx_va - mm->base_va;
action_t action = xlat_tables_map_region_action(mm,
- desc & DESC_MASK, table_idx_pa, table_idx_va, level);
+ (uint32_t)(desc & DESC_MASK), table_idx_pa,
+ table_idx_va, level);
if (action == ACTION_WRITE_BLOCK_ENTRY) {
@@ -538,6 +559,7 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
level);
} else if (action == ACTION_CREATE_NEW_TABLE) {
+ uintptr_t end_va;
subtable = xlat_table_get_empty(ctx);
if (subtable == NULL) {
@@ -549,20 +571,31 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
table_base[table_idx] = TABLE_DESC | (unsigned long)subtable;
/* Recurse to write into subtable */
- uintptr_t end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
+ end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
subtable, XLAT_TABLE_ENTRIES,
- level + 1);
- if (end_va != table_idx_va + XLAT_BLOCK_SIZE(level) - 1)
+ level + 1U);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)subtable,
+ XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
+ if (end_va !=
+ (table_idx_va + XLAT_BLOCK_SIZE(level) - 1U))
return end_va;
} else if (action == ACTION_RECURSE_INTO_TABLE) {
+ uintptr_t end_va;
subtable = (uint64_t *)(uintptr_t)(desc & TABLE_ADDR_MASK);
/* Recurse to write into subtable */
- uintptr_t end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
+ end_va = xlat_tables_map_region(ctx, mm, table_idx_va,
subtable, XLAT_TABLE_ENTRIES,
- level + 1);
- if (end_va != table_idx_va + XLAT_BLOCK_SIZE(level) - 1)
+ level + 1U);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)subtable,
+ XLAT_TABLE_ENTRIES * sizeof(uint64_t));
+#endif
+ if (end_va !=
+ (table_idx_va + XLAT_BLOCK_SIZE(level) - 1U))
return end_va;
} else {
@@ -579,7 +612,7 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
break;
}
- return table_idx_va - 1;
+ return table_idx_va - 1U;
}
/*
@@ -591,23 +624,23 @@ static uintptr_t xlat_tables_map_region(xlat_ctx_t *ctx, mmap_region_t *mm,
* ENOMEM: There is not enough memory in the mmap array.
* EPERM: Region overlaps another one in an invalid way.
*/
-static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm)
+static int mmap_add_region_check(const xlat_ctx_t *ctx, const mmap_region_t *mm)
{
unsigned long long base_pa = mm->base_pa;
uintptr_t base_va = mm->base_va;
size_t size = mm->size;
size_t granularity = mm->granularity;
- unsigned long long end_pa = base_pa + size - 1;
- uintptr_t end_va = base_va + size - 1;
+ unsigned long long end_pa = base_pa + size - 1U;
+ uintptr_t end_va = base_va + size - 1U;
if (!IS_PAGE_ALIGNED(base_pa) || !IS_PAGE_ALIGNED(base_va) ||
!IS_PAGE_ALIGNED(size))
return -EINVAL;
- if ((granularity != XLAT_BLOCK_SIZE(1)) &&
- (granularity != XLAT_BLOCK_SIZE(2)) &&
- (granularity != XLAT_BLOCK_SIZE(3))) {
+ if ((granularity != XLAT_BLOCK_SIZE(1U)) &&
+ (granularity != XLAT_BLOCK_SIZE(2U)) &&
+ (granularity != XLAT_BLOCK_SIZE(3U))) {
return -EINVAL;
}
@@ -622,24 +655,23 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm)
return -ERANGE;
/* Check that there is space in the ctx->mmap array */
- if (ctx->mmap[ctx->mmap_num - 1].size != 0)
+ if (ctx->mmap[ctx->mmap_num - 1].size != 0U)
return -ENOMEM;
/* Check for PAs and VAs overlaps with all other regions */
- for (mmap_region_t *mm_cursor = ctx->mmap;
- mm_cursor->size; ++mm_cursor) {
+ for (const mmap_region_t *mm_cursor = ctx->mmap;
+ mm_cursor->size != 0U; ++mm_cursor) {
uintptr_t mm_cursor_end_va = mm_cursor->base_va
- + mm_cursor->size - 1;
+ + mm_cursor->size - 1U;
/*
* Check if one of the regions is completely inside the other
* one.
*/
- int fully_overlapped_va =
+ bool fully_overlapped_va =
((base_va >= mm_cursor->base_va) &&
(end_va <= mm_cursor_end_va)) ||
-
((mm_cursor->base_va >= base_va) &&
(mm_cursor_end_va <= end_va));
@@ -652,8 +684,8 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm)
if (fully_overlapped_va) {
#if PLAT_XLAT_TABLES_DYNAMIC
- if ((mm->attr & MT_DYNAMIC) ||
- (mm_cursor->attr & MT_DYNAMIC))
+ if (((mm->attr & MT_DYNAMIC) != 0U) ||
+ ((mm_cursor->attr & MT_DYNAMIC) != 0U))
return -EPERM;
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
if ((mm_cursor->base_va - mm_cursor->base_pa) !=
@@ -672,16 +704,14 @@ static int mmap_add_region_check(xlat_ctx_t *ctx, const mmap_region_t *mm)
*/
unsigned long long mm_cursor_end_pa =
- mm_cursor->base_pa + mm_cursor->size - 1;
+ mm_cursor->base_pa + mm_cursor->size - 1U;
- int separated_pa =
- (end_pa < mm_cursor->base_pa) ||
+ bool separated_pa = (end_pa < mm_cursor->base_pa) ||
(base_pa > mm_cursor_end_pa);
- int separated_va =
- (end_va < mm_cursor->base_va) ||
+ bool separated_va = (end_va < mm_cursor->base_va) ||
(base_va > mm_cursor_end_va);
- if (!(separated_va && separated_pa))
+ if (!separated_va || !separated_pa)
return -EPERM;
}
}
@@ -693,13 +723,13 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
{
mmap_region_t *mm_cursor = ctx->mmap, *mm_destination;
const mmap_region_t *mm_end = ctx->mmap + ctx->mmap_num;
- mmap_region_t *mm_last;
- unsigned long long end_pa = mm->base_pa + mm->size - 1;
- uintptr_t end_va = mm->base_va + mm->size - 1;
+ const mmap_region_t *mm_last;
+ unsigned long long end_pa = mm->base_pa + mm->size - 1U;
+ uintptr_t end_va = mm->base_va + mm->size - 1U;
int ret;
/* Ignore empty regions */
- if (!mm->size)
+ if (mm->size == 0U)
return;
/* Static regions must be added before initializing the xlat tables. */
@@ -708,7 +738,7 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
ret = mmap_add_region_check(ctx, mm);
if (ret != 0) {
ERROR("mmap_add_region_check() failed. error %d\n", ret);
- assert(0);
+ assert(false);
return;
}
@@ -736,13 +766,15 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
* Overlapping is only allowed for static regions.
*/
- while ((mm_cursor->base_va + mm_cursor->size - 1) < end_va
- && mm_cursor->size)
+ while (((mm_cursor->base_va + mm_cursor->size - 1U) < end_va)
+ && (mm_cursor->size != 0U)) {
++mm_cursor;
+ }
- while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va) &&
- (mm_cursor->size != 0U) && (mm_cursor->size < mm->size))
+ while (((mm_cursor->base_va + mm_cursor->size - 1U) == end_va) &&
+ (mm_cursor->size != 0U) && (mm_cursor->size < mm->size)) {
++mm_cursor;
+ }
/*
* Find the last entry marker in the mmap
@@ -761,7 +793,7 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
/* Make room for new region by moving other regions up by one place */
mm_destination = mm_cursor + 1;
- memmove(mm_destination, mm_cursor,
+ (void)memmove(mm_destination, mm_cursor,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
/*
@@ -781,9 +813,11 @@ void mmap_add_region_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
{
- while (mm->size) {
- mmap_add_region_ctx(ctx, mm);
- mm++;
+ const mmap_region_t *mm_cursor = mm;
+
+ while (mm_cursor->size != 0U) {
+ mmap_add_region_ctx(ctx, mm_cursor);
+ mm_cursor++;
}
}
@@ -792,13 +826,13 @@ void mmap_add_ctx(xlat_ctx_t *ctx, const mmap_region_t *mm)
int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
{
mmap_region_t *mm_cursor = ctx->mmap;
- mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
- unsigned long long end_pa = mm->base_pa + mm->size - 1;
- uintptr_t end_va = mm->base_va + mm->size - 1;
+ const mmap_region_t *mm_last = mm_cursor + ctx->mmap_num;
+ unsigned long long end_pa = mm->base_pa + mm->size - 1U;
+ uintptr_t end_va = mm->base_va + mm->size - 1U;
int ret;
/* Nothing to do */
- if (!mm->size)
+ if (mm->size == 0U)
return 0;
/* Now this region is a dynamic one */
@@ -813,16 +847,18 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
* static regions in mmap_add_region_ctx().
*/
- while ((mm_cursor->base_va + mm_cursor->size - 1)
- < end_va && mm_cursor->size)
+ while (((mm_cursor->base_va + mm_cursor->size - 1U) < end_va)
+ && (mm_cursor->size != 0U)) {
++mm_cursor;
+ }
- while ((mm_cursor->base_va + mm_cursor->size - 1 == end_va)
- && (mm_cursor->size < mm->size))
+ while (((mm_cursor->base_va + mm_cursor->size - 1U) == end_va) &&
+ (mm_cursor->size != 0U) && (mm_cursor->size < mm->size)) {
++mm_cursor;
+ }
/* Make room for new region by moving other regions up by one place */
- memmove(mm_cursor + 1, mm_cursor,
+ (void)memmove(mm_cursor + 1U, mm_cursor,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
/*
@@ -830,7 +866,7 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
* This shouldn't happen as we have checked in mmap_add_region_check
* that there is free space.
*/
- assert(mm_last->size == 0);
+ assert(mm_last->size == 0U);
*mm_cursor = *mm;
@@ -839,13 +875,16 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
* not, this region will be mapped when they are initialized.
*/
if (ctx->initialized) {
- uintptr_t end_va = xlat_tables_map_region(ctx, mm_cursor,
- 0, ctx->base_table, ctx->base_table_entries,
+ end_va = xlat_tables_map_region(ctx, mm_cursor,
+ 0U, ctx->base_table, ctx->base_table_entries,
ctx->base_level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+ ctx->base_table_entries * sizeof(uint64_t));
+#endif
/* Failed to map, remove mmap entry, unmap and return error. */
- if (end_va != mm_cursor->base_va + mm_cursor->size - 1) {
- memmove(mm_cursor, mm_cursor + 1,
+ if (end_va != (mm_cursor->base_va + mm_cursor->size - 1U)) {
+ (void)memmove(mm_cursor, mm_cursor + 1U,
(uintptr_t)mm_last - (uintptr_t)mm_cursor);
/*
@@ -860,14 +899,18 @@ int mmap_add_dynamic_region_ctx(xlat_ctx_t *ctx, mmap_region_t *mm)
* entries, undo every change done up to this point.
*/
mmap_region_t unmap_mm = {
- .base_pa = 0,
+ .base_pa = 0U,
.base_va = mm->base_va,
.size = end_va - mm->base_va,
- .attr = 0
+ .attr = 0U
};
- xlat_tables_unmap_region(ctx, &unmap_mm, 0, ctx->base_table,
- ctx->base_table_entries, ctx->base_level);
-
+ xlat_tables_unmap_region(ctx, &unmap_mm, 0U,
+ ctx->base_table, ctx->base_table_entries,
+ ctx->base_level);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+ ctx->base_table_entries * sizeof(uint64_t));
+#endif
return -ENOMEM;
}
@@ -901,61 +944,65 @@ int mmap_remove_dynamic_region_ctx(xlat_ctx_t *ctx, uintptr_t base_va,
size_t size)
{
mmap_region_t *mm = ctx->mmap;
- mmap_region_t *mm_last = mm + ctx->mmap_num;
+ const mmap_region_t *mm_last = mm + ctx->mmap_num;
int update_max_va_needed = 0;
int update_max_pa_needed = 0;
/* Check sanity of mmap array. */
- assert(mm[ctx->mmap_num].size == 0);
+ assert(mm[ctx->mmap_num].size == 0U);
- while (mm->size) {
+ while (mm->size != 0U) {
if ((mm->base_va == base_va) && (mm->size == size))
break;
++mm;
}
/* Check that the region was found */
- if (mm->size == 0)
+ if (mm->size == 0U)
return -EINVAL;
/* If the region is static it can't be removed */
- if (!(mm->attr & MT_DYNAMIC))
+ if ((mm->attr & MT_DYNAMIC) == 0U)
return -EPERM;
/* Check if this region is using the top VAs or PAs. */
- if ((mm->base_va + mm->size - 1) == ctx->max_va)
+ if ((mm->base_va + mm->size - 1U) == ctx->max_va)
update_max_va_needed = 1;
- if ((mm->base_pa + mm->size - 1) == ctx->max_pa)
+ if ((mm->base_pa + mm->size - 1U) == ctx->max_pa)
update_max_pa_needed = 1;
/* Update the translation tables if needed */
if (ctx->initialized) {
- xlat_tables_unmap_region(ctx, mm, 0, ctx->base_table,
+ xlat_tables_unmap_region(ctx, mm, 0U, ctx->base_table,
ctx->base_table_entries,
ctx->base_level);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+ ctx->base_table_entries * sizeof(uint64_t));
+#endif
xlat_arch_tlbi_va_sync();
}
/* Remove this region by moving the rest down by one place. */
- memmove(mm, mm + 1, (uintptr_t)mm_last - (uintptr_t)mm);
+ (void)memmove(mm, mm + 1U, (uintptr_t)mm_last - (uintptr_t)mm);
/* Check if we need to update the max VAs and PAs */
- if (update_max_va_needed) {
- ctx->max_va = 0;
+ if (update_max_va_needed == 1) {
+ ctx->max_va = 0U;
mm = ctx->mmap;
- while (mm->size) {
- if ((mm->base_va + mm->size - 1) > ctx->max_va)
- ctx->max_va = mm->base_va + mm->size - 1;
+ while (mm->size != 0U) {
+ if ((mm->base_va + mm->size - 1U) > ctx->max_va)
+ ctx->max_va = mm->base_va + mm->size - 1U;
++mm;
}
}
- if (update_max_pa_needed) {
- ctx->max_pa = 0;
+ if (update_max_pa_needed == 1) {
+ ctx->max_pa = 0U;
mm = ctx->mmap;
- while (mm->size) {
- if ((mm->base_pa + mm->size - 1) > ctx->max_pa)
- ctx->max_pa = mm->base_pa + mm->size - 1;
+ while (mm->size != 0U) {
+ if ((mm->base_pa + mm->size - 1U) > ctx->max_pa)
+ ctx->max_pa = mm->base_pa + mm->size - 1U;
++mm;
}
}
@@ -969,7 +1016,9 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx)
{
assert(ctx != NULL);
assert(!ctx->initialized);
- assert(ctx->xlat_regime == EL3_REGIME || ctx->xlat_regime == EL1_EL0_REGIME);
+ assert((ctx->xlat_regime == EL3_REGIME) ||
+ (ctx->xlat_regime == EL2_REGIME) ||
+ (ctx->xlat_regime == EL1_EL0_REGIME));
assert(!is_mmu_enabled_ctx(ctx));
mmap_region_t *mm = ctx->mmap;
@@ -978,25 +1027,29 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx)
/* All tables must be zeroed before mapping any region. */
- for (unsigned int i = 0; i < ctx->base_table_entries; i++)
+ for (unsigned int i = 0U; i < ctx->base_table_entries; i++)
ctx->base_table[i] = INVALID_DESC;
- for (unsigned int j = 0; j < ctx->tables_num; j++) {
+ for (int j = 0; j < ctx->tables_num; j++) {
#if PLAT_XLAT_TABLES_DYNAMIC
ctx->tables_mapped_regions[j] = 0;
#endif
- for (unsigned int i = 0; i < XLAT_TABLE_ENTRIES; i++)
+ for (unsigned int i = 0U; i < XLAT_TABLE_ENTRIES; i++)
ctx->tables[j][i] = INVALID_DESC;
}
- while (mm->size) {
- uintptr_t end_va = xlat_tables_map_region(ctx, mm, 0, ctx->base_table,
- ctx->base_table_entries, ctx->base_level);
-
- if (end_va != mm->base_va + mm->size - 1) {
+ while (mm->size != 0U) {
+ uintptr_t end_va = xlat_tables_map_region(ctx, mm, 0U,
+ ctx->base_table, ctx->base_table_entries,
+ ctx->base_level);
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ xlat_clean_dcache_range((uintptr_t)ctx->base_table,
+ ctx->base_table_entries * sizeof(uint64_t));
+#endif
+ if (end_va != (mm->base_va + mm->size - 1U)) {
ERROR("Not enough memory to map region:\n"
- " VA:%p PA:0x%llx size:0x%zx attr:0x%x\n",
- (void *)mm->base_va, mm->base_pa, mm->size, mm->attr);
+ " VA:0x%lx PA:0x%llx size:0x%zx attr:0x%x\n",
+ mm->base_va, mm->base_pa, mm->size, mm->attr);
panic();
}
@@ -1007,7 +1060,7 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx)
assert(ctx->max_va <= ctx->va_max_address);
assert(ctx->max_pa <= ctx->pa_max_address);
- ctx->initialized = 1;
+ ctx->initialized = true;
xlat_tables_print(ctx);
}
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 4a54ec5d0..528996a29 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -4,10 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __XLAT_TABLES_PRIVATE_H__
-#define __XLAT_TABLES_PRIVATE_H__
+#ifndef XLAT_TABLES_PRIVATE_H
+#define XLAT_TABLES_PRIVATE_H
#include <platform_def.h>
+#include <stdbool.h>
#include <xlat_tables_defs.h>
#if PLAT_XLAT_TABLES_DYNAMIC
@@ -35,22 +36,26 @@
#endif /* PLAT_XLAT_TABLES_DYNAMIC */
+extern uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
+
+/*
+ * Return the execute-never mask that will prevent instruction fetch at the
+ * given translation regime.
+ */
+uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime);
+
/*
* Invalidate all TLB entries that match the given virtual address. This
* operation applies to all PEs in the same Inner Shareable domain as the PE
* that executes this function. This functions must be called for every
- * translation table entry that is modified.
- *
- * xlat_arch_tlbi_va() applies the invalidation to the exception level of the
- * current translation regime, whereas xlat_arch_tlbi_va_regime() applies it to
- * the given translation regime.
+ * translation table entry that is modified. It only affects the specified
+ * translation regime.
*
* Note, however, that it is architecturally UNDEFINED to invalidate TLB entries
* pertaining to a higher exception level, e.g. invalidating EL3 entries from
* S-EL1.
*/
-void xlat_arch_tlbi_va(uintptr_t va);
-void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime);
+void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime);
/*
* This function has to be called at the end of any code that uses the function
@@ -59,7 +64,7 @@ void xlat_arch_tlbi_va_regime(uintptr_t va, int xlat_regime);
void xlat_arch_tlbi_va_sync(void);
/* Print VA, PA, size and attributes of all regions in the mmap array. */
-void xlat_mmap_print(mmap_region_t *const mmap);
+void xlat_mmap_print(const mmap_region_t *mmap);
/*
* Print the current state of the translation tables by reading them from
@@ -71,14 +76,14 @@ void xlat_tables_print(xlat_ctx_t *ctx);
* Returns a block/page table descriptor for the given level and attributes.
*/
uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr,
- unsigned long long addr_pa, int level);
+ unsigned long long addr_pa, unsigned int level);
/*
* Architecture-specific initialization code.
*/
/* Returns the current Exception Level. The returned EL must be 1 or higher. */
-int xlat_arch_current_el(void);
+unsigned int xlat_arch_current_el(void);
/*
* Return the maximum physical address supported by the hardware.
@@ -86,14 +91,13 @@ int xlat_arch_current_el(void);
*/
unsigned long long xlat_arch_get_max_supported_pa(void);
-/* Enable MMU and configure it to use the specified translation tables. */
-void setup_mmu_cfg(unsigned int flags, const uint64_t *base_table,
- unsigned long long max_pa, uintptr_t max_va);
-
/*
- * Return 1 if the MMU of the translation regime managed by the given xlat_ctx_t
- * is enabled, 0 otherwise.
+ * Returns true if the MMU of the translation regime managed by the given
+ * xlat_ctx_t is enabled, false otherwise.
*/
-int is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
+bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx);
+
+/* Returns true if the data cache is enabled at the current EL. */
+bool is_dcache_enabled(void);
-#endif /* __XLAT_TABLES_PRIVATE_H__ */
+#endif /* XLAT_TABLES_PRIVATE_H */
diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c
index 5a78434ab..41c01aee7 100644
--- a/lib/xlat_tables_v2/xlat_tables_utils.c
+++ b/lib/xlat_tables_v2/xlat_tables_utils.c
@@ -9,9 +9,10 @@
#include <debug.h>
#include <errno.h>
#include <platform_def.h>
-#include <types.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
#include <utils_def.h>
-#include <xlat_tables_arch_private.h>
#include <xlat_tables_defs.h>
#include <xlat_tables_v2.h>
@@ -19,7 +20,7 @@
#if LOG_LEVEL < LOG_LEVEL_VERBOSE
-void xlat_mmap_print(__unused mmap_region_t *const mmap)
+void xlat_mmap_print(__unused const mmap_region_t *mmap)
{
/* Empty */
}
@@ -31,39 +32,39 @@ void xlat_tables_print(__unused xlat_ctx_t *ctx)
#else /* if LOG_LEVEL >= LOG_LEVEL_VERBOSE */
-void xlat_mmap_print(mmap_region_t *const mmap)
+void xlat_mmap_print(const mmap_region_t *mmap)
{
- tf_printf("mmap:\n");
+ printf("mmap:\n");
const mmap_region_t *mm = mmap;
while (mm->size != 0U) {
- tf_printf(" VA:0x%lx PA:0x%llx size:0x%zx attr:0x%x "
- "granularity:0x%zx\n", mm->base_va, mm->base_pa,
- mm->size, mm->attr, mm->granularity);
+ printf(" VA:0x%lx PA:0x%llx size:0x%zx attr:0x%x granularity:0x%zx\n",
+ mm->base_va, mm->base_pa, mm->size, mm->attr,
+ mm->granularity);
++mm;
};
- tf_printf("\n");
+ printf("\n");
}
/* Print the attributes of the specified block descriptor. */
static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc)
{
- int mem_type_index = ATTR_INDEX_GET(desc);
+ uint64_t mem_type_index = ATTR_INDEX_GET(desc);
int xlat_regime = ctx->xlat_regime;
if (mem_type_index == ATTR_IWBWA_OWBWA_NTR_INDEX) {
- tf_printf("MEM");
+ printf("MEM");
} else if (mem_type_index == ATTR_NON_CACHEABLE_INDEX) {
- tf_printf("NC");
+ printf("NC");
} else {
assert(mem_type_index == ATTR_DEVICE_INDEX);
- tf_printf("DEV");
+ printf("DEV");
}
- if (xlat_regime == EL3_REGIME) {
- /* For EL3 only check the AP[2] and XN bits. */
- tf_printf((desc & LOWER_ATTRS(AP_RO)) ? "-RO" : "-RW");
- tf_printf((desc & UPPER_ATTRS(XN)) ? "-XN" : "-EXEC");
+ if ((xlat_regime == EL3_REGIME) || (xlat_regime == EL2_REGIME)) {
+ /* For EL3 and EL2 only check the AP[2] and XN bits. */
+ printf(((desc & LOWER_ATTRS(AP_RO)) != 0ULL) ? "-RO" : "-RW");
+ printf(((desc & UPPER_ATTRS(XN)) != 0ULL) ? "-XN" : "-EXEC");
} else {
assert(xlat_regime == EL1_EL0_REGIME);
/*
@@ -81,18 +82,18 @@ static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc)
assert((xn_perm == xn_mask) || (xn_perm == 0ULL));
#endif
- tf_printf((desc & LOWER_ATTRS(AP_RO)) ? "-RO" : "-RW");
+ printf(((desc & LOWER_ATTRS(AP_RO)) != 0ULL) ? "-RO" : "-RW");
/* Only check one of PXN and UXN, the other one is the same. */
- tf_printf((desc & UPPER_ATTRS(PXN)) ? "-XN" : "-EXEC");
+ printf(((desc & UPPER_ATTRS(PXN)) != 0ULL) ? "-XN" : "-EXEC");
/*
* Privileged regions can only be accessed from EL1, user
* regions can be accessed from EL1 and EL0.
*/
- tf_printf((desc & LOWER_ATTRS(AP_ACCESS_UNPRIVILEGED))
+ printf(((desc & LOWER_ATTRS(AP_ACCESS_UNPRIVILEGED)) != 0ULL)
? "-USER" : "-PRIV");
}
- tf_printf(LOWER_ATTRS(NS) & desc ? "-NS" : "-S");
+ printf(((LOWER_ATTRS(NS) & desc) != 0ULL) ? "-NS" : "-S");
}
static const char * const level_spacers[] = {
@@ -109,17 +110,15 @@ static const char *invalid_descriptors_ommited =
* Recursive function that reads the translation tables passed as an argument
* and prints their status.
*/
-static void xlat_tables_print_internal(xlat_ctx_t *ctx,
- const uintptr_t table_base_va,
- uint64_t *const table_base, const int table_entries,
- const unsigned int level)
+static void xlat_tables_print_internal(xlat_ctx_t *ctx, uintptr_t table_base_va,
+ const uint64_t *table_base, unsigned int table_entries,
+ unsigned int level)
{
assert(level <= XLAT_TABLE_LEVEL_MAX);
uint64_t desc;
uintptr_t table_idx_va = table_base_va;
- int table_idx = 0;
-
+ unsigned int table_idx = 0U;
size_t level_size = XLAT_BLOCK_SIZE(level);
/*
@@ -137,18 +136,18 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx,
if ((desc & DESC_MASK) == INVALID_DESC) {
if (invalid_row_count == 0) {
- tf_printf("%sVA:%p size:0x%zx\n",
- level_spacers[level],
- (void *)table_idx_va, level_size);
+ printf("%sVA:0x%lx size:0x%zx\n",
+ level_spacers[level],
+ table_idx_va, level_size);
}
invalid_row_count++;
} else {
if (invalid_row_count > 1) {
- tf_printf(invalid_descriptors_ommited,
- level_spacers[level],
- invalid_row_count - 1);
+ printf(invalid_descriptors_ommited,
+ level_spacers[level],
+ invalid_row_count - 1);
}
invalid_row_count = 0;
@@ -165,23 +164,22 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx,
* but instead points to the next translation
* table in the translation table walk.
*/
- tf_printf("%sVA:%p size:0x%zx\n",
- level_spacers[level],
- (void *)table_idx_va, level_size);
+ printf("%sVA:0x%lx size:0x%zx\n",
+ level_spacers[level],
+ table_idx_va, level_size);
uintptr_t addr_inner = desc & TABLE_ADDR_MASK;
xlat_tables_print_internal(ctx, table_idx_va,
(uint64_t *)addr_inner,
- XLAT_TABLE_ENTRIES, level + 1);
+ XLAT_TABLE_ENTRIES, level + 1U);
} else {
- tf_printf("%sVA:%p PA:0x%llx size:0x%zx ",
- level_spacers[level],
- (void *)table_idx_va,
- (unsigned long long)(desc & TABLE_ADDR_MASK),
- level_size);
+ printf("%sVA:0x%lx PA:0x%llx size:0x%zx ",
+ level_spacers[level], table_idx_va,
+ (uint64_t)(desc & TABLE_ADDR_MASK),
+ level_size);
xlat_desc_print(ctx, desc);
- tf_printf("\n");
+ printf("\n");
}
}
@@ -190,16 +188,20 @@ static void xlat_tables_print_internal(xlat_ctx_t *ctx,
}
if (invalid_row_count > 1) {
- tf_printf(invalid_descriptors_ommited,
- level_spacers[level], invalid_row_count - 1);
+ printf(invalid_descriptors_ommited,
+ level_spacers[level], invalid_row_count - 1);
}
}
void xlat_tables_print(xlat_ctx_t *ctx)
{
const char *xlat_regime_str;
+ int used_page_tables;
+
if (ctx->xlat_regime == EL1_EL0_REGIME) {
xlat_regime_str = "1&0";
+ } else if (ctx->xlat_regime == EL2_REGIME) {
+ xlat_regime_str = "2";
} else {
assert(ctx->xlat_regime == EL3_REGIME);
xlat_regime_str = "3";
@@ -207,29 +209,28 @@ void xlat_tables_print(xlat_ctx_t *ctx)
VERBOSE("Translation tables state:\n");
VERBOSE(" Xlat regime: EL%s\n", xlat_regime_str);
VERBOSE(" Max allowed PA: 0x%llx\n", ctx->pa_max_address);
- VERBOSE(" Max allowed VA: %p\n", (void *) ctx->va_max_address);
+ VERBOSE(" Max allowed VA: 0x%lx\n", ctx->va_max_address);
VERBOSE(" Max mapped PA: 0x%llx\n", ctx->max_pa);
- VERBOSE(" Max mapped VA: %p\n", (void *) ctx->max_va);
+ VERBOSE(" Max mapped VA: 0x%lx\n", ctx->max_va);
- VERBOSE(" Initial lookup level: %i\n", ctx->base_level);
- VERBOSE(" Entries @initial lookup level: %i\n",
+ VERBOSE(" Initial lookup level: %u\n", ctx->base_level);
+ VERBOSE(" Entries @initial lookup level: %u\n",
ctx->base_table_entries);
- int used_page_tables;
#if PLAT_XLAT_TABLES_DYNAMIC
used_page_tables = 0;
- for (unsigned int i = 0; i < ctx->tables_num; ++i) {
+ for (int i = 0; i < ctx->tables_num; ++i) {
if (ctx->tables_mapped_regions[i] != 0)
++used_page_tables;
}
#else
used_page_tables = ctx->next_table;
#endif
- VERBOSE(" Used %i sub-tables out of %i (spare: %i)\n",
+ VERBOSE(" Used %d sub-tables out of %d (spare: %d)\n",
used_page_tables, ctx->tables_num,
ctx->tables_num - used_page_tables);
- xlat_tables_print_internal(ctx, 0, ctx->base_table,
+ xlat_tables_print_internal(ctx, 0U, ctx->base_table,
ctx->base_table_entries, ctx->base_level);
}
@@ -252,13 +253,13 @@ void xlat_tables_print(xlat_ctx_t *ctx)
*/
static uint64_t *find_xlat_table_entry(uintptr_t virtual_addr,
void *xlat_table_base,
- int xlat_table_base_entries,
+ unsigned int xlat_table_base_entries,
unsigned long long virt_addr_space_size,
- int *out_level)
+ unsigned int *out_level)
{
unsigned int start_level;
uint64_t *table;
- int entries;
+ unsigned int entries;
start_level = GET_XLAT_TABLE_LEVEL_BASE(virt_addr_space_size);
@@ -268,9 +269,7 @@ static uint64_t *find_xlat_table_entry(uintptr_t virtual_addr,
for (unsigned int level = start_level;
level <= XLAT_TABLE_LEVEL_MAX;
++level) {
- int idx;
- uint64_t desc;
- uint64_t desc_type;
+ uint64_t idx, desc, desc_type;
idx = XLAT_TABLE_IDX(virtual_addr, level);
if (idx >= entries) {
@@ -311,19 +310,19 @@ static uint64_t *find_xlat_table_entry(uintptr_t virtual_addr,
* This shouldn't be reached, the translation table walk should end at
* most at level XLAT_TABLE_LEVEL_MAX and return from inside the loop.
*/
- assert(0);
+ assert(false);
return NULL;
}
-static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
- uint32_t *attributes, uint64_t **table_entry,
- unsigned long long *addr_pa, int *table_level)
+static int xlat_get_mem_attributes_internal(const xlat_ctx_t *ctx,
+ uintptr_t base_va, uint32_t *attributes, uint64_t **table_entry,
+ unsigned long long *addr_pa, unsigned int *table_level)
{
uint64_t *entry;
uint64_t desc;
- int level;
+ unsigned int level;
unsigned long long virt_addr_space_size;
/*
@@ -331,10 +330,12 @@ static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
*/
assert(ctx != NULL);
assert(ctx->initialized);
- assert(ctx->xlat_regime == EL1_EL0_REGIME || ctx->xlat_regime == EL3_REGIME);
+ assert((ctx->xlat_regime == EL1_EL0_REGIME) ||
+ (ctx->xlat_regime == EL2_REGIME) ||
+ (ctx->xlat_regime == EL3_REGIME));
- virt_addr_space_size = (unsigned long long)ctx->va_max_address + 1;
- assert(virt_addr_space_size > 0);
+ virt_addr_space_size = (unsigned long long)ctx->va_max_address + 1ULL;
+ assert(virt_addr_space_size > 0U);
entry = find_xlat_table_entry(base_va,
ctx->base_table,
@@ -342,7 +343,7 @@ static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
virt_addr_space_size,
&level);
if (entry == NULL) {
- WARN("Address %p is not mapped.\n", (void *)base_va);
+ WARN("Address 0x%lx is not mapped.\n", base_va);
return -EINVAL;
}
@@ -363,13 +364,13 @@ static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
VERBOSE("Attributes: ");
xlat_desc_print(ctx, desc);
- tf_printf("\n");
+ printf("\n");
#endif /* LOG_LEVEL >= LOG_LEVEL_VERBOSE */
assert(attributes != NULL);
- *attributes = 0;
+ *attributes = 0U;
- int attr_index = (desc >> ATTR_INDEX_SHIFT) & ATTR_INDEX_MASK;
+ uint64_t attr_index = (desc >> ATTR_INDEX_SHIFT) & ATTR_INDEX_MASK;
if (attr_index == ATTR_IWBWA_OWBWA_NTR_INDEX) {
*attributes |= MT_MEMORY;
@@ -380,20 +381,21 @@ static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
*attributes |= MT_DEVICE;
}
- int ap2_bit = (desc >> AP2_SHIFT) & 1;
+ uint64_t ap2_bit = (desc >> AP2_SHIFT) & 1U;
if (ap2_bit == AP2_RW)
*attributes |= MT_RW;
if (ctx->xlat_regime == EL1_EL0_REGIME) {
- int ap1_bit = (desc >> AP1_SHIFT) & 1;
+ uint64_t ap1_bit = (desc >> AP1_SHIFT) & 1U;
+
if (ap1_bit == AP1_ACCESS_UNPRIVILEGED)
*attributes |= MT_USER;
}
- int ns_bit = (desc >> NS_SHIFT) & 1;
+ uint64_t ns_bit = (desc >> NS_SHIFT) & 1U;
- if (ns_bit == 1)
+ if (ns_bit == 1U)
*attributes |= MT_NS;
uint64_t xn_mask = xlat_arch_regime_get_xn_desc(ctx->xlat_regime);
@@ -401,25 +403,23 @@ static int get_mem_attributes_internal(const xlat_ctx_t *ctx, uintptr_t base_va,
if ((desc & xn_mask) == xn_mask) {
*attributes |= MT_EXECUTE_NEVER;
} else {
- assert((desc & xn_mask) == 0);
+ assert((desc & xn_mask) == 0U);
}
return 0;
}
-int get_mem_attributes(const xlat_ctx_t *ctx, uintptr_t base_va,
- uint32_t *attributes)
+int xlat_get_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+ uint32_t *attr)
{
- return get_mem_attributes_internal(ctx, base_va, attributes,
- NULL, NULL, NULL);
+ return xlat_get_mem_attributes_internal(ctx, base_va, attr,
+ NULL, NULL, NULL);
}
-int change_mem_attributes(xlat_ctx_t *ctx,
- uintptr_t base_va,
- size_t size,
- uint32_t attr)
+int xlat_change_mem_attributes_ctx(const xlat_ctx_t *ctx, uintptr_t base_va,
+ size_t size, uint32_t attr)
{
/* Note: This implementation isn't optimized. */
@@ -427,46 +427,46 @@ int change_mem_attributes(xlat_ctx_t *ctx,
assert(ctx->initialized);
unsigned long long virt_addr_space_size =
- (unsigned long long)ctx->va_max_address + 1;
- assert(virt_addr_space_size > 0);
+ (unsigned long long)ctx->va_max_address + 1U;
+ assert(virt_addr_space_size > 0U);
if (!IS_PAGE_ALIGNED(base_va)) {
- WARN("%s: Address %p is not aligned on a page boundary.\n",
- __func__, (void *)base_va);
+ WARN("%s: Address 0x%lx is not aligned on a page boundary.\n",
+ __func__, base_va);
return -EINVAL;
}
- if (size == 0) {
+ if (size == 0U) {
WARN("%s: Size is 0.\n", __func__);
return -EINVAL;
}
- if ((size % PAGE_SIZE) != 0) {
+ if ((size % PAGE_SIZE) != 0U) {
WARN("%s: Size 0x%zx is not a multiple of a page size.\n",
__func__, size);
return -EINVAL;
}
- if (((attr & MT_EXECUTE_NEVER) == 0) && ((attr & MT_RW) != 0)) {
+ if (((attr & MT_EXECUTE_NEVER) == 0U) && ((attr & MT_RW) != 0U)) {
WARN("%s: Mapping memory as read-write and executable not allowed.\n",
__func__);
return -EINVAL;
}
- int pages_count = size / PAGE_SIZE;
+ size_t pages_count = size / PAGE_SIZE;
- VERBOSE("Changing memory attributes of %i pages starting from address %p...\n",
- pages_count, (void *)base_va);
+ VERBOSE("Changing memory attributes of %zu pages starting from address 0x%lx...\n",
+ pages_count, base_va);
uintptr_t base_va_original = base_va;
/*
* Sanity checks.
*/
- for (int i = 0; i < pages_count; ++i) {
- uint64_t *entry;
- uint64_t desc;
- int level;
+ for (size_t i = 0U; i < pages_count; ++i) {
+ const uint64_t *entry;
+ uint64_t desc, attr_index;
+ unsigned int level;
entry = find_xlat_table_entry(base_va,
ctx->base_table,
@@ -474,7 +474,7 @@ int change_mem_attributes(xlat_ctx_t *ctx,
virt_addr_space_size,
&level);
if (entry == NULL) {
- WARN("Address %p is not mapped.\n", (void *)base_va);
+ WARN("Address 0x%lx is not mapped.\n", base_va);
return -EINVAL;
}
@@ -486,8 +486,8 @@ int change_mem_attributes(xlat_ctx_t *ctx,
*/
if (((desc & DESC_MASK) != PAGE_DESC) ||
(level != XLAT_TABLE_LEVEL_MAX)) {
- WARN("Address %p is not mapped at the right granularity.\n",
- (void *)base_va);
+ WARN("Address 0x%lx is not mapped at the right granularity.\n",
+ base_va);
WARN("Granularity is 0x%llx, should be 0x%x.\n",
(unsigned long long)XLAT_BLOCK_SIZE(level), PAGE_SIZE);
return -EINVAL;
@@ -496,11 +496,11 @@ int change_mem_attributes(xlat_ctx_t *ctx,
/*
* If the region type is device, it shouldn't be executable.
*/
- int attr_index = (desc >> ATTR_INDEX_SHIFT) & ATTR_INDEX_MASK;
+ attr_index = (desc >> ATTR_INDEX_SHIFT) & ATTR_INDEX_MASK;
if (attr_index == ATTR_DEVICE_INDEX) {
- if ((attr & MT_EXECUTE_NEVER) == 0) {
- WARN("Setting device memory as executable at address %p.",
- (void *)base_va);
+ if ((attr & MT_EXECUTE_NEVER) == 0U) {
+ WARN("Setting device memory as executable at address 0x%lx.",
+ base_va);
return -EINVAL;
}
}
@@ -511,14 +511,14 @@ int change_mem_attributes(xlat_ctx_t *ctx,
/* Restore original value. */
base_va = base_va_original;
- for (int i = 0; i < pages_count; ++i) {
+ for (unsigned int i = 0U; i < pages_count; ++i) {
- uint32_t old_attr, new_attr;
- uint64_t *entry;
- int level;
- unsigned long long addr_pa;
+ uint32_t old_attr = 0U, new_attr;
+ uint64_t *entry = NULL;
+ unsigned int level = 0U;
+ unsigned long long addr_pa = 0ULL;
- get_mem_attributes_internal(ctx, base_va, &old_attr,
+ (void) xlat_get_mem_attributes_internal(ctx, base_va, &old_attr,
&entry, &addr_pa, &level);
/*
@@ -542,16 +542,20 @@ int change_mem_attributes(xlat_ctx_t *ctx,
* before writing the new descriptor.
*/
*entry = INVALID_DESC;
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ dccvac((uintptr_t)entry);
+#endif
/* Invalidate any cached copy of this mapping in the TLBs. */
- xlat_arch_tlbi_va_regime(base_va, ctx->xlat_regime);
+ xlat_arch_tlbi_va(base_va, ctx->xlat_regime);
/* Ensure completion of the invalidation. */
xlat_arch_tlbi_va_sync();
/* Write new descriptor */
*entry = xlat_desc(ctx, new_attr, addr_pa, level);
-
+#if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
+ dccvac((uintptr_t)entry);
+#endif
base_va += PAGE_SIZE;
}
diff --git a/maintainers.rst b/maintainers.rst
index 638f66a7c..ee6682e3f 100644
--- a/maintainers.rst
+++ b/maintainers.rst
@@ -30,17 +30,24 @@ Armv7-A architecture port
:M: Etienne Carriere <etienne.carriere@linaro.org>
:G: `etienne-lms`_
+Arm System Guidance for Infrastructure / Mobile FVP platforms
+-------------------------------------------------------------
+:M: Nariman Poushin <nariman.poushin@linaro.org>
+:G: `nariman`_
+:F: plat/arm/css/sgi/
+:F: plat/arm/css/sgm/
+:F: plat/arm/board/sgi575/
+:F: plat/arm/board/sgm775/
+
eMMC/UFS drivers
----------------
:M: Haojian Zhuang <haojian.zhuang@linaro.org>
:G: `hzhuang1`_
-:F: drivers/emmc/
:F: drivers/partition/
:F: drivers/synopsys/emmc/
:F: drivers/synopsys/ufs/
:F: drivers/ufs/
:F: include/drivers/dw_ufs.h
-:F: include/drivers/emmc.h
:F: include/drivers/ufs.h
:F: include/drivers/synopsys/dw_mmc.h
@@ -66,6 +73,14 @@ MediaTek platform ports
:G: `mtk09422`_
:F: plat/mediatek/
+Marvell platform ports and SoC drivers
+--------------------------------------
+:M: Konstantin Porotchkin <kostap@marvell.com>
+:G: `kostapr`_
+:F: docs/plat/marvell/
+:F: plat/marvell/
+:F: drivers/marvell/
+
NVidia platform ports
---------------------
:M: Varun Wadekar <vwadekar@nvidia.com>
@@ -117,6 +132,18 @@ RockChip platform port
:G: `rockchip-linux`_
:F: plat/rockchip/
+STM32MP1 platform port
+----------------------
+:M: Yann Gautier <yann.gautier@st.com>
+:G: `Yann-lms`_
+:F: docs/plat/stm32mp1.rst
+:F: drivers/st/
+:F: fdts/stm32\*
+:F: include/drivers/st/
+:F: include/dt-bindings/\*/stm32\*
+:F: plat/st/
+:F: tools/stm32image/
+
Synquacer platform port
-----------------------
:M: Sumit Garg <sumit.garg@linaro.org>
@@ -165,8 +192,10 @@ Xilinx platform port
.. _glneo: https://github.com/glneo
.. _hzhuang1: https://github.com/hzhuang1
.. _jenswi-linaro: https://github.com/jenswi-linaro
+.. _kostapr: https://github.com/kostapr
.. _masahir0y: https://github.com/masahir0y
.. _mtk09422: https://github.com/mtk09422
+.. _nariman: https://github.com/npoushin
.. _qoriq-open-source: https://github.com/qoriq-open-source
.. _rockchip-linux: https://github.com/rockchip-linux
.. _shawnguo2: https://github.com/shawnguo2
@@ -175,3 +204,4 @@ Xilinx platform port
.. _soby-mathew: https://github.com/soby-mathew
.. _TonyXie06: https://github.com/TonyXie06
.. _vwadekar: https://github.com/vwadekar
+.. _Yann-lms: https://github.com/Yann-lms
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index 2a6ded497..92a0f6e86 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -189,6 +189,24 @@ GZIP_SUFFIX := .gz
MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@ -MP
+
+# MAKE_C_LIB builds a C source file and generates the dependency file
+# $(1) = output directory
+# $(2) = source file (%.c)
+# $(3) = library name
+define MAKE_C_LIB
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+$(eval DEP := $(patsubst %.o,%.d,$(OBJ)))
+
+$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | lib$(3)_dirs
+ @echo " CC $$<"
+ $$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(MAKE_DEP) -c $$< -o $$@
+
+-include $(DEP)
+
+endef
+
+
# MAKE_C builds a C source file and generates the dependency file
# $(1) = output directory
# $(2) = source file (%.c)
@@ -243,6 +261,18 @@ $(1): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
endef
+# MAKE_LIB_OBJS builds both C source files
+# $(1) = output directory
+# $(2) = list of source files
+# $(3) = name of the library
+define MAKE_LIB_OBJS
+ $(eval C_OBJS := $(filter %.c,$(2)))
+ $(eval REMAIN := $(filter-out %.c,$(2)))
+ $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C_LIB,$(1),$(obj),$(3))))
+
+ $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
# MAKE_OBJS builds both C and assembly source files
# $(1) = output directory
@@ -274,6 +304,49 @@ endef
# This must be set to a C string (including quotes where applicable).
BUILD_MESSAGE_TIMESTAMP ?= __TIME__", "__DATE__
+.PHONY: libraries
+
+# MAKE_LIB_DIRS macro defines the target for the directory where
+# libraries are created
+define MAKE_LIB_DIRS
+ $(eval LIB_DIR := ${BUILD_PLAT}/lib)
+ $(eval ROMLIB_DIR := ${BUILD_PLAT}/romlib)
+ $(eval LIBWRAPPER_DIR := ${BUILD_PLAT}/libwrapper)
+ $(eval $(call MAKE_PREREQ_DIR,${LIB_DIR},${BUILD_PLAT}))
+ $(eval $(call MAKE_PREREQ_DIR,${ROMLIB_DIR},${BUILD_PLAT}))
+ $(eval $(call MAKE_PREREQ_DIR,${LIBWRAPPER_DIR},${BUILD_PLAT}))
+endef
+
+# MAKE_LIB macro defines the targets and options to build each BL image.
+# Arguments:
+# $(1) = Library name
+define MAKE_LIB
+ $(eval BUILD_DIR := ${BUILD_PLAT}/lib$(1))
+ $(eval LIB_DIR := ${BUILD_PLAT}/lib)
+ $(eval ROMLIB_DIR := ${BUILD_PLAT}/romlib)
+ $(eval SOURCES := $(LIB$(call uppercase,$(1))_SRCS))
+ $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call SOURCES_TO_OBJS,$(SOURCES))))
+
+$(eval $(call MAKE_PREREQ_DIR,${BUILD_DIR},${BUILD_PLAT}))
+$(eval $(call MAKE_LIB_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+
+.PHONY : lib${1}_dirs
+lib${1}_dirs: | ${BUILD_DIR} ${LIB_DIR} ${ROMLIB_DIR} ${LIBWRAPPER_DIR}
+libraries: ${LIB_DIR}/lib$(1).a
+LDPATHS = -L${LIB_DIR}
+LDLIBS += -l$(1)
+
+ifeq ($(USE_ROMLIB),1)
+LDLIBS := -lwrappers -lc
+endif
+
+all: ${LIB_DIR}/lib$(1).a
+
+${LIB_DIR}/lib$(1).a: $(OBJS)
+ @echo " AR $$@"
+ $$(Q)$$(AR) cr $$@ $$?
+endef
+
# MAKE_BL macro defines the targets and options to build each BL image.
# Arguments:
# $(1) = BL stage (2, 2u, 30, 31, 32, 33)
@@ -290,6 +363,7 @@ define MAKE_BL
$(eval DUMP := $(call IMG_DUMP,$(1)))
$(eval BIN := $(call IMG_BIN,$(1)))
$(eval BL_LINKERFILE := $(BL$(call uppercase,$(1))_LINKERFILE))
+ $(eval BL_LIBS := $(BL$(call uppercase,$(1))_LIBS))
# We use sort only to get a list of unique object directory names.
# ordering is not relevant but sort removes duplicates.
$(eval TEMP_OBJ_DIRS := $(sort $(dir ${OBJS} ${LINKERFILE})))
@@ -312,7 +386,11 @@ bl${1}_dirs: | ${OBJ_DIRS}
$(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
$(eval $(call MAKE_LD,$(LINKERFILE),$(BL_LINKERFILE),$(1)))
-$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs
+ifeq ($(USE_ROMLIB),1)
+$(ELF): romlib.bin
+endif
+
+$(ELF): $(OBJS) $(LINKERFILE) | bl$(1)_dirs libraries $(BL_LIBS)
@echo " LD $$@"
ifdef MAKE_BUILD_STRINGS
$(call MAKE_BUILD_STRINGS, $(BUILD_DIR)/build_message.o)
@@ -322,7 +400,8 @@ else
$$(CC) $$(TF_CFLAGS) $$(CFLAGS) -xc -c - -o $(BUILD_DIR)/build_message.o
endif
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
- --script $(LINKERFILE) $(BUILD_DIR)/build_message.o $(OBJS) $(LDLIBS)
+ --script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
+ $(OBJS) $(LDPATHS) $(LDLIBS) $(BL_LIBS)
$(DUMP): $(ELF)
@echo " OD $$@"
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index cea853381..908da2216 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -10,6 +10,9 @@
# poised to handle dependencies, as all build variables would have a default
# value by then.
+# Use T32 by default
+AARCH32_INSTRUCTION_SET := T32
+
# The AArch32 Secure Payload to be built as BL32 image
AARCH32_SP := none
@@ -62,6 +65,9 @@ DEFAULT_PLAT := fvp
# development platforms.
DYN_DISABLE_AUTH := 0
+# Build option to enable MPAM for lower ELs
+ENABLE_MPAM_FOR_LOWER_ELS := 0
+
# Flag to enable Performance Measurement Framework
ENABLE_PMF := 0
@@ -166,6 +172,9 @@ TRUSTED_BOARD_BOOT := 0
# Build option to choose whether Trusted firmware uses Coherent memory or not.
USE_COHERENT_MEM := 1
+# Build option to choose wheter Trusted firmware uses library at ROM
+USE_ROMLIB := 0
+
# Use tbbr_oid.h instead of platform_oid.h
USE_TBBR_DEFS = $(ERROR_DEPRECATED)
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index d0391888d..b46d41016 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -4,12 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <common_def.h>
#include <sunxi_mmap.h>
#include <tbbr/tbbr_img_def.h>
+#include <utils_def.h>
#define BL31_BASE SUNXI_SRAM_A2_BASE
#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
@@ -23,11 +24,11 @@
#define MAX_MMAP_REGIONS (4 + PLATFORM_MMAP_REGIONS)
#define MAX_XLAT_TABLES 2
-#define PLAT_MAX_PWR_LVL_STATES 2
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_PWR_LVL_STATES U(2)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
-#define PLAT_MAX_PWR_LVL 2
+#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_NUM_PWR_DOMAINS (1 + \
PLATFORM_CLUSTER_COUNT + \
PLATFORM_CORE_COUNT)
@@ -48,4 +49,4 @@
#endif
#endif
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/board/common/board_common.mk b/plat/arm/board/common/board_common.mk
index d63ae9a3b..af47c0def 100644
--- a/plat/arm/board/common/board_common.mk
+++ b/plat/arm/board/common/board_common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,13 +12,7 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
BL1_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
-BL2_SOURCES += lib/utils/mem_region.c \
- plat/arm/common/arm_nor_psci_mem_protect.c \
- plat/arm/board/common/drivers/norflash/norflash.c
-
-BL31_SOURCES += lib/utils/mem_region.c \
- plat/arm/board/common/drivers/norflash/norflash.c \
- plat/arm/common/arm_nor_psci_mem_protect.c
+BL2_SOURCES += plat/arm/board/common/drivers/norflash/norflash.c
ifneq (${TRUSTED_BOARD_BOOT},0)
ifneq (${ARM_CRYPTOCELL_INTEG}, 1)
diff --git a/plat/arm/board/common/board_css_common.c b/plat/arm/board/common/board_css_common.c
index c4e83a427..40b1a275a 100644
--- a/plat/arm/board/common/board_css_common.c
+++ b/plat/arm/board/common/board_css_common.c
@@ -53,6 +53,8 @@ const mmap_region_t plat_arm_mmap[] = {
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
CSS_MAP_DEVICE,
+ CSS_MAP_SCP_BL2U,
+ V2M_MAP_IOFPGA,
SOC_CSS_MAP_DEVICE,
{0}
};
diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c
index bcba60a3b..ea1170859 100644
--- a/plat/arm/board/fvp/fvp_bl31_setup.c
+++ b/plat/arm/board/fvp/fvp_bl31_setup.c
@@ -34,6 +34,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
fvp_interconnect_enable();
/* On FVP RevC, intialize SMMUv3 */
- if (arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3)
+ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
smmuv3_init(PLAT_FVP_SMMUV3_BASE);
}
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index acf3cf469..4e20c310a 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -4,8 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __FVP_DEF_H__
-#define __FVP_DEF_H__
+#ifndef FVP_DEF_H
+#define FVP_DEF_H
+
+#include <utils_def.h>
#ifndef FVP_CLUSTER_COUNT
#define FVP_CLUSTER_COUNT 2
@@ -153,4 +155,4 @@
#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-#endif /* __FVP_DEF_H__ */
+#endif /* FVP_DEF_H */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index b1adbee24..f22a8ec17 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -163,4 +163,7 @@
#define PLAT_ARM_PRIVATE_SDEI_EVENTS ARM_SDEI_PRIVATE_EVENTS
#define PLAT_ARM_SHARED_SDEI_EVENTS ARM_SDEI_SHARED_EVENTS
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
+ ARM_SP_IMAGE_NS_BUF_SIZE)
+
#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 2b1e0ac70..fd93b9977 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -134,13 +134,17 @@ BL1_SOURCES += drivers/io/io_semihosting.c \
BL2_SOURCES += drivers/io/io_semihosting.c \
+ lib/utils/mem_region.c \
lib/semihosting/semihosting.c \
lib/semihosting/${ARCH}/semihosting_call.S \
plat/arm/board/fvp/fvp_bl2_setup.c \
plat/arm/board/fvp/fvp_io_storage.c \
plat/arm/board/fvp/fvp_trusted_boot.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_SECURITY_SOURCES}
+
+
ifeq (${BL2_AT_EL3},1)
BL2_SOURCES += plat/arm/board/fvp/${ARCH}/fvp_helpers.S \
plat/arm/board/fvp/fvp_bl2_el3_setup.c \
@@ -156,11 +160,14 @@ BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \
${FVP_SECURITY_SOURCES}
BL31_SOURCES += drivers/arm/smmu/smmu_v3.c \
+ lib/utils/mem_region.c \
plat/arm/board/fvp/fvp_bl31_setup.c \
plat/arm/board/fvp/fvp_pm.c \
plat/arm/board/fvp/fvp_topology.c \
plat/arm/board/fvp/aarch64/fvp_helpers.S \
plat/arm/board/fvp/drivers/pwrc/fvp_pwrc.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
${FVP_CPU_LIBS} \
${FVP_GIC_SOURCES} \
${FVP_INTERCONNECT_SOURCES} \
diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h
index 80d4ba81a..3f71d7355 100644
--- a/plat/arm/board/juno/include/platform_def.h
+++ b/plat/arm/board/juno/include/platform_def.h
@@ -67,6 +67,8 @@
* in debug mode. We can test TBB on Juno bypassing the ROM and using 128 KB of
* flash
*/
+#define PLAT_ARM_MAX_ROMLIB_RO_SIZE 0
+
#if TRUSTED_BOARD_BOOT
#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00020000
#else
@@ -98,7 +100,7 @@
#endif
#ifdef IMAGE_BL2U
-# define PLAT_ARM_MMAP_ENTRIES 4
+# define PLAT_ARM_MMAP_ENTRIES 5
# define MAX_XLAT_TABLES 3
#endif
@@ -123,6 +125,15 @@
#endif
/*
+ * PLAT_ARM_MAX_ROMLIB_RW_SIZE is define to use a full page
+ */
+#if USE_ROMLIB
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0x1000
+#else
+#define PLAT_ARM_MAX_ROMLIB_RW_SIZE 0
+#endif
+
+/*
* PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
* little space for growth.
*/
diff --git a/plat/arm/board/juno/juno_bl2_setup.c b/plat/arm/board/juno/juno_bl2_setup.c
index cedef66c9..1f483d63d 100644
--- a/plat/arm/board/juno/juno_bl2_setup.c
+++ b/plat/arm/board/juno/juno_bl2_setup.c
@@ -16,7 +16,7 @@
* boot flow as the core comes up in aarch64 and to enter the BL32 image a warm
* reset in aarch32 state is required.
******************************************************************************/
-int bl2_plat_handle_post_image_load(unsigned int image_id)
+int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
int err = arm_bl2_handle_post_image_load(image_id);
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 63e245697..95f2b3915 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,12 +1,13 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __JUNO_DEF_H__
-#define __JUNO_DEF_H__
+#ifndef JUNO_DEF_H
+#define JUNO_DEF_H
+#include <utils_def.h>
/*******************************************************************************
* Juno memory map related constants
@@ -90,4 +91,4 @@
#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-#endif /* __JUNO_DEF_H__ */
+#endif /* JUNO_DEF_H */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 3ab99ef3a..16390fa4e 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -59,7 +59,9 @@ BL1_SOURCES += lib/cpus/aarch64/cortex_a53.S \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}
-BL2_SOURCES += plat/arm/board/juno/juno_bl2_setup.c \
+BL2_SOURCES += lib/utils/mem_region.c \
+ plat/arm/board/juno/juno_bl2_setup.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
${JUNO_SECURITY_SOURCES}
BL2U_SOURCES += ${JUNO_SECURITY_SOURCES}
@@ -67,7 +69,10 @@ 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 \
+ lib/utils/mem_region.c \
plat/arm/board/juno/juno_topology.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
${JUNO_SECURITY_SOURCES}
diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk
index 9893ba500..284bae8aa 100644
--- a/plat/arm/board/sgi575/platform.mk
+++ b/plat/arm/board/sgi575/platform.mk
@@ -5,3 +5,10 @@
#
include plat/arm/css/sgi/sgi-common.mk
+
+BL2_SOURCES += lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += lib/utils/mem_region.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
new file mode 100644
index 000000000..95025493b
--- /dev/null
+++ b/plat/arm/board/sgm775/fdts/sgm775_tb_fw_config.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ /* Platform Config */
+ plat_arm_bl2 {
+ compatible = "arm,tb_fw";
+ hw_config_addr = <0x0 0x83000000>;
+ hw_config_max_size = <0x01000000>;
+ };
+};
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
new file mode 100644
index 000000000..babe0930e
--- /dev/null
+++ b/plat/arm/board/sgm775/include/platform_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <sgm_base_platform_def.h>
+
+#define PLAT_MAX_CPUS_PER_CLUSTER 8
+#define PLAT_MAX_PE_PER_CPU 1
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/arm/board/sgm775/platform.mk b/plat/arm/board/sgm775/platform.mk
new file mode 100644
index 000000000..633cee664
--- /dev/null
+++ b/plat/arm/board/sgm775/platform.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include plat/arm/css/sgm/sgm-common.mk
+
+SGM775_BASE= plat/arm/board/sgm775
+
+FDT_SOURCES += ${SGM775_BASE}/fdts/sgm775_tb_fw_config.dts
+
+PLAT_INCLUDES +=-I${SGM775_BASE}/include/
+
+BL2_SOURCES += lib/utils/mem_region.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
+
+BL31_SOURCES += lib/utils/mem_region.c \
+ plat/arm/board/common/drivers/norflash/norflash.c \
+ plat/arm/common/arm_nor_psci_mem_protect.c
diff --git a/plat/arm/common/arm_bl1_setup.c b/plat/arm/common/arm_bl1_setup.c
index c9b1a68a9..d43555382 100644
--- a/plat/arm/common/arm_bl1_setup.c
+++ b/plat/arm/common/arm_bl1_setup.c
@@ -7,6 +7,7 @@
#include <arch.h>
#include <arm_def.h>
#include <arm_xlat_tables.h>
+#include <assert.h>
#include <bl1.h>
#include <bl_common.h>
#include <plat_arm.h>
@@ -23,6 +24,30 @@
#pragma weak bl1_plat_sec_mem_layout
#pragma weak bl1_plat_prepare_exit
+#define MAP_BL1_TOTAL MAP_REGION_FLAT( \
+ bl1_tzram_layout.total_base, \
+ bl1_tzram_layout.total_size, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+/*
+ * If SEPARATE_CODE_AND_RODATA=1 we define a region for each section
+ * otherwise one region is defined containing both
+ */
+#if SEPARATE_CODE_AND_RODATA
+#define MAP_BL1_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL1_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE), \
+ MAP_REGION_FLAT( \
+ BL1_RO_DATA_BASE, \
+ BL1_RO_DATA_END \
+ - BL_RO_DATA_BASE, \
+ MT_RO_DATA | MT_SECURE)
+#else
+#define MAP_BL1_RO MAP_REGION_FLAT( \
+ BL_CODE_BASE, \
+ BL1_CODE_END - BL_CODE_BASE, \
+ MT_CODE | MT_SECURE)
+#endif
/* Data structure which holds the extents of the trusted SRAM for BL1*/
static meminfo_t bl1_tzram_layout;
@@ -84,22 +109,29 @@ void bl1_early_platform_setup(void)
*****************************************************************************/
void arm_bl1_plat_arch_setup(void)
{
- arm_setup_page_tables(bl1_tzram_layout.total_base,
- bl1_tzram_layout.total_size,
- BL_CODE_BASE,
- BL1_CODE_END,
- BL1_RO_DATA_BASE,
- BL1_RO_DATA_END
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ /* ARM platforms dont use coherent memory in BL1 */
+ assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
#endif
- );
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL1_TOTAL,
+ MAP_BL1_RO,
+#if USE_ROMLIB
+ ARM_MAP_ROMLIB_CODE,
+ ARM_MAP_ROMLIB_DATA,
+ #endif
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el3(0);
#endif /* AARCH32 */
+
+ arm_setup_romlib();
}
void bl1_plat_arch_setup(void)
diff --git a/plat/arm/common/arm_bl2_el3_setup.c b/plat/arm/common/arm_bl2_el3_setup.c
index e7247c63d..c67ab4914 100644
--- a/plat/arm/common/arm_bl2_el3_setup.c
+++ b/plat/arm/common/arm_bl2_el3_setup.c
@@ -3,6 +3,8 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arm_def.h>
+#include <assert.h>
#include <generic_delay_timer.h>
#include <plat_arm.h>
#include <platform.h>
@@ -11,6 +13,11 @@
#pragma weak bl2_el3_plat_arch_setup
#pragma weak bl2_el3_plat_prepare_exit
+#define MAP_BL2_EL3_TOTAL MAP_REGION_FLAT( \
+ bl2_el3_tzram_layout.total_base, \
+ bl2_el3_tzram_layout.total_size, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
static meminfo_t bl2_el3_tzram_layout;
/*
@@ -60,20 +67,22 @@ void bl2_el3_early_platform_setup(u_register_t arg0 __unused,
******************************************************************************/
void arm_bl2_el3_plat_arch_setup(void)
{
- arm_setup_page_tables(bl2_el3_tzram_layout.total_base,
- bl2_el3_tzram_layout.total_size,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
+
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ /* Ensure ARM platforms dont use coherent memory in BL2_AT_EL3 */
+ assert(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE == 0U);
#endif
- );
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL2_EL3_TOTAL,
+ ARM_MAP_BL_RO,
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el3(0);
#endif
diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c
index 33c2fe85e..a8ea075d8 100644
--- a/plat/arm/common/arm_bl2_setup.c
+++ b/plat/arm/common/arm_bl2_setup.c
@@ -35,9 +35,14 @@ CASSERT(BL2_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl2_base_overflows);
#pragma weak bl2_plat_arch_setup
#pragma weak bl2_plat_sec_mem_layout
+#define MAP_BL2_TOTAL MAP_REGION_FLAT( \
+ bl2_tzram_layout.total_base, \
+ bl2_tzram_layout.total_size, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
#if LOAD_IMAGE_V2
-#pragma weak bl2_plat_handle_post_image_load
+#pragma weak arm_bl2_plat_handle_post_image_load
#else /* LOAD_IMAGE_V2 */
@@ -232,23 +237,31 @@ void bl2_platform_setup(void)
******************************************************************************/
void arm_bl2_plat_arch_setup(void)
{
- arm_setup_page_tables(bl2_tzram_layout.total_base,
- bl2_tzram_layout.total_size,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
+
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ /* Ensure ARM platforms dont use coherent memory in BL2 */
+ assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
+#endif
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL2_TOTAL,
+ ARM_MAP_BL_RO,
+#if USE_ROMLIB
+ ARM_MAP_ROMLIB_CODE,
+ ARM_MAP_ROMLIB_DATA,
#endif
- );
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el1(0);
#endif
+
+ arm_setup_romlib();
}
void bl2_plat_arch_setup(void)
@@ -315,11 +328,16 @@ int arm_bl2_handle_post_image_load(unsigned int image_id)
* This function can be used by the platforms to update/use image
* information for given `image_id`.
******************************************************************************/
-int bl2_plat_handle_post_image_load(unsigned int image_id)
+int arm_bl2_plat_handle_post_image_load(unsigned int image_id)
{
return arm_bl2_handle_post_image_load(image_id);
}
+int bl2_plat_handle_post_image_load(unsigned int image_id)
+{
+ return arm_bl2_plat_handle_post_image_load(image_id);
+}
+
#else /* LOAD_IMAGE_V2 */
/*******************************************************************************
diff --git a/plat/arm/common/arm_bl2u_setup.c b/plat/arm/common/arm_bl2u_setup.c
index dce00e5bd..b518f0f62 100644
--- a/plat/arm/common/arm_bl2u_setup.c
+++ b/plat/arm/common/arm_bl2u_setup.c
@@ -6,6 +6,7 @@
#include <arch_helpers.h>
#include <arm_def.h>
+#include <assert.h>
#include <bl_common.h>
#include <generic_delay_timer.h>
#include <plat_arm.h>
@@ -18,6 +19,11 @@
#pragma weak bl2u_early_platform_setup
#pragma weak bl2u_plat_arch_setup
+#define MAP_BL2U_TOTAL MAP_REGION_FLAT( \
+ BL2U_BASE, \
+ BL2U_LIMIT - BL2U_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
/*
* Perform ARM standard platform setup for BL2U
*/
@@ -58,23 +64,30 @@ void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info)
******************************************************************************/
void arm_bl2u_plat_arch_setup(void)
{
- arm_setup_page_tables(BL2U_BASE,
- BL31_LIMIT,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
+
#if USE_COHERENT_MEM
- ,
- BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ /* Ensure ARM platforms dont use coherent memory in BL2U */
+ assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
+#endif
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL2U_TOTAL,
+ ARM_MAP_BL_RO,
+#if USE_ROMLIB
+ ARM_MAP_ROMLIB_CODE,
+ ARM_MAP_ROMLIB_DATA,
#endif
- );
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el1(0);
#endif
+ arm_setup_romlib();
}
void bl2u_plat_arch_setup(void)
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index b1f95c957..4e16e3b5e 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -16,8 +16,6 @@
#include <platform.h>
#include <ras.h>
-#define BL31_END (uintptr_t)(&__BL31_END__)
-
/*
* Placeholder variables for copying the arguments that have been passed to
* BL31 from BL2.
@@ -37,6 +35,10 @@ CASSERT(BL31_BASE >= ARM_TB_FW_CONFIG_LIMIT, assert_bl31_base_overflows);
#pragma weak bl31_plat_arch_setup
#pragma weak bl31_plat_get_next_image_ep_info
+#define MAP_BL31_TOTAL MAP_REGION_FLAT( \
+ BL31_BASE, \
+ BL31_END - BL31_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for the
@@ -148,7 +150,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
* Copy BL33 and BL32 (if present), entry point information.
* They are stored in Secure RAM, in BL2's address space.
*/
- while (bl_params) {
+ while (bl_params != NULL) {
if (bl_params->image_id == BL32_IMAGE_ID)
bl32_image_ep_info = *bl_params->ep_info;
@@ -158,7 +160,7 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
bl_params = bl_params->next_params_info;
}
- if (bl33_image_ep_info.pc == 0)
+ if (bl33_image_ep_info.pc == 0U)
panic();
# else /* LOAD_IMAGE_V2 */
@@ -171,8 +173,8 @@ void arm_bl31_early_platform_setup(bl31_params_t *from_bl2, uintptr_t soc_fw_con
assert(from_bl2->h.version >= VERSION_1);
/* Dynamic Config is not supported for LOAD_IMAGE_V1 */
- assert(soc_fw_config == 0);
- assert(hw_config == 0);
+ assert(soc_fw_config == 0U);
+ assert(hw_config == 0U);
/*
* Copy BL32 (if populated by BL2) and BL33 entry point information.
@@ -232,7 +234,7 @@ void arm_bl31_platform_setup(void)
/* Enable and initialize the System level generic timer */
mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0) | CNTCR_EN);
+ CNTCR_FCREQ(0U) | CNTCR_EN);
/* Allow access to the System counter timer module */
arm_configure_sys_timer();
@@ -280,18 +282,30 @@ void bl31_plat_runtime_setup(void)
******************************************************************************/
void arm_bl31_plat_arch_setup(void)
{
- arm_setup_page_tables(BL31_BASE,
- BL31_END - BL31_BASE,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
+
+#define ARM_MAP_BL_ROMLIB MAP_REGION_FLAT( \
+ BL31_BASE, \
+ BL31_END - BL31_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL31_TOTAL,
+ ARM_MAP_BL_RO,
+#if USE_ROMLIB
+ ARM_MAP_ROMLIB_CODE,
+ ARM_MAP_ROMLIB_DATA,
+#endif
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ ARM_MAP_BL_COHERENT_RAM,
#endif
- );
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
+
enable_mmu_el3(0);
+
+ arm_setup_romlib();
}
void bl31_plat_arch_setup(void)
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index 270abb2bd..ed43c379d 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -10,8 +10,9 @@
#include <debug.h>
#include <mmio.h>
#include <plat_arm.h>
-#include <platform_def.h>
#include <platform.h>
+#include <platform_def.h>
+#include <romlib.h>
#include <secure_partition.h>
/* Weak definitions may be overridden in specific ARM standard platform */
@@ -24,63 +25,45 @@
#pragma weak plat_get_syscnt_freq2
#endif
+
+void arm_setup_romlib(void)
+{
+#if USE_ROMLIB
+ if (!rom_lib_init(ROMLIB_VERSION))
+ panic();
+#endif
+}
+
/*
* Set up the page tables for the generic and platform-specific memory regions.
- * The extents of the generic memory regions are specified by the function
- * arguments and consist of:
- * - Trusted SRAM seen by the BL image;
+ * The size of the Trusted SRAM seen by the BL image must be specified as well
+ * as an array specifying the generic memory regions which can be;
* - Code section;
* - Read-only data section;
* - Coherent memory region, if applicable.
*/
-void arm_setup_page_tables(uintptr_t total_base,
- size_t total_size,
- uintptr_t code_start,
- uintptr_t code_limit,
- uintptr_t rodata_start,
- uintptr_t rodata_limit
-#if USE_COHERENT_MEM
- ,
- uintptr_t coh_start,
- uintptr_t coh_limit
-#endif
- )
+
+void arm_setup_page_tables(const mmap_region_t bl_regions[],
+ const mmap_region_t plat_regions[])
{
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+ const mmap_region_t *regions = bl_regions;
+
+ while (regions->size != 0U) {
+ VERBOSE("Region: 0x%lx - 0x%lx has attributes 0x%x\n",
+ regions->base_va,
+ (regions->base_va + regions->size),
+ regions->attr);
+ regions++;
+ }
+#endif
/*
* Map the Trusted SRAM with appropriate memory attributes.
* Subsequent mappings will adjust the attributes for specific regions.
*/
- VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
- (void *) total_base, (void *) (total_base + total_size));
- mmap_add_region(total_base, total_base,
- total_size,
- MT_MEMORY | MT_RW | MT_SECURE);
-
- /* Re-map the code section */
- VERBOSE("Code region: %p - %p\n",
- (void *) code_start, (void *) code_limit);
- mmap_add_region(code_start, code_start,
- code_limit - code_start,
- MT_CODE | MT_SECURE);
-
- /* Re-map the read-only data section */
- VERBOSE("Read-only data region: %p - %p\n",
- (void *) rodata_start, (void *) rodata_limit);
- mmap_add_region(rodata_start, rodata_start,
- rodata_limit - rodata_start,
- MT_RO_DATA | MT_SECURE);
-
-#if USE_COHERENT_MEM
- /* Re-map the coherent memory region */
- VERBOSE("Coherent region: %p - %p\n",
- (void *) coh_start, (void *) coh_limit);
- mmap_add_region(coh_start, coh_start,
- coh_limit - coh_start,
- MT_DEVICE | MT_RW | MT_SECURE);
-#endif
-
+ mmap_add(bl_regions);
/* Now (re-)map the platform-specific memory regions */
- mmap_add(plat_arm_get_mmap());
+ mmap_add(plat_regions);
/* Create the page tables to reflect the above mappings */
init_xlat_tables();
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index 67b574de6..d8eda35b6 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -185,8 +185,7 @@ include lib/libfdt/libfdt.mk
DYN_CFG_SOURCES += plat/arm/common/arm_dyn_cfg.c \
plat/arm/common/arm_dyn_cfg_helpers.c \
- common/fdt_wrappers.c \
- ${LIBFDT_SRCS}
+ common/fdt_wrappers.c
BL1_SOURCES += ${DYN_CFG_SOURCES}
BL2_SOURCES += ${DYN_CFG_SOURCES}
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 118bd2628..b9c73f0b0 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -110,7 +110,7 @@ void arm_bl2_dyn_cfg_init(void)
return;
}
- err = arm_dyn_tb_fw_cfg_init((void *)tb_fw_cfg_dtb, &tb_fw_node);
+ err = arm_dyn_tb_fw_cfg_init(tb_fw_cfg_dtb, &tb_fw_node);
if (err < 0) {
ERROR("Invalid TB_FW_CONFIG passed from BL1\n");
panic();
@@ -125,7 +125,7 @@ void arm_bl2_dyn_cfg_init(void)
continue;
}
- err = arm_dyn_get_config_load_info((void *)tb_fw_cfg_dtb, tb_fw_node,
+ err = arm_dyn_get_config_load_info(tb_fw_cfg_dtb, tb_fw_node,
config_ids[i], &image_base, &image_size);
if (err < 0) {
VERBOSE("Couldn't find config_id %d load info in TB_FW_CONFIG\n",
@@ -171,7 +171,7 @@ void arm_bl2_dyn_cfg_init(void)
#if TRUSTED_BOARD_BOOT && defined(DYN_DISABLE_AUTH)
uint32_t disable_auth = 0;
- err = arm_dyn_get_disable_auth((void *)tb_fw_cfg_dtb, tb_fw_node,
+ err = arm_dyn_get_disable_auth(tb_fw_cfg_dtb, tb_fw_node,
&disable_auth);
if (err < 0)
return;
diff --git a/plat/arm/common/arm_err.c b/plat/arm/common/arm_err.c
index 59c586181..66568e7dc 100644
--- a/plat/arm/common/arm_err.c
+++ b/plat/arm/common/arm_err.c
@@ -5,12 +5,12 @@
*/
#include <arch_helpers.h>
-#include <board_arm_def.h>
#include <console.h>
#include <debug.h>
#include <errno.h>
#include <norflash.h>
#include <platform.h>
+#include <platform_def.h>
#include <stdint.h>
/*
diff --git a/plat/arm/common/arm_nor_psci_mem_protect.c b/plat/arm/common/arm_nor_psci_mem_protect.c
index c01e4ed5c..1b0b1da66 100644
--- a/plat/arm/common/arm_nor_psci_mem_protect.c
+++ b/plat/arm/common/arm_nor_psci_mem_protect.c
@@ -51,14 +51,14 @@ int arm_psci_read_mem_protect(int *enabled)
******************************************************************************/
int arm_nor_psci_write_mem_protect(int val)
{
- int enable = (val != 0);
+ int enable = (val != 0) ? 1 : 0;
if (nor_unlock(PLAT_ARM_MEM_PROT_ADDR) != 0) {
ERROR("unlocking memory protect variable\n");
return -1;
}
- if (enable != 0) {
+ if (enable == 1) {
/*
* If we want to write a value different than 0
* then we have to erase the full block because
@@ -117,14 +117,14 @@ void arm_nor_psci_do_static_mem_protect(void)
{
int enable;
- arm_psci_read_mem_protect(&enable);
+ (void) arm_psci_read_mem_protect(&enable);
if (enable == 0)
return;
INFO("PSCI: Overwriting non secure memory\n");
clear_mem_regions(arm_ram_ranges,
ARRAY_SIZE(arm_ram_ranges));
- arm_nor_psci_write_mem_protect(0);
+ (void) arm_nor_psci_write_mem_protect(0);
}
/*******************************************************************************
diff --git a/plat/arm/common/arm_pm.c b/plat/arm/common/arm_pm.c
index d0350d6c5..4257d3cd3 100644
--- a/plat/arm/common/arm_pm.c
+++ b/plat/arm/common/arm_pm.c
@@ -18,10 +18,6 @@
#pragma weak plat_arm_psci_override_pm_ops
#pragma weak plat_arm_program_trusted_mailbox
-#if ARM_RECOM_STATE_ID_ENC
-extern unsigned int arm_pm_idle_states[];
-#endif /* __ARM_RECOM_STATE_ID_ENC__ */
-
#if !ARM_RECOM_STATE_ID_ENC
/*******************************************************************************
* ARM standard platform handler called to check the validity of the power state
@@ -30,11 +26,11 @@ extern unsigned int arm_pm_idle_states[];
int arm_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
- int pstate = psci_get_pstate_type(power_state);
- int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
- int i;
+ unsigned int pstate = psci_get_pstate_type(power_state);
+ unsigned int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+ unsigned int i;
- assert(req_state);
+ assert(req_state > 0U);
if (pwr_lvl > PLAT_MAX_PWR_LVL)
return PSCI_E_INVALID_PARAMS;
@@ -59,7 +55,7 @@ int arm_validate_power_state(unsigned int power_state,
/*
* We expect the 'state id' to be zero.
*/
- if (psci_get_pstate_id(power_state))
+ if (psci_get_pstate_id(power_state) != 0U)
return PSCI_E_INVALID_PARAMS;
return PSCI_E_SUCCESS;
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index bb5b5c6b9..e450c6f94 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -64,9 +64,9 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
/*
* Pointers used in execution state switch are all 32 bits wide
*/
- return arm_execution_state_switch(smc_fid, (uint32_t) x1,
- (uint32_t) x2, (uint32_t) x3, (uint32_t) x4,
- handle);
+ return (uintptr_t) arm_execution_state_switch(smc_fid,
+ (uint32_t) x1, (uint32_t) x2, (uint32_t) x3,
+ (uint32_t) x4, handle);
}
case ARM_SIP_SVC_CALL_COUNT:
diff --git a/plat/arm/common/arm_tzc_dmc500.c b/plat/arm/common/arm_tzc_dmc500.c
index 89c502cce..8cb81e7ae 100644
--- a/plat/arm/common/arm_tzc_dmc500.c
+++ b/plat/arm/common/arm_tzc_dmc500.c
@@ -7,6 +7,7 @@
#include <arm_def.h>
#include <assert.h>
#include <debug.h>
+#include <plat_arm.h>
#include <platform_def.h>
#include <tzc_dmc500.h>
diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/execution_state_switch.c
index 22d552ad9..b12d82c15 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/execution_state_switch.c
@@ -11,6 +11,7 @@
#include <plat_arm.h>
#include <psci.h>
#include <smccc_helpers.h>
+#include <stdbool.h>
#include <string.h>
#include <utils.h>
@@ -39,7 +40,8 @@ int arm_execution_state_switch(unsigned int smc_fid,
{
/* Execution state can be switched only if EL3 is AArch64 */
#ifdef AARCH64
- int caller_64, from_el2, el, endianness, thumb = 0;
+ bool caller_64, thumb = false, from_el2;
+ unsigned int el, endianness;
u_register_t spsr, pc, scr, sctlr;
entry_point_info_t ep;
cpu_context_t *ctx = (cpu_context_t *) handle;
@@ -50,7 +52,7 @@ int arm_execution_state_switch(unsigned int smc_fid,
/*
* Disallow state switch if any of the secondaries have been brought up.
*/
- if (psci_secondaries_brought_up())
+ if (psci_secondaries_brought_up() != 0)
goto exec_denied;
spsr = read_ctx_reg(el3_ctx, CTX_SPSR_EL3);
@@ -61,20 +63,20 @@ int arm_execution_state_switch(unsigned int smc_fid,
* If the call originated from AArch64, expect 32-bit pointers when
* switching to AArch32.
*/
- if ((pc_hi != 0) || (cookie_hi != 0))
+ if ((pc_hi != 0U) || (cookie_hi != 0U))
goto invalid_param;
pc = pc_lo;
/* Instruction state when entering AArch32 */
- thumb = pc & 1;
+ thumb = (pc & 1U) != 0U;
} else {
/* Construct AArch64 PC */
pc = (((u_register_t) pc_hi) << 32) | pc_lo;
}
/* Make sure PC is 4-byte aligned, except for Thumb */
- if ((pc & 0x3) && !thumb)
+ if (((pc & 0x3U) != 0U) && !thumb)
goto invalid_param;
/*
@@ -95,7 +97,7 @@ int arm_execution_state_switch(unsigned int smc_fid,
* Disallow switching state if there's a Hypervisor in place;
* this request must be taken up with the Hypervisor instead.
*/
- if (scr & SCR_HCE_BIT)
+ if ((scr & SCR_HCE_BIT) != 0U)
goto exec_denied;
}
@@ -105,11 +107,11 @@ int arm_execution_state_switch(unsigned int smc_fid,
* directly.
*/
sctlr = from_el2 ? read_sctlr_el2() : read_sctlr_el1();
- endianness = !!(sctlr & SCTLR_EE_BIT);
+ endianness = ((sctlr & SCTLR_EE_BIT) != 0U) ? 1U : 0U;
/* Construct SPSR for the exception state we're about to switch to */
if (caller_64) {
- int impl;
+ unsigned long long impl;
/*
* Switching from AArch64 to AArch32. Ensure this CPU implements
@@ -121,7 +123,8 @@ int arm_execution_state_switch(unsigned int smc_fid,
/* Return to the equivalent AArch32 privilege level */
el = from_el2 ? MODE32_hyp : MODE32_svc;
- spsr = SPSR_MODE32(el, thumb ? SPSR_T_THUMB : SPSR_T_ARM,
+ spsr = SPSR_MODE32((u_register_t) el,
+ thumb ? SPSR_T_THUMB : SPSR_T_ARM,
endianness, DISABLE_ALL_EXCEPTIONS);
} else {
/*
@@ -130,7 +133,8 @@ int arm_execution_state_switch(unsigned int smc_fid,
* raised), it's safe to assume AArch64 is also implemented.
*/
el = from_el2 ? MODE_EL2 : MODE_EL1;
- spsr = SPSR_64(el, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ spsr = SPSR_64((u_register_t) el, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
}
/*
@@ -143,10 +147,11 @@ int arm_execution_state_switch(unsigned int smc_fid,
*/
zeromem(&ep, sizeof(ep));
ep.pc = pc;
- ep.spsr = spsr;
+ ep.spsr = (uint32_t) spsr;
SET_PARAM_HEAD(&ep, PARAM_EP, VERSION_1,
- ((endianness ? EP_EE_BIG : EP_EE_LITTLE) | NON_SECURE |
- EP_ST_DISABLE));
+ ((unsigned int) ((endianness != 0U) ? EP_EE_BIG :
+ EP_EE_LITTLE)
+ | NON_SECURE | EP_ST_DISABLE));
/*
* Re-initialize the system register context, and exit EL3 as if for the
diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c
index b42e35f3a..10c191423 100644
--- a/plat/arm/common/sp_min/arm_sp_min_setup.c
+++ b/plat/arm/common/sp_min/arm_sp_min_setup.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <bl_common.h>
#include <console.h>
#include <debug.h>
#include <mmio.h>
@@ -13,8 +14,6 @@
#include <platform_def.h>
#include <platform_sp_min.h>
-#define BL32_END (uintptr_t)(&__BL32_END__)
-
static entry_point_info_t bl33_image_ep_info;
/* Weak definitions may be overridden in specific ARM standard platform */
@@ -22,6 +21,11 @@ static entry_point_info_t bl33_image_ep_info;
#pragma weak sp_min_plat_arch_setup
#pragma weak plat_arm_sp_min_early_platform_setup
+#define MAP_BL_SP_MIN_TOTAL MAP_REGION_FLAT( \
+ BL32_BASE, \
+ BL32_END - BL32_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
/*
* Check that BL32_BASE is above ARM_TB_FW_CONFIG_LIMIT. The reserved page
* is required for SOC_FW_CONFIG/TOS_FW_CONFIG passed from BL2.
@@ -176,7 +180,7 @@ void sp_min_platform_setup(void)
/* Enable and initialize the System level generic timer */
mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0) | CNTCR_EN);
+ CNTCR_FCREQ(0U) | CNTCR_EN);
/* Allow access to the System counter timer module */
arm_configure_sys_timer();
@@ -196,18 +200,16 @@ void sp_min_plat_runtime_setup(void)
******************************************************************************/
void sp_min_plat_arch_setup(void)
{
-
- arm_setup_page_tables(BL32_BASE,
- (BL32_END - BL32_BASE),
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
+ const mmap_region_t bl_regions[] = {
+ MAP_BL_SP_MIN_TOTAL,
+ ARM_MAP_BL_RO,
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ ARM_MAP_BL_COHERENT_RAM,
#endif
- );
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
}
diff --git a/plat/arm/common/tsp/arm_tsp_setup.c b/plat/arm/common/tsp/arm_tsp_setup.c
index 16125ad4f..2d42d8e00 100644
--- a/plat/arm/common/tsp/arm_tsp_setup.c
+++ b/plat/arm/common/tsp/arm_tsp_setup.c
@@ -5,6 +5,7 @@
*/
#include <arm_def.h>
+#include <assert.h>
#include <bl_common.h>
#include <console.h>
#include <debug.h>
@@ -20,6 +21,10 @@
#pragma weak tsp_platform_setup
#pragma weak tsp_plat_arch_setup
+#define MAP_BL_TSP_TOTAL MAP_REGION_FLAT( \
+ BL32_BASE, \
+ BL32_END - BL32_BASE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
/*******************************************************************************
* Initialize the UART
@@ -69,16 +74,17 @@ void tsp_platform_setup(void)
******************************************************************************/
void tsp_plat_arch_setup(void)
{
- arm_setup_page_tables(BL32_BASE,
- (BL32_END - BL32_BASE),
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END
#if USE_COHERENT_MEM
- , BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
+ /* Ensure ARM platforms dont use coherent memory in TSP */
+ assert((BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE) == 0U);
#endif
- );
+
+ const mmap_region_t bl_regions[] = {
+ MAP_BL_TSP_TOTAL,
+ ARM_MAP_BL_RO,
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
}
diff --git a/plat/arm/css/common/css_topology.c b/plat/arm/css/common/css_topology.c
index 42f94554d..d1f1c98f4 100644
--- a/plat/arm/css/common/css_topology.c
+++ b/plat/arm/css/common/css_topology.c
@@ -23,6 +23,12 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
if (arm_check_mpidr(mpidr) == 0) {
#if ARM_PLAT_MT
assert((read_mpidr_el1() & MPIDR_MT_MASK) != 0);
+
+ /*
+ * The DTB files don't provide the MT bit in the mpidr argument
+ * so set it manually before calculating core position
+ */
+ mpidr |= MPIDR_MT_MASK;
#endif
return plat_arm_calc_core_pos(mpidr);
}
diff --git a/plat/arm/css/drivers/scp/css_pm_scmi.c b/plat/arm/css/drivers/scp/css_pm_scmi.c
index 703226771..cb39da27e 100644
--- a/plat/arm/css/drivers/scp/css_pm_scmi.c
+++ b/plat/arm/css/drivers/scp/css_pm_scmi.c
@@ -79,8 +79,7 @@ ARM_INSTANTIATE_LOCK;
*/
void css_scp_suspend(const struct psci_power_state *target_state)
{
- int lvl, ret;
- uint32_t scmi_pwr_state = 0;
+ int ret;
/* At least power domain level 0 should be specified to be suspended */
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
@@ -99,7 +98,9 @@ void css_scp_suspend(const struct psci_power_state *target_state)
}
return;
}
-
+#if !HW_ASSISTED_COHERENCY
+ int lvl;
+ uint32_t scmi_pwr_state = 0;
/*
* If we reach here, then assert that power down at system power domain
* level is running.
@@ -136,6 +137,7 @@ void css_scp_suspend(const struct psci_power_state *target_state)
ret);
panic();
}
+#endif
}
/*
diff --git a/plat/arm/css/drivers/scp/css_scp.h b/plat/arm/css/drivers/scp/css_scp.h
index 671612a80..44dfbca05 100644
--- a/plat/arm/css/drivers/scp/css_scp.h
+++ b/plat/arm/css/drivers/scp/css_scp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
#include <cassert.h>
#include <platform_def.h>
-#include <types.h>
+#include <stdint.h>
/* Forward declarations */
struct psci_power_state;
diff --git a/plat/arm/css/sgi/aarch64/sgi_helper.S b/plat/arm/css/sgi/aarch64/sgi_helper.S
index aaa51560f..dd0fc5bbd 100644
--- a/plat/arm/css/sgi/aarch64/sgi_helper.S
+++ b/plat/arm/css/sgi/aarch64/sgi_helper.S
@@ -7,28 +7,10 @@
#include <arch.h>
#include <asm_macros.S>
#include <platform_def.h>
+#include <cortex_a75.h>
- .globl plat_is_my_cpu_primary
.globl plat_arm_calc_core_pos
-
- /* -----------------------------------------------------
- * unsigned int plat_is_my_cpu_primary (void);
- *
- * Find out whether the current cpu is the primary
- * cpu (applicable only after a cold boot)
- * -----------------------------------------------------
- */
-func plat_is_my_cpu_primary
- mov x9, x30
- bl plat_my_core_pos
- ldr x1, =SGI_BOOT_CFG_ADDR
- ldr x1, [x1]
- ubfx x1, x1, #PLAT_CSS_PRIMARY_CPU_SHIFT, \
- #PLAT_CSS_PRIMARY_CPU_BIT_WIDTH
- cmp x0, x1
- cset w0, eq
- ret x9
-endfunc plat_is_my_cpu_primary
+ .globl plat_reset_handler
/* -----------------------------------------------------
* unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
@@ -65,3 +47,41 @@ func plat_arm_calc_core_pos
madd x0, x1, x5, x0
ret
endfunc plat_arm_calc_core_pos
+
+ /* ------------------------------------------------------
+ * Helper macro that reads the part number of the current
+ * CPU and jumps to the given label if it matches the CPU
+ * MIDR provided.
+ *
+ * Clobbers x0.
+ * -----------------------------------------------------
+ */
+ .macro jump_if_cpu_midr _cpu_midr, _label
+ mrs x0, midr_el1
+ ubfx x0, x0, MIDR_PN_SHIFT, #12
+ cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+ b.eq \_label
+ .endm
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the CPU MIDR and disable power down bit for
+ * that CPU.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ jump_if_cpu_midr CORTEX_A75_MIDR, A75
+ ret
+
+ /* -----------------------------------------------------
+ * Disable CPU power down bit in power control register
+ * -----------------------------------------------------
+ */
+A75:
+ mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
+ bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
+ msr CORTEX_A75_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc plat_reset_handler
diff --git a/plat/arm/css/sgi/include/platform_def.h b/plat/arm/css/sgi/include/platform_def.h
index 84ef2c424..c645d109e 100644
--- a/plat/arm/css/sgi/include/platform_def.h
+++ b/plat/arm/css/sgi/include/platform_def.h
@@ -4,15 +4,18 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arm_def.h>
+#include <arm_spm_def.h>
#include <board_arm_def.h>
#include <board_css_def.h>
#include <common_def.h>
#include <css_def.h>
#include <soc_css_def.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
@@ -57,7 +60,7 @@
#define PLAT_ARM_NSRAM_BASE 0x06000000
#define PLAT_ARM_NSRAM_SIZE 0x00080000 /* 512KB */
-#define PLAT_MAX_PWR_LVL 1
+#define PLAT_MAX_PWR_LVL U(1)
#define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \
CSS_IRQ_MHU
@@ -74,16 +77,60 @@
CSS_SGI_DEVICE_SIZE, \
MT_DEVICE | MT_RW | MT_SECURE)
-#define PLAT_CSS_SCP_COM_SHARED_MEM_BASE 0x45400000
-#define SGI_BOOT_CFG_ADDR 0x45410000
-#define PLAT_CSS_PRIMARY_CPU_SHIFT 8
-#define PLAT_CSS_PRIMARY_CPU_BIT_WIDTH 6
-
/* GIC related constants */
#define PLAT_ARM_GICD_BASE 0x30000000
#define PLAT_ARM_GICC_BASE 0x2C000000
#define PLAT_ARM_GICR_BASE 0x300C0000
+/* Map the secure region for access from S-EL0 */
+#define PLAT_ARM_SECURE_MAP_DEVICE MAP_REGION_FLAT( \
+ SOC_CSS_DEVICE_BASE, \
+ SOC_CSS_DEVICE_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE | MT_USER)
+
+#if RAS_EXTENSION
+/* Allocate 128KB for CPER buffers */
+#define PLAT_SP_BUF_BASE ULL(0x20000)
+
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
+ ARM_SP_IMAGE_NS_BUF_SIZE + \
+ PLAT_SP_BUF_BASE)
+
+/* Platform specific SMC FID's used for RAS */
+#define SP_DMC_ERROR_INJECT_EVENT_AARCH64 0xC4000042
+#define SP_DMC_ERROR_INJECT_EVENT_AARCH32 0x84000042
+
+#define SP_DMC_ERROR_OVERFLOW_EVENT_AARCH64 0xC4000043
+#define SP_DMC_ERROR_OVERFLOW_EVENT_AARCH32 0x84000043
+
+#define SP_DMC_ERROR_ECC_EVENT_AARCH64 0xC4000044
+#define SP_DMC_ERROR_ECC_EVENT_AARCH32 0x84000044
+
+/* ARM SDEI dynamic shared event numbers */
+#define SGI_SDEI_DS_EVENT_0 804
+#define SGI_SDEI_DS_EVENT_1 805
+
+#define PLAT_ARM_PRIVATE_SDEI_EVENTS \
+ SDEI_DEFINE_EVENT_0(ARM_SDEI_SGI), \
+ SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_0, SDEI_MAPF_CRITICAL), \
+ SDEI_EXPLICIT_EVENT(SGI_SDEI_DS_EVENT_1, SDEI_MAPF_CRITICAL),
+#define PLAT_ARM_SHARED_SDEI_EVENTS
+
+#define ARM_SP_CPER_BUF_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
+ ARM_SP_IMAGE_NS_BUF_SIZE)
+#define ARM_SP_CPER_BUF_SIZE ULL(0x20000)
+#define ARM_SP_CPER_BUF_MMAP MAP_REGION2( \
+ ARM_SP_CPER_BUF_BASE, \
+ ARM_SP_CPER_BUF_BASE, \
+ ARM_SP_CPER_BUF_SIZE, \
+ MT_RW_DATA | MT_NS | MT_USER, \
+ PAGE_SIZE)
+
+#else
+#define PLAT_ARM_SP_IMAGE_STACK_BASE (ARM_SP_IMAGE_NS_BUF_BASE + \
+ ARM_SP_IMAGE_NS_BUF_SIZE)
+#endif /* RAS_EXTENSION */
+
/* Platform ID address */
#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
#ifndef __ASSEMBLY__
@@ -108,4 +155,4 @@
V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/arm/css/sgi/include/sgi_ras.h b/plat/arm/css/sgi/include/sgi_ras.h
new file mode 100644
index 000000000..b307b9c94
--- /dev/null
+++ b/plat/arm/css/sgi/include/sgi_ras.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGI_RAS__
+#define __SGI_RAS__
+
+/*
+ * Mapping the RAS interrupt with SDEI event number and the event
+ * id used with Standalone MM code
+ */
+struct sgi_ras_ev_map {
+ int ras_ev_num; /* RAS Event number */
+ int sdei_ev_num; /* SDEI Event number */
+ int intr; /* Physical intr number */
+};
+
+int sgi_ras_intr_handler_setup(void);
+
+#endif /* __SGI_RAS__ */
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index f4092f389..74d255cba 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -4,10 +4,22 @@
# SPDX-License-Identifier: BSD-3-Clause
#
+CSS_USE_SCMI_SDS_DRIVER := 1
+
ENABLE_PLAT_COMPAT := 0
CSS_ENT_BASE := plat/arm/css/sgi
+RAS_EXTENSION := 0
+
+ENABLE_SPM := 0
+
+SDEI_SUPPORT := 0
+
+EL3_EXCEPTION_HANDLING := 0
+
+HANDLE_EA_EL3_FIRST := 0
+
INTERCONNECT_SOURCES := ${CSS_ENT_BASE}/sgi_interconnect.c
PLAT_INCLUDES += -I${CSS_ENT_BASE}/include
@@ -40,6 +52,10 @@ BL31_SOURCES += ${ENT_CPU_SOURCES} \
${CSS_ENT_BASE}/sgi_topology.c \
${CSS_ENT_BASE}/sgi_plat_config.c
+ifeq (${RAS_EXTENSION},1)
+BL31_SOURCES += ${CSS_ENT_BASE}/sgi_ras.c
+endif
+
# Add the FDT_SOURCES and options for Dynamic Config
FDT_SOURCES += ${CSS_ENT_BASE}/fdts/${PLAT}_tb_fw_config.dts
TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb
diff --git a/plat/arm/css/sgi/sgi_bl31_setup.c b/plat/arm/css/sgi/sgi_bl31_setup.c
index 20908463f..09f493edd 100644
--- a/plat/arm/css/sgi/sgi_bl31_setup.c
+++ b/plat/arm/css/sgi/sgi_bl31_setup.c
@@ -8,6 +8,7 @@
#include <debug.h>
#include <plat_arm.h>
#include <sgi_plat_config.h>
+#include <sgi_ras.h>
void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
@@ -17,3 +18,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
}
+
+void bl31_platform_setup(void)
+{
+ arm_bl31_platform_setup();
+
+#if RAS_EXTENSION
+ sgi_ras_intr_handler_setup();
+#endif
+}
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 7e1d4e207..6aa76efe0 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -5,11 +5,14 @@
*/
#include <arm_def.h>
+#include <arm_spm_def.h>
#include <bl_common.h>
#include <ccn.h>
#include <debug.h>
#include <plat_arm.h>
+#include <platform_def.h>
#include <platform.h>
+#include <secure_partition.h>
#include "../../../../bl1/bl1_private.h"
#if USE_COHERENT_MEM
@@ -58,6 +61,9 @@ const mmap_region_t plat_arm_mmap[] = {
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
+#if ENABLE_SPM
+ ARM_SP_IMAGE_MMAP,
+#endif
{0}
};
#endif
@@ -67,8 +73,73 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
CSS_SGI_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
+#if ENABLE_SPM
+ ARM_SPM_BUF_EL3_MMAP,
+#endif
{0}
};
+
+#if ENABLE_SPM && defined(IMAGE_BL31)
+const mmap_region_t plat_arm_secure_partition_mmap[] = {
+ PLAT_ARM_SECURE_MAP_DEVICE,
+ ARM_SP_IMAGE_MMAP,
+ ARM_SP_IMAGE_NS_BUF_MMAP,
+ ARM_SP_CPER_BUF_MMAP,
+ ARM_SP_IMAGE_RW_MMAP,
+ ARM_SPM_BUF_EL0_MMAP,
+ {0}
+};
+#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
#endif
ARM_CASSERT_MMAP
+
+#if ENABLE_SPM && defined(IMAGE_BL31)
+/*
+ * Boot information passed to a secure partition during initialisation. Linear
+ * indices in MP information will be filled at runtime.
+ */
+static secure_partition_mp_info_t sp_mp_info[] = {
+ [0] = {0x81000000, 0},
+ [1] = {0x81000100, 0},
+ [2] = {0x81000200, 0},
+ [3] = {0x81000300, 0},
+ [4] = {0x81010000, 0},
+ [5] = {0x81010100, 0},
+ [6] = {0x81010200, 0},
+ [7] = {0x81010300, 0},
+};
+
+const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+ .h.type = PARAM_SP_IMAGE_BOOT_INFO,
+ .h.version = VERSION_1,
+ .h.size = sizeof(secure_partition_boot_info_t),
+ .h.attr = 0,
+ .sp_mem_base = ARM_SP_IMAGE_BASE,
+ .sp_mem_limit = ARM_SP_IMAGE_LIMIT,
+ .sp_image_base = ARM_SP_IMAGE_BASE,
+ .sp_stack_base = PLAT_SP_IMAGE_STACK_BASE,
+ .sp_heap_base = ARM_SP_IMAGE_HEAP_BASE,
+ .sp_ns_comm_buf_base = ARM_SP_IMAGE_NS_BUF_BASE,
+ .sp_shared_buf_base = PLAT_SPM_BUF_BASE,
+ .sp_image_size = ARM_SP_IMAGE_SIZE,
+ .sp_pcpu_stack_size = PLAT_SP_IMAGE_STACK_PCPU_SIZE,
+ .sp_heap_size = ARM_SP_IMAGE_HEAP_SIZE,
+ .sp_ns_comm_buf_size = ARM_SP_IMAGE_NS_BUF_SIZE,
+ .sp_shared_buf_size = PLAT_SPM_BUF_SIZE,
+ .num_sp_mem_regions = ARM_SP_IMAGE_NUM_MEM_REGIONS,
+ .num_cpus = PLATFORM_CORE_COUNT,
+ .mp_info = &sp_mp_info[0],
+};
+
+const struct mmap_region *plat_get_secure_partition_mmap(void *cookie)
+{
+ return plat_arm_secure_partition_mmap;
+}
+
+const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+ void *cookie)
+{
+ return &plat_arm_secure_partition_boot_info;
+}
+#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
new file mode 100644
index 000000000..ac4610d21
--- /dev/null
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_spm_def.h>
+#include <assert.h>
+#include <context_mgmt.h>
+#include <interrupt_mgmt.h>
+#include <mm_svc.h>
+#include <ras.h>
+#include <sgi_ras.h>
+#include <platform.h>
+#include <spm_svc.h>
+#include <sdei.h>
+#include <string.h>
+
+static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
+ int probe_data,
+ const struct err_handler_data *const data);
+struct efi_guid {
+ uint32_t data1;
+ uint16_t data2;
+ uint16_t data3;
+ uint8_t data4[8];
+};
+
+typedef struct mm_communicate_header {
+ struct efi_guid header_guid;
+ size_t message_len;
+ uint8_t data[8];
+} mm_communicate_header_t;
+
+struct sgi_ras_ev_map sgi575_ras_map[] = {
+
+ /* DMC620 error overflow interrupt*/
+ {SP_DMC_ERROR_OVERFLOW_EVENT_AARCH64, SGI_SDEI_DS_EVENT_1, 33},
+
+ /* DMC620 error ECC error interrupt*/
+ {SP_DMC_ERROR_ECC_EVENT_AARCH64, SGI_SDEI_DS_EVENT_0, 35},
+};
+
+#define SGI575_RAS_MAP_SIZE ARRAY_SIZE(sgi575_ras_map)
+
+struct err_record_info sgi_err_records[] = {
+ {
+ .handler = &sgi_ras_intr_handler,
+ },
+};
+
+struct ras_interrupt sgi_ras_interrupts[] = {
+ {
+ .intr_number = 33,
+ .err_record = &sgi_err_records[0],
+ },
+ {
+ .intr_number = 35,
+ .err_record = &sgi_err_records[0],
+ }
+};
+
+REGISTER_ERR_RECORD_INFO(sgi_err_records);
+REGISTER_RAS_INTERRUPTS(sgi_ras_interrupts);
+
+static struct sgi_ras_ev_map *plat_sgi_get_ras_ev_map(void)
+{
+ return sgi575_ras_map;
+}
+
+static int plat_sgi_get_ras_ev_map_size(void)
+{
+ return SGI575_RAS_MAP_SIZE;
+}
+
+/*
+ * Find event mapping for a given interrupt number: On success, returns pointer
+ * to the event mapping. On error, returns NULL.
+ */
+static struct sgi_ras_ev_map *find_ras_event_map_by_intr(uint32_t intr_num)
+{
+ struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
+ int i;
+ int size = plat_sgi_get_ras_ev_map_size();
+
+ for (i = 0; i < size; i++) {
+ if (map->intr == intr_num)
+ return map;
+
+ map++;
+ }
+
+ return NULL;
+}
+
+static void sgi_ras_intr_configure(int intr)
+{
+ plat_ic_set_interrupt_type(intr, INTR_TYPE_EL3);
+ plat_ic_set_interrupt_priority(intr, PLAT_RAS_PRI);
+ plat_ic_clear_interrupt_pending(intr);
+ plat_ic_set_spi_routing(intr, INTR_ROUTING_MODE_ANY,
+ (u_register_t)read_mpidr_el1());
+ plat_ic_enable_interrupt(intr);
+}
+
+static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
+ int probe_data,
+ const struct err_handler_data *const data)
+{
+ struct sgi_ras_ev_map *ras_map;
+ mm_communicate_header_t *header;
+ uint32_t intr;
+
+ cm_el1_sysregs_context_save(NON_SECURE);
+ intr = data->interrupt;
+
+ /*
+ * Find if this is a RAS interrupt. There must be an event against
+ * this interrupt
+ */
+ ras_map = find_ras_event_map_by_intr(intr);
+ assert(ras_map);
+
+ /*
+ * Populate the MM_COMMUNICATE payload to share the
+ * event info with StandaloneMM code. This allows us to use
+ * MM_COMMUNICATE as a common entry mechanism into S-EL0. The
+ * header data will be parsed in StandaloneMM to process the
+ * corresponding event.
+ *
+ * TBD - Currently, the buffer allocated by SPM for communication
+ * between EL3 and S-EL0 is being used(PLAT_SPM_BUF_BASE). But this
+ * should happen via a dynamic mem allocation, which should be
+ * managed by SPM -- the individual platforms then call the mem
+ * alloc api to get memory for the payload.
+ */
+ header = (void *) PLAT_SPM_BUF_BASE;
+ memset(header, 0, sizeof(*header));
+ memcpy(&header->data, &ras_map->ras_ev_num,
+ sizeof(ras_map->ras_ev_num));
+ header->message_len = 4;
+
+ spm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+ plat_my_core_pos());
+
+ /*
+ * Do an EOI of the RAS interuupt. This allows the
+ * sdei event to be dispatched at the SDEI event's
+ * priority.
+ */
+ plat_ic_end_of_interrupt(intr);
+
+ /* Dispatch the event to the SDEI client */
+ sdei_dispatch_event(ras_map->sdei_ev_num);
+
+ return 0;
+}
+
+int sgi_ras_intr_handler_setup(void)
+{
+ int i;
+ struct sgi_ras_ev_map *map = plat_sgi_get_ras_ev_map();
+ int size = plat_sgi_get_ras_ev_map_size();
+
+ for (i = 0; i < size; i++) {
+ sgi_ras_intr_configure(map->intr);
+ map++;
+ }
+
+ INFO("SGI: RAS Interrupt Handler successfully registered\n");
+
+ return 0;
+}
diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c
index 1d2e027df..3f6357bd1 100644
--- a/plat/arm/css/sgi/sgi_topology.c
+++ b/plat/arm/css/sgi/sgi_topology.c
@@ -42,3 +42,12 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr)
{
return sgi_topology.plat_cluster_core_count;
}
+
+/*******************************************************************************
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ ******************************************************************************/
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+};
diff --git a/plat/arm/css/sgm/aarch64/css_sgm_helpers.S b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
new file mode 100644
index 000000000..d9b3df68d
--- /dev/null
+++ b/plat/arm/css/sgm/aarch64/css_sgm_helpers.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <cortex_a75.h>
+#include <cortex_a55.h>
+
+ .globl plat_arm_calc_core_pos
+ .globl plat_reset_handler
+
+ /* ---------------------------------------------------------------------
+ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr)
+ *
+ * Function to calculate the core position on FVP.
+ *
+ * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) +
+ * (CPUId * MAX_PE_PER_CPU) +
+ * ThreadId
+ *
+ * which can be simplified as:
+ *
+ * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU)
+ * + ThreadId
+ * ---------------------------------------------------------------------
+ */
+func plat_arm_calc_core_pos
+ /*
+ * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it
+ * look as if in a multi-threaded implementation.
+ */
+ tst x0, #MPIDR_MT_MASK
+ lsr x3, x0, #MPIDR_AFFINITY_BITS
+ csel x3, x3, x0, eq
+
+ /* Extract individual affinity fields from MPIDR */
+ ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS
+ ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS
+
+ /* Compute linear position */
+ mov x4, #PLAT_MAX_CPUS_PER_CLUSTER
+ madd x1, x2, x4, x1
+ mov x5, #PLAT_MAX_PE_PER_CPU
+ madd x0, x1, x5, x0
+ ret
+endfunc plat_arm_calc_core_pos
+
+ /* ------------------------------------------------------
+ * Helper macro that reads the part number of the current
+ * CPU and jumps to the given label if it matches the CPU
+ * MIDR provided.
+ *
+ * Clobbers x0.
+ * -----------------------------------------------------
+ */
+ .macro jump_if_cpu_midr _cpu_midr, _label
+ mrs x0, midr_el1
+ ubfx x0, x0, MIDR_PN_SHIFT, #12
+ cmp w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
+ b.eq \_label
+ .endm
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler(void);
+ *
+ * Determine the CPU MIDR and disable power down bit for
+ * that CPU.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ jump_if_cpu_midr CORTEX_A75_MIDR, A75
+ jump_if_cpu_midr CORTEX_A55_MIDR, A55
+ ret
+
+ /* -----------------------------------------------------
+ * Disable CPU power down bit in power control register
+ * -----------------------------------------------------
+ */
+A75:
+ mrs x0, CORTEX_A75_CPUPWRCTLR_EL1
+ bic x0, x0, #CORTEX_A75_CORE_PWRDN_EN_MASK
+ msr CORTEX_A75_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+A55:
+ mrs x0, CORTEX_A55_CPUPWRCTLR_EL1
+ bic x0, x0, #CORTEX_A55_CORE_PWRDN_EN_MASK
+ msr CORTEX_A55_CPUPWRCTLR_EL1, x0
+ isb
+ ret
+endfunc plat_reset_handler
diff --git a/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
new file mode 100644
index 000000000..95025493b
--- /dev/null
+++ b/plat/arm/css/sgm/fdts/sgm_tb_fw_config.dts
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+ /* Platform Config */
+ plat_arm_bl2 {
+ compatible = "arm,tb_fw";
+ hw_config_addr = <0x0 0x83000000>;
+ hw_config_max_size = <0x01000000>;
+ };
+};
diff --git a/plat/arm/css/sgm/include/plat_macros.S b/plat/arm/css/sgm/include/plat_macros.S
new file mode 100644
index 000000000..d877ef880
--- /dev/null
+++ b/plat/arm/css/sgm/include/plat_macros.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <cci_macros.S>
+#include <css_macros.S>
+
+/* ---------------------------------------------
+ * The below required platform porting macro
+ * prints out relevant platform registers
+ * whenever an unhandled exception is taken in
+ * BL31.
+ * ---------------------------------------------
+ */
+.macro plat_crash_print_regs
+css_print_gic_regs
+print_cci_regs
+.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/arm/css/sgm/include/platform_oid.h b/plat/arm/css/sgm/include/platform_oid.h
new file mode 100644
index 000000000..18d41e3df
--- /dev/null
+++ b/plat/arm/css/sgm/include/platform_oid.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "../../../../../include/plat/arm/board/common/board_arm_oid.h"
+
+/*
+ * Required platform OIDs
+ * (Provided by included header)
+ */
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
new file mode 100644
index 000000000..2498430c4
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_BASE_PLATFORM_DEF_H__
+#define __SGM_BASE_PLATFORM_DEF_H__
+
+#include <arm_def.h>
+#include <board_arm_def.h>
+#include <board_css_def.h>
+#include <common_def.h>
+#include <css_def.h>
+#include <soc_css_def.h>
+#include <tzc400.h>
+#include <tzc_common.h>
+
+/* CPU topology */
+#define PLAT_ARM_CLUSTER_COUNT 1
+#define PLAT_ARM_CLUSTER_CORE_COUNT 8
+#define PLATFORM_CORE_COUNT PLAT_ARM_CLUSTER_CORE_COUNT
+
+#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
+#define PLAT_NUM_PWR_DOMAINS (ARM_SYSTEM_COUNT + \
+ PLAT_ARM_CLUSTER_COUNT + \
+ PLATFORM_CORE_COUNT)
+
+/*
+ * 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
+ * as Group 0 interrupts.
+ */
+#define PLAT_ARM_G1S_IRQ_PROPS(grp) \
+ CSS_G1S_IRQ_PROPS(grp), \
+ ARM_G1S_IRQ_PROPS(grp)
+
+#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp)
+
+/* GIC related constants */
+#define PLAT_ARM_GICD_BASE 0x30000000
+#define PLAT_ARM_GICR_BASE 0x300C0000
+#define PLAT_ARM_GICC_BASE 0x2c000000
+
+#define CSS_GIC_SIZE 0x00200000
+
+#define CSS_MAP_GIC_DEVICE MAP_REGION_FLAT( \
+ PLAT_ARM_GICD_BASE, \
+ CSS_GIC_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/* Platform ID address */
+#define SSC_VERSION (SSC_REG_BASE + SSC_VERSION_OFFSET)
+#ifndef __ASSEMBLY__
+/* SSC_VERSION related accessors */
+/* Returns the part number of the platform */
+#define GET_PLAT_PART_NUM \
+ GET_SSC_VERSION_PART_NUM(mmio_read_32(SSC_VERSION))
+/* Returns the configuration number of the platform */
+#define GET_PLAT_CONFIG_NUM \
+ GET_SSC_VERSION_CONFIG(mmio_read_32(SSC_VERSION))
+#endif /* __ASSEMBLY__ */
+
+
+/*************************************************************************
+ * Definitions common to all SGM CSS based platforms
+ *************************************************************************/
+
+/* TZC-400 related constants */
+#define PLAT_ARM_TZC_BASE 0x2a500000
+#define TZC_NSAID_ALL_AP 0 /* Note: Same as default NSAID!! */
+#define TZC_NSAID_HDLCD0 2
+#define TZC_NSAID_HDLCD1 3
+#define TZC_NSAID_GPU 9
+#define TZC_NSAID_VIDEO 10
+#define TZC_NSAID_DISP0 11
+#define TZC_NSAID_DISP1 12
+
+
+/*************************************************************************
+ * Required platform porting definitions common to all SGM CSS based
+ * platforms
+ *************************************************************************/
+
+/* MHU related constants */
+#define PLAT_CSS_MHU_BASE 0x2b1f0000
+
+#define PLAT_ARM_TRUSTED_ROM_BASE 0x00000000
+#define PLAT_ARM_TRUSTED_ROM_SIZE 0x00080000
+
+#define PLAT_ARM_CCI_BASE 0x2a000000
+
+/* Cluster to CCI slave mapping */
+#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 6
+#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 5
+
+/* System timer related constants */
+#define PLAT_ARM_NSTIMER_FRAME_ID 0
+
+/* TZC related constants */
+#define PLAT_ARM_TZC_NS_DEV_ACCESS ( \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD1) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_GPU) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIDEO) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP0) | \
+ TZC_REGION_ACCESS_RDWR(TZC_NSAID_DISP1))
+
+/* Display Processor register definitions to setup the NSAIDs */
+#define MALI_DP_BASE 0x2cc00000
+#define DP_NPROT_NSAID_OFFSET 0x1000c
+#define W_NPROT_NSAID_SHIFT 24
+#define LS_NPORT_NSAID_SHIFT 12
+
+/*
+ * Base address of the first memory region used for communication between AP
+ * and SCP. Used by the BootOverMHU and SCPI protocols.
+ */
+#if !CSS_USE_SCMI_SDS_DRIVER
+/*
+ * 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. 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
+#endif
+
+/*
+ * tspd support is conditional so enable this for CSS sgm platforms.
+ */
+#define SPD_tspd
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current
+ * SCP_BL2 size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x15000
+
+/*
+ * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current
+ * SCP_BL2U size plus a little space for growth.
+ */
+#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x15000
+
+/*
+ * Most platform porting definitions provided by included headers
+ */
+
+/*
+ * If ARM_BOARD_OPTIMISE_MEM=0 then use the default, unoptimised values
+ * defined for ARM development platforms.
+ */
+#if ARM_BOARD_OPTIMISE_MEM
+/*
+ * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the
+ * plat_arm_mmap array defined for each BL stage.
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+# define PLAT_ARM_MMAP_ENTRIES 7
+# else
+# define PLAT_ARM_MMAP_ENTRIES 6
+# endif /* TRUSTED_BOARD_BOOT */
+#elif IMAGE_BL2
+# define PLAT_ARM_MMAP_ENTRIES 8
+#elif IMAGE_BL2U
+# define PLAT_ARM_MMAP_ENTRIES 4
+#elif IMAGE_BL31
+# define PLAT_ARM_MMAP_ENTRIES 6
+#elif IMAGE_BL32
+# define PLAT_ARM_MMAP_ENTRIES 5
+#endif
+
+/*
+ * Platform specific page table and MMU setup constants
+ */
+#if IMAGE_BL1
+# if TRUSTED_BOARD_BOOT
+# define MAX_XLAT_TABLES 4
+# else
+# define MAX_XLAT_TABLES 3
+#endif
+#elif IMAGE_BL2
+# define MAX_XLAT_TABLES 4
+#elif IMAGE_BL2U
+# define MAX_XLAT_TABLES 4
+#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
+#endif
+
+/*
+ * 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 0xA000
+#else
+# define PLAT_ARM_MAX_BL1_RW_SIZE 0x7000
+#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 0xD000
+#endif
+
+#endif /* ARM_BOARD_OPTIMISE_MEM */
+
+/*******************************************************************************
+ * Memprotect definitions
+ ******************************************************************************/
+/* PSCI memory protect definitions:
+ * This variable is stored in a non-secure flash because some ARM reference
+ * platforms do not have secure NVRAM. Real systems that provided MEM_PROTECT
+ * support must use a secure NVRAM to store the PSCI MEM_PROTECT definitions.
+ */
+#define PLAT_ARM_MEM_PROT_ADDR (V2M_FLASH0_BASE + \
+ V2M_FLASH0_SIZE - V2M_FLASH_BLOCK_SIZE)
+#endif /* __SGM_BASE_PLATFORM_DEF_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_plat_config.h b/plat/arm/css/sgm/include/sgm_plat_config.h
new file mode 100644
index 000000000..b171d9a68
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_plat_config.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_PLAT_CONFIG_H__
+#define __SGM_PLAT_CONFIG_H__
+
+#include <arm_gic.h>
+#include <ccn.h>
+#include <gicv3.h>
+
+/* The type of interconnect */
+typedef enum {
+ ARM_CCI = 0,
+ ARM_CCN,
+ ARM_CMN
+} css_inteconn_type_t;
+
+typedef ccn_desc_t inteconn_desc_t;
+
+/* Interconnect configurations */
+typedef struct css_inteconn_config {
+ css_inteconn_type_t ip_type;
+ const inteconn_desc_t *plat_inteconn_desc;
+} css_inteconn_config_t;
+
+/* Topology configurations */
+typedef struct css_topology {
+ const unsigned char *power_tree;
+ unsigned int plat_cluster_core_count;
+} css_topology_t;
+
+typedef struct css_plat_config {
+ const gicv3_driver_data_t *gic_data;
+ const css_inteconn_config_t *inteconn;
+ const css_topology_t *topology;
+} css_plat_config_t;
+
+void plat_config_init(void);
+css_plat_config_t *get_plat_config(void);
+#endif /* __SGM_PLAT_CONFIG_H__ */
diff --git a/plat/arm/css/sgm/include/sgm_variant.h b/plat/arm/css/sgm/include/sgm_variant.h
new file mode 100644
index 000000000..a0a91b0c5
--- /dev/null
+++ b/plat/arm/css/sgm/include/sgm_variant.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SGM_VARIANT_H__
+#define __SGM_VARIANT_H__
+
+/* SSC_VERSION values for sgm */
+#define SGM775_SSC_VER_PART_NUM 0x0790
+
+/* DMC configuration for sgm */
+#define SGM_DMC_SIZE 0x40000
+#define SGM775_DMC_COUNT 4
+
+#endif /* __SGM_VARIANT_H__ */
diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk
new file mode 100644
index 000000000..6a3caba24
--- /dev/null
+++ b/plat/arm/css/sgm/sgm-common.mk
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+CSS_SGM_BASE := plat/arm/css/sgm
+
+PLAT_INCLUDES := -I${CSS_SGM_BASE}/include
+
+PLAT_BL_COMMON_SOURCES := ${CSS_SGM_BASE}/sgm_mmap_config.c \
+ ${CSS_SGM_BASE}/aarch64/css_sgm_helpers.S
+
+SECURITY_SOURCES := drivers/arm/tzc/tzc_dmc500.c \
+ plat/arm/common/arm_tzc_dmc500.c \
+ ${CSS_SGM_BASE}/sgm_security.c
+
+SGM_CPU_SOURCES := lib/cpus/aarch64/cortex_a55.S \
+ lib/cpus/aarch64/cortex_a75.S
+
+INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c
+
+SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v3/gicv3_main.c \
+ drivers/arm/gic/v3/gicv3_helpers.c \
+ plat/common/plat_gicv3.c \
+ plat/arm/common/arm_gicv3.c \
+ drivers/arm/gic/v3/gic600.c \
+ drivers/arm/gic/v3/arm_gicv3_common.c
+
+BL1_SOURCES += $(SGM_CPU_SOURCES) \
+ ${INTERCONNECT_SOURCES} \
+ ${CSS_SGM_BASE}/sgm_bl1_setup.c \
+ ${CSS_SGM_BASE}/sgm_plat_config.c
+
+BL2_SOURCES += ${SECURITY_SOURCES}
+
+BL2U_SOURCES += ${SECURITY_SOURCES}
+
+BL31_SOURCES += $(SGM_CPU_SOURCES) \
+ ${INTERCONNECT_SOURCES} \
+ ${SECURITY_SOURCES} \
+ ${SGM_GIC_SOURCES} \
+ ${CSS_SGM_BASE}/sgm_topology.c \
+ ${CSS_SGM_BASE}/sgm_bl31_setup.c \
+ ${CSS_SGM_BASE}/sgm_plat_config.c
+
+# sgm uses CCI-500 as Cache Coherent Interconnect
+ARM_CCI_PRODUCT_ID := 500
+
+# Disable the PSCI platform compatibility layer
+ENABLE_PLAT_COMPAT := 0
+
+# System coherency is managed in hardware
+HW_ASSISTED_COHERENCY := 1
+
+# When building for systems with hardware-assisted coherency, there's no need to
+# use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too.
+USE_COHERENT_MEM := 0
+
+override ARM_PLAT_MT := 1
+
+$(eval $(call add_define,SGM_PLAT))
+
+include plat/arm/common/arm_common.mk
+include plat/arm/board/common/board_common.mk
+include plat/arm/css/common/css_common.mk
+include plat/arm/soc/common/soc_css.mk
diff --git a/plat/arm/css/sgm/sgm_bl1_setup.c b/plat/arm/css/sgm/sgm_bl1_setup.c
new file mode 100644
index 000000000..51e3e5332
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl1_setup.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+#include <soc_css.h>
+
+void bl1_early_platform_setup(void)
+{
+ /* Initialize the platform configuration structure */
+ plat_config_init();
+
+ arm_bl1_early_platform_setup();
+
+#if !HW_ASSISTED_COHERENCY
+ /*
+ * Initialize Interconnect for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ plat_arm_interconnect_init();
+ /*
+ * Enable Interconnect coherency for the primary CPU's cluster.
+ */
+ plat_arm_interconnect_enter_coherency();
+#endif
+}
diff --git a/plat/arm/css/sgm/sgm_bl31_setup.c b/plat/arm/css/sgm/sgm_bl31_setup.c
new file mode 100644
index 000000000..a55176a74
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_bl31_setup.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ uint32_t plat_version;
+ bl_params_node_t *bl_params;
+
+ bl_params = ((bl_params_t *)arg0)->head;
+
+ /* Initialize the platform configuration structure */
+ plat_config_init();
+
+ while (bl_params) {
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ plat_version = mmio_read_32(SSC_VERSION);
+ bl_params->ep_info->args.arg2 = plat_version;
+ break;
+ }
+
+ bl_params = bl_params->next_params_info;
+ }
+
+ arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+}
diff --git a/plat/arm/css/sgm/sgm_interconnect.c b/plat/arm/css/sgm/sgm_interconnect.c
new file mode 100644
index 000000000..301ea84f0
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_interconnect.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * As the SGM platform supports FCM (with automatic interconnect
+ * enter/exit), we should not do anything in these interface functions.
+ * They are used to override the weak functions in cci drivers.
+ */
+
+/******************************************************************************
+ * Helper function to initialize ARM interconnect driver.
+ *****************************************************************************/
+void plat_arm_interconnect_init(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to place current master into coherency
+ *****************************************************************************/
+void plat_arm_interconnect_enter_coherency(void)
+{
+}
+
+/******************************************************************************
+ * Helper function to remove current master from coherency
+ *****************************************************************************/
+void plat_arm_interconnect_exit_coherency(void)
+{
+}
diff --git a/plat/arm/css/sgm/sgm_mmap_config.c b/plat/arm/css/sgm/sgm_mmap_config.c
new file mode 100644
index 000000000..009ee6403
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_mmap_config.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arm_def.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_variant.h>
+
+/*
+ * Table of regions for different BL stages to map using the MMU.
+ * This doesn't include Trusted RAM as the 'mem_layout' argument passed to
+ * arm_configure_mmu_elx() will give the available subset of that.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_FLASH0_RO,
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ CSS_MAP_GIC_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+#if TRUSTED_BOARD_BOOT
+ ARM_MAP_NS_DRAM1,
+#endif
+ {0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_FLASH0_RO,
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ CSS_MAP_GIC_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ ARM_MAP_NS_DRAM1,
+ ARM_MAP_TSP_SEC_MEM,
+#ifdef SPD_opteed
+ ARM_OPTEE_PAGEABLE_LOAD_MEM,
+#endif
+ {0}
+};
+#endif
+#if IMAGE_BL2U
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ CSS_MAP_DEVICE,
+ CSS_MAP_GIC_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+#endif
+#if IMAGE_BL31
+const mmap_region_t plat_arm_mmap[] = {
+ ARM_MAP_SHARED_RAM,
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ CSS_MAP_GIC_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+#endif
+#if IMAGE_BL32
+const mmap_region_t plat_arm_mmap[] = {
+ V2M_MAP_IOFPGA,
+ CSS_MAP_DEVICE,
+ CSS_MAP_GIC_DEVICE,
+ SOC_CSS_MAP_DEVICE,
+ {0}
+};
+#endif
+
+ARM_CASSERT_MMAP
+
+const mmap_region_t *plat_arm_get_mmap(void)
+{
+ return plat_arm_mmap;
+}
diff --git a/plat/arm/css/sgm/sgm_plat_config.c b/plat/arm/css/sgm/sgm_plat_config.c
new file mode 100644
index 000000000..809edf68e
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_plat_config.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <plat_arm.h>
+#include <platform_def.h>
+#include <sgm_plat_config.h>
+#include <sgm_variant.h>
+#include <string.h>
+
+static css_plat_config_t *css_plat_info;
+
+/* Interconnect */
+const css_inteconn_config_t sgm_inteconn = {
+ .ip_type = ARM_CCI,
+ .plat_inteconn_desc = NULL
+};
+
+/* Special definition for SGM775 */
+/* Topology configuration for SGM775 */
+const unsigned char sgm775_power_domain_tree_desc[] = {
+ /* No of root nodes */
+ ARM_SYSTEM_COUNT,
+ /* No of children for the root node */
+ PLAT_ARM_CLUSTER_COUNT,
+ /* No of children for the first cluster node */
+ PLAT_ARM_CLUSTER_CORE_COUNT,
+};
+
+const css_topology_t sgm775_topology = {
+ .power_tree = sgm775_power_domain_tree_desc,
+ .plat_cluster_core_count = PLAT_ARM_CLUSTER_CORE_COUNT
+};
+
+/* Configuration structure for SGM775 */
+css_plat_config_t sgm775_config = {
+ .inteconn = &sgm_inteconn,
+ .topology = &sgm775_topology
+};
+
+/*******************************************************************************
+ * This function initializes the platform structure.
+ ******************************************************************************/
+void plat_config_init(void)
+{
+ /* Get the platform configurations */
+ switch (GET_PLAT_PART_NUM) {
+ case SGM775_SSC_VER_PART_NUM:
+ css_plat_info = &sgm775_config;
+
+ break;
+ default:
+ ERROR("Not a valid sgm variant!\n");
+ panic();
+ }
+}
+
+/*******************************************************************************
+ * This function returns the platform structure pointer.
+ ******************************************************************************/
+css_plat_config_t *get_plat_config(void)
+{
+ assert(css_plat_info != NULL);
+ return css_plat_info;
+}
diff --git a/plat/arm/css/sgm/sgm_security.c b/plat/arm/css/sgm/sgm_security.c
new file mode 100644
index 000000000..7f9806001
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_security.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <plat_arm.h>
+#include <sgm_variant.h>
+#include <soc_css.h>
+#include <tzc_dmc500.h>
+
+/* Is populated with the DMC-500 controllers base addresses */
+static tzc_dmc500_driver_data_t plat_driver_data;
+
+void plat_sgm_dp_security_setup(void)
+{
+ unsigned int nprot_nsaid;
+
+ /*
+ * At reset the Mali display processors start with NSAIDs set to zero
+ * so the firmware must set them up to the expected values for ARM sgm
+ * platforms.
+ */
+
+ nprot_nsaid = mmio_read_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET);
+ nprot_nsaid &= ~((0xF << W_NPROT_NSAID_SHIFT) |
+ (0xF << LS_NPORT_NSAID_SHIFT));
+ nprot_nsaid |= ((TZC_NSAID_DISP1 << W_NPROT_NSAID_SHIFT) |
+ (TZC_NSAID_DISP0 << LS_NPORT_NSAID_SHIFT));
+ mmio_write_32(MALI_DP_BASE + DP_NPROT_NSAID_OFFSET, nprot_nsaid);
+}
+
+void plat_arm_security_setup(void)
+{
+ unsigned int i;
+ unsigned int part_num = GET_PLAT_PART_NUM;
+
+ INFO("part_num: 0x%x\n", part_num);
+
+ /*
+ * Initialise plat_driver_data with platform specific DMC_BASE
+ * addresses
+ */
+ switch (part_num) {
+ case SGM775_SSC_VER_PART_NUM:
+ for (i = 0; i < SGM775_DMC_COUNT; i++)
+ plat_driver_data.dmc_base[i] = PLAT_ARM_TZC_BASE
+ + SGM_DMC_SIZE * i;
+ plat_driver_data.dmc_count = SGM775_DMC_COUNT;
+ break;
+ default:
+ /* Unexpected platform */
+ ERROR("Unexpected platform\n");
+ panic();
+ }
+ /* Initialize the TrustZone Controller in DMC-500 */
+ arm_tzc_dmc500_setup(&plat_driver_data, NULL);
+
+ /* Do DP NSAID setup */
+ plat_sgm_dp_security_setup();
+ /* Do ARM CSS SoC security setup */
+ soc_css_security_setup();
+}
diff --git a/plat/arm/css/sgm/sgm_topology.c b/plat/arm/css/sgm/sgm_topology.c
new file mode 100644
index 000000000..ce7246448
--- /dev/null
+++ b/plat/arm/css/sgm/sgm_topology.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+/*******************************************************************************
+ * This function returns the topology tree information.
+ ******************************************************************************/
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return get_plat_config()->topology->power_tree;
+}
+
+/*******************************************************************************
+ * 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 get_plat_config()->topology->plat_cluster_core_count;
+}
+
+/*
+ * The array mapping platform core position (implemented by plat_my_core_pos())
+ * to the SCMI power domain ID implemented by SCP.
+ */
+const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = {
+ 0, 1, 2, 3, 4, 5, 6, 7 };
diff --git a/plat/arm/css/sgm/tsp/sgm_tsp_setup.c b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
new file mode 100644
index 000000000..39bba94a3
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/sgm_tsp_setup.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat_arm.h>
+#include <sgm_plat_config.h>
+
+void tsp_early_platform_setup(void)
+{
+ /* Initialize the platform configuration structure */
+ plat_config_init();
+
+ arm_tsp_early_platform_setup();
+}
diff --git a/plat/arm/css/sgm/tsp/tsp-sgm.mk b/plat/arm/css/sgm/tsp/tsp-sgm.mk
new file mode 100644
index 000000000..a9e413163
--- /dev/null
+++ b/plat/arm/css/sgm/tsp/tsp-sgm.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BL32_SOURCES += ${SGM_GIC_SOURCES} \
+ ${CSS_SGM_BASE}/sgm_plat_config.c \
+ plat/arm/board/sgm/tsp/sgm_tsp_setup.c
+
+include plat/arm/common/tsp/arm_tsp.mk
diff --git a/plat/common/aarch32/plat_common.c b/plat/common/aarch32/plat_common.c
index 4f2714902..16c2b5c95 100644
--- a/plat/common/aarch32/plat_common.c
+++ b/plat/common/aarch32/plat_common.c
@@ -17,5 +17,5 @@
void bl32_plat_enable_mmu(uint32_t flags)
{
- enable_mmu_secure(flags);
+ enable_mmu_svc_mon(flags);
}
diff --git a/plat/common/aarch64/platform_helpers.S b/plat/common/aarch64/platform_helpers.S
index a413f5fd1..a5d26c013 100644
--- a/plat/common/aarch64/platform_helpers.S
+++ b/plat/common/aarch64/platform_helpers.S
@@ -20,6 +20,10 @@
.weak bl31_plat_enable_mmu
.weak bl32_plat_enable_mmu
+ .weak plat_handle_uncontainable_ea
+ .weak plat_handle_double_fault
+ .weak plat_handle_el3_ea
+
#if !ENABLE_PLAT_COMPAT
.globl platform_get_core_pos
@@ -186,3 +190,34 @@ endfunc bl31_plat_enable_mmu
func bl32_plat_enable_mmu
b enable_mmu_direct_el1
endfunc bl32_plat_enable_mmu
+
+
+ /* -----------------------------------------------------
+ * Platform handler for Uncontainable External Abort.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ * -----------------------------------------------------
+ */
+func plat_handle_uncontainable_ea
+ b report_unhandled_exception
+endfunc plat_handle_uncontainable_ea
+
+ /* -----------------------------------------------------
+ * Platform handler for Double Fault.
+ *
+ * x0: EA reason
+ * x1: EA syndrome
+ * -----------------------------------------------------
+ */
+func plat_handle_double_fault
+ b report_unhandled_exception
+endfunc plat_handle_double_fault
+
+ /* -----------------------------------------------------
+ * Platform handler for EL3 External Abort.
+ * -----------------------------------------------------
+ */
+func plat_handle_el3_ea
+ b report_unhandled_exception
+endfunc plat_handle_el3_ea
diff --git a/plat/common/plat_gicv2.c b/plat/common/plat_gicv2.c
index 026ea7132..2b61834b2 100644
--- a/plat/common/plat_gicv2.c
+++ b/plat/common/plat_gicv2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#include <gicv2.h>
#include <interrupt_mgmt.h>
#include <platform.h>
+#include <stdbool.h>
/*
* The following platform GIC functions are weakly defined. They
@@ -101,7 +102,7 @@ uint32_t plat_ic_get_interrupt_type(uint32_t id)
type = gicv2_get_interrupt_group(id);
/* Assume that all secure interrupts are S-EL1 interrupts */
- return type == GICV2_INTR_GROUP1 ? INTR_TYPE_NS :
+ return (type == GICV2_INTR_GROUP1) ? INTR_TYPE_NS :
#if GICV2_G0_FOR_EL3
INTR_TYPE_EL3;
#else
@@ -130,9 +131,8 @@ void plat_ic_end_of_interrupt(uint32_t id)
uint32_t plat_interrupt_type_to_line(uint32_t type,
uint32_t security_state)
{
- assert(type == INTR_TYPE_S_EL1 ||
- type == INTR_TYPE_EL3 ||
- type == INTR_TYPE_NS);
+ assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) ||
+ (type == INTR_TYPE_NS));
assert(sec_state_is_valid(security_state));
@@ -144,8 +144,8 @@ uint32_t plat_interrupt_type_to_line(uint32_t type,
* Secure interrupts are signaled using the IRQ line if the FIQ is
* not enabled else they are signaled using the FIQ line.
*/
- return ((gicv2_is_fiq_enabled()) ? __builtin_ctz(SCR_FIQ_BIT) :
- __builtin_ctz(SCR_IRQ_BIT));
+ return ((gicv2_is_fiq_enabled() != 0U) ? __builtin_ctz(SCR_FIQ_BIT) :
+ __builtin_ctz(SCR_IRQ_BIT));
}
unsigned int plat_ic_get_running_priority(void)
@@ -211,7 +211,7 @@ int plat_ic_has_interrupt_type(unsigned int type)
void plat_ic_set_interrupt_type(unsigned int id, unsigned int type)
{
- int gicv2_type = 0;
+ unsigned int gicv2_type = 0U;
/* Map canonical interrupt type to GICv2 type */
switch (type) {
@@ -226,7 +226,7 @@ void plat_ic_set_interrupt_type(unsigned int id, unsigned int type)
gicv2_type = GICV2_INTR_GROUP1;
break;
default:
- assert(0);
+ assert(false);
break;
}
@@ -247,7 +247,7 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
gicv2_raise_sgi(sgi_num, id);
#else
- assert(0);
+ assert(false);
#endif
}
@@ -266,7 +266,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
proc_num = -1;
break;
default:
- assert(0);
+ assert(false);
break;
}
diff --git a/plat/common/plat_gicv3.c b/plat/common/plat_gicv3.c
index 26a4973f9..e43a35507 100644
--- a/plat/common/plat_gicv3.c
+++ b/plat/common/plat_gicv3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <gicv3.h>
#include <interrupt_mgmt.h>
#include <platform.h>
+#include <stdbool.h>
#ifdef IMAGE_BL31
@@ -54,7 +55,7 @@ uint32_t plat_ic_get_pending_interrupt_id(void)
assert(IS_IN_EL3());
irqnr = gicv3_get_pending_interrupt_id();
- return (gicv3_is_intr_id_special_identifier(irqnr)) ?
+ return gicv3_is_intr_id_special_identifier(irqnr) ?
INTR_ID_UNAVAILABLE : irqnr;
}
@@ -73,20 +74,27 @@ uint32_t plat_ic_get_pending_interrupt_id(void)
uint32_t plat_ic_get_pending_interrupt_type(void)
{
unsigned int irqnr;
+ uint32_t type;
assert(IS_IN_EL3());
irqnr = gicv3_get_pending_interrupt_type();
switch (irqnr) {
case PENDING_G1S_INTID:
- return INTR_TYPE_S_EL1;
+ type = INTR_TYPE_S_EL1;
+ break;
case PENDING_G1NS_INTID:
- return INTR_TYPE_NS;
+ type = INTR_TYPE_NS;
+ break;
case GIC_SPURIOUS_INTERRUPT:
- return INTR_TYPE_INVAL;
+ type = INTR_TYPE_INVAL;
+ break;
default:
- return INTR_TYPE_EL3;
+ type = INTR_TYPE_EL3;
+ break;
}
+
+ return type;
}
/*
@@ -132,9 +140,9 @@ void plat_ic_end_of_interrupt(uint32_t id)
uint32_t plat_interrupt_type_to_line(uint32_t type,
uint32_t security_state)
{
- assert(type == INTR_TYPE_S_EL1 ||
- type == INTR_TYPE_EL3 ||
- type == INTR_TYPE_NS);
+ assert((type == INTR_TYPE_S_EL1) ||
+ (type == INTR_TYPE_EL3) ||
+ (type == INTR_TYPE_NS));
assert(sec_state_is_valid(security_state));
assert(IS_IN_EL3());
@@ -227,9 +235,10 @@ void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target)
assert(plat_core_pos_by_mpidr(target) >= 0);
/* Verify that this is a secure EL3 SGI */
- assert(plat_ic_get_interrupt_type(sgi_num) == INTR_TYPE_EL3);
+ assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) ==
+ INTR_TYPE_EL3);
- gicv3_raise_secure_g0_sgi(sgi_num, target);
+ gicv3_raise_secure_g0_sgi((unsigned int)sgi_num, target);
}
void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
@@ -246,7 +255,7 @@ void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode,
irm = GICV3_IRM_ANY;
break;
default:
- assert(0);
+ assert(false);
break;
}
@@ -274,10 +283,10 @@ unsigned int plat_ic_set_priority_mask(unsigned int mask)
unsigned int plat_ic_get_interrupt_id(unsigned int raw)
{
- unsigned int id = (raw & INT_ID_MASK);
+ unsigned int id = raw & INT_ID_MASK;
- return (gicv3_is_intr_id_special_identifier(id) ?
- INTR_ID_UNAVAILABLE : id);
+ return gicv3_is_intr_id_special_identifier(id) ?
+ INTR_ID_UNAVAILABLE : id;
}
#endif
#ifdef IMAGE_BL32
diff --git a/plat/common/plat_log_common.c b/plat/common/plat_log_common.c
index 30dcb1219..49e1c152f 100644
--- a/plat/common/plat_log_common.c
+++ b/plat/common/plat_log_common.c
@@ -1,25 +1,28 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <assert.h>
#include <debug.h>
-#include <platform.h>
/* Allow platforms to override the log prefix string */
#pragma weak plat_log_get_prefix
-static const char *prefix_str[] = {
+static const char *plat_prefix_str[] = {
"ERROR: ", "NOTICE: ", "WARNING: ", "INFO: ", "VERBOSE: "};
const char *plat_log_get_prefix(unsigned int log_level)
{
- if (log_level < LOG_LEVEL_ERROR)
- log_level = LOG_LEVEL_ERROR;
- else if (log_level > LOG_LEVEL_VERBOSE)
- log_level = LOG_LEVEL_VERBOSE;
+ unsigned int level;
- return prefix_str[(log_level/10) - 1];
+ if (log_level < LOG_LEVEL_ERROR) {
+ level = LOG_LEVEL_ERROR;
+ } else if (log_level > LOG_LEVEL_VERBOSE) {
+ level = LOG_LEVEL_VERBOSE;
+ } else {
+ level = log_level;
+ }
+
+ return plat_prefix_str[(level / 10U) - 1U];
}
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 0e818d0de..fab3c770b 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +16,7 @@
#pragma weak plat_psci_stat_get_residency
/* Ticks elapsed in one second by a signal of 1 MHz */
-#define MHZ_TICKS_PER_SEC 1000000
+#define MHZ_TICKS_PER_SEC 1000000U
/* Maximum time-stamp value read from architectural counters */
#ifdef AARCH32
@@ -49,7 +49,7 @@ static u_register_t calc_stat_residency(unsigned long long pwrupts,
* convert time-stamp into microseconds.
*/
residency_div = read_cntfrq_el0() / MHZ_TICKS_PER_SEC;
- assert(residency_div);
+ assert(residency_div > 0U);
if (pwrupts < pwrdnts)
res = MAX_TS - pwrdnts + pwrupts;
@@ -67,7 +67,7 @@ static u_register_t calc_stat_residency(unsigned long long pwrupts,
void plat_psci_stat_accounting_start(
__unused const psci_power_state_t *state_info)
{
- assert(state_info);
+ assert(state_info != NULL);
PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_ENTER_LOW_PWR,
PMF_NO_CACHE_MAINT);
}
@@ -80,7 +80,7 @@ void plat_psci_stat_accounting_start(
void plat_psci_stat_accounting_stop(
__unused const psci_power_state_t *state_info)
{
- assert(state_info);
+ assert(state_info != NULL);
PMF_CAPTURE_TIMESTAMP(psci_svc, PSCI_STAT_ID_EXIT_LOW_PWR,
PMF_NO_CACHE_MAINT);
}
@@ -97,12 +97,12 @@ u_register_t plat_psci_stat_get_residency(unsigned int lvl,
unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
unsigned int pmf_flags;
- assert(lvl >= PSCI_CPU_PWR_LVL && lvl <= PLAT_MAX_PWR_LVL);
- assert(state_info);
- assert(last_cpu_idx >= 0 && last_cpu_idx <= PLATFORM_CORE_COUNT);
+ assert((lvl >= PSCI_CPU_PWR_LVL) && (lvl <= PLAT_MAX_PWR_LVL));
+ assert(state_info != NULL);
+ assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
if (lvl == PSCI_CPU_PWR_LVL)
- assert(last_cpu_idx == plat_my_core_pos());
+ assert((unsigned int)last_cpu_idx == plat_my_core_pos());
/*
* If power down is requested, then timestamp capture will
@@ -110,10 +110,10 @@ u_register_t plat_psci_stat_get_residency(unsigned int lvl,
* when reading the timestamp.
*/
state = state_info->pwr_domain_state[PSCI_CPU_PWR_LVL];
- if (is_local_state_off(state)) {
+ if (is_local_state_off(state) != 0) {
pmf_flags = PMF_CACHE_MAINT;
} else {
- assert(is_local_state_retn(state));
+ assert(is_local_state_retn(state) == 1);
pmf_flags = PMF_NO_CACHE_MAINT;
}
@@ -150,14 +150,18 @@ plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
unsigned int ncpu)
{
plat_local_state_t target = PLAT_MAX_OFF_STATE, temp;
+ const plat_local_state_t *st = states;
+ unsigned int n = ncpu;
- assert(ncpu);
+ assert(ncpu > 0U);
do {
- temp = *states++;
+ temp = *st;
+ st++;
if (temp < target)
target = temp;
- } while (--ncpu);
+ n--;
+ } while (n > 0U);
return target;
}
diff --git a/plat/hisilicon/hikey/hikey_bl1_setup.c b/plat/hisilicon/hikey/hikey_bl1_setup.c
index da6f6a519..ec779f46a 100644
--- a/plat/hisilicon/hikey/hikey_bl1_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl1_setup.c
@@ -10,11 +10,11 @@
#include <console.h>
#include <debug.h>
#include <dw_mmc.h>
-#include <emmc.h>
#include <errno.h>
#include <hi6220.h>
#include <hikey_def.h>
#include <hikey_layout.h>
+#include <mmc.h>
#include <mmio.h>
#include <platform.h>
#include <string.h>
@@ -97,6 +97,7 @@ void bl1_plat_arch_setup(void)
void bl1_platform_setup(void)
{
dw_mmc_params_t params;
+ struct mmc_device_info info;
assert((HIKEY_BL1_MMC_DESC_BASE >= SRAM_BASE) &&
((SRAM_BASE + SRAM_SIZE) >=
@@ -115,9 +116,10 @@ void bl1_platform_setup(void)
params.desc_base = HIKEY_BL1_MMC_DESC_BASE;
params.desc_size = 1 << 20;
params.clk_rate = 24 * 1000 * 1000;
- params.bus_width = EMMC_BUS_WIDTH_8;
- params.flags = EMMC_FLAG_CMD23;
- dw_mmc_init(&params);
+ params.bus_width = MMC_BUS_WIDTH_8;
+ params.flags = MMC_FLAG_CMD23;
+ info.mmc_dev_type = MMC_IS_EMMC;
+ dw_mmc_init(&params, &info);
hikey_io_setup();
}
diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c
index a3fc607bb..aad350bf8 100644
--- a/plat/hisilicon/hikey/hikey_bl2_setup.c
+++ b/plat/hisilicon/hikey/hikey_bl2_setup.c
@@ -11,11 +11,11 @@
#include <debug.h>
#include <desc_image_load.h>
#include <dw_mmc.h>
-#include <emmc.h>
#include <errno.h>
#include <hi6220.h>
#include <hisi_mcu.h>
#include <hisi_sram_map.h>
+#include <mmc.h>
#include <mmio.h>
#ifdef SPD_opteed
#include <optee_utils.h>
@@ -299,6 +299,7 @@ void bl2_el3_plat_arch_setup(void)
void bl2_platform_setup(void)
{
dw_mmc_params_t params;
+ struct mmc_device_info info;
hikey_sp804_init();
hikey_gpio_init();
@@ -328,9 +329,10 @@ void bl2_platform_setup(void)
params.desc_base = HIKEY_MMC_DESC_BASE;
params.desc_size = 1 << 20;
params.clk_rate = 24 * 1000 * 1000;
- params.bus_width = EMMC_BUS_WIDTH_8;
- params.flags = EMMC_FLAG_CMD23;
- dw_mmc_init(&params);
+ params.bus_width = MMC_BUS_WIDTH_8;
+ params.flags = MMC_FLAG_CMD23;
+ info.mmc_dev_type = MMC_IS_EMMC;
+ dw_mmc_init(&params, &info);
hikey_io_setup();
}
diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c
index 90c2f8165..3efbefe8c 100644
--- a/plat/hisilicon/hikey/hikey_io_storage.c
+++ b/plat/hisilicon/hikey/hikey_io_storage.c
@@ -7,7 +7,6 @@
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
-#include <emmc.h>
#include <errno.h>
#include <firmware_image_package.h>
#include <io_block.h>
@@ -15,6 +14,7 @@
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
+#include <mmc.h>
#include <mmio.h>
#include <platform_def.h>
#include <semihosting.h> /* For FOPEN_MODE_... */
@@ -59,10 +59,10 @@ static const io_block_dev_spec_t emmc_dev_spec = {
},
#endif
.ops = {
- .read = emmc_read_blocks,
- .write = emmc_write_blocks,
+ .read = mmc_read_blocks,
+ .write = mmc_write_blocks,
},
- .block_size = EMMC_BLOCK_SIZE,
+ .block_size = MMC_BLOCK_SIZE,
};
static const io_uuid_spec_t bl31_uuid_spec = {
@@ -89,6 +89,44 @@ static const io_uuid_spec_t scp_bl2_uuid_spec = {
.uuid = UUID_SCP_FIRMWARE_SCP_BL2,
};
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t scp_fw_key_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_key_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t scp_fw_cert_uuid_spec = {
+ .uuid = UUID_SCP_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t soc_fw_cert_uuid_spec = {
+ .uuid = UUID_SOC_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
static const struct plat_io_policy policies[] = {
[FIP_IMAGE_ID] = {
&emmc_dev_handle,
@@ -124,7 +162,54 @@ static const struct plat_io_policy policies[] = {
&fip_dev_handle,
(uintptr_t)&bl33_uuid_spec,
check_fip
- }
+ },
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&trusted_key_cert_uuid_spec,
+ check_fip
+ },
+ [SCP_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_fw_key_cert_uuid_spec,
+ check_fip
+ },
+ [SOC_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_key_cert_uuid_spec,
+ check_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_key_cert_uuid_spec,
+ check_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_key_cert_uuid_spec,
+ check_fip
+ },
+ [SCP_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_fw_cert_uuid_spec,
+ check_fip
+ },
+ [SOC_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&soc_fw_cert_uuid_spec,
+ check_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_cert_uuid_spec,
+ check_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_cert_uuid_spec,
+ check_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
};
static int check_emmc(const uintptr_t spec)
diff --git a/plat/hisilicon/hikey/hikey_rotpk.S b/plat/hisilicon/hikey/hikey_rotpk.S
new file mode 100644
index 000000000..f308eeea2
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_rotpk.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global hikey_rotpk_hash
+ .global hikey_rotpk_hash_end
+ .section .rodata.hikey_rotpk_hash, "a"
+hikey_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+hikey_rotpk_hash_end:
diff --git a/plat/hisilicon/hikey/hikey_security.c b/plat/hisilicon/hikey/hikey_security.c
index 863ad2b46..43d7b7ad7 100644
--- a/plat/hisilicon/hikey/hikey_security.c
+++ b/plat/hisilicon/hikey/hikey_security.c
@@ -8,7 +8,7 @@
#include <debug.h>
#include <platform_def.h>
#include <stdint.h>
-#include <strings.h>
+#include <string.h>
#include <utils_def.h>
#include "hikey_private.h"
diff --git a/plat/hisilicon/hikey/hikey_tbbr.c b/plat/hisilicon/hikey/hikey_tbbr.c
new file mode 100644
index 000000000..20eda3619
--- /dev/null
+++ b/plat/hisilicon/hikey/hikey_tbbr.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform.h>
+
+extern char hikey_rotpk_hash[], hikey_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = hikey_rotpk_hash;
+ *key_len = hikey_rotpk_hash_end - hikey_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
diff --git a/plat/hisilicon/hikey/hisi_ipc.c b/plat/hisilicon/hikey/hisi_ipc.c
index 0469a08b9..7e02f3ae1 100644
--- a/plat/hisilicon/hikey/hisi_ipc.c
+++ b/plat/hisilicon/hikey/hisi_ipc.c
@@ -1,10 +1,11 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
+#include <debug.h>
#include <hisi_ipc.h>
#include <hisi_sram_map.h>
#include <mmio.h>
diff --git a/plat/hisilicon/hikey/include/hikey_layout.h b/plat/hisilicon/hikey/include/hikey_layout.h
index 637a1c9be..acc7ad6f0 100644
--- a/plat/hisilicon/hikey/include/hikey_layout.h
+++ b/plat/hisilicon/hikey/include/hikey_layout.h
@@ -31,20 +31,20 @@
* + loader +
* ++++++++++ 0xF980_1000
* + BL1_RO +
- * ++++++++++ 0xF981_0000
+ * ++++++++++ 0xF981_8000
* + BL1_RW +
* ++++++++++ 0xF989_8000
*/
#define BL1_RO_BASE (XG2RAM0_BASE + BL1_XG2RAM0_OFFSET)
-#define BL1_RO_LIMIT (XG2RAM0_BASE + 0x10000)
-#define BL1_RW_BASE (BL1_RO_LIMIT) /* 0xf981_0000 */
-#define BL1_RW_SIZE (0x00088000)
+#define BL1_RO_LIMIT (XG2RAM0_BASE + 0x18000)
+#define BL1_RW_BASE (BL1_RO_LIMIT) /* 0xf981_8000 */
+#define BL1_RW_SIZE (0x00080000)
#define BL1_RW_LIMIT (0xF9898000)
/*
* Non-Secure BL1U specific defines.
*/
-#define NS_BL1U_BASE (0xf9818000)
+#define NS_BL1U_BASE (0xf9828000)
#define NS_BL1U_SIZE (0x00010000)
#define NS_BL1U_LIMIT (NS_BL1U_BASE + NS_BL1U_SIZE)
@@ -58,10 +58,10 @@
* + loader +
* ++++++++++ 0xF980_1000
* + BL2 +
- * ++++++++++ 0xF981_8000
+ * ++++++++++ 0xF983_0000
*/
#define BL2_BASE (BL1_RO_BASE) /* 0xf980_1000 */
-#define BL2_LIMIT (0xF9818000) /* 0xf981_8000 */
+#define BL2_LIMIT (0xF9830000) /* 0xf983_0000 */
/*
* SCP_BL2 specific defines.
diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h
index 8c560047c..54be97859 100644
--- a/plat/hisilicon/hikey/include/platform_def.h
+++ b/plat/hisilicon/hikey/include/platform_def.h
@@ -4,14 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <common_def.h>
#include <hikey_def.h>
#include <hikey_layout.h> /* BL memory region sizes, etc */
#include <tbbr_img_def.h>
+#include <utils_def.h>
/* Special value used to verify platform parameters from BL2 to BL3-1 */
#define HIKEY_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
@@ -21,7 +22,7 @@
*/
/* Size of cacheable stacks */
-#define PLATFORM_STACK_SIZE 0x800
+#define PLATFORM_STACK_SIZE 0x1000
#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
@@ -34,8 +35,8 @@
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
PLATFORM_CLUSTER_COUNT + 1)
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
#define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4
@@ -79,4 +80,4 @@
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk
index 38eb148cf..ccc729602 100644
--- a/plat/hisilicon/hikey/platform.mk
+++ b/plat/hisilicon/hikey/platform.mk
@@ -65,7 +65,7 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
drivers/io/io_storage.c \
- drivers/emmc/emmc.c \
+ drivers/mmc/mmc.c \
drivers/synopsys/emmc/dw_mmc.c \
lib/cpus/aarch64/cortex_a53.S \
plat/hisilicon/hikey/aarch64/hikey_helpers.S \
@@ -81,7 +81,7 @@ BL2_SOURCES += common/desc_image_load.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
drivers/io/io_storage.c \
- drivers/emmc/emmc.c \
+ drivers/mmc/mmc.c \
drivers/synopsys/emmc/dw_mmc.c \
lib/cpus/aarch64/cortex_a53.S \
plat/hisilicon/hikey/aarch64/hikey_helpers.S \
@@ -122,6 +122,46 @@ BL31_SOURCES += plat/hisilicon/hikey/hisi_sip_svc.c \
lib/pmf/pmf_smc.c
endif
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+USE_TBBR_DEFS := 1
+
+AUTH_SOURCES := drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot.c
+
+BL1_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/hisilicon/hikey/hikey_tbbr.c \
+ plat/hisilicon/hikey/hikey_rotpk.S
+
+BL2_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/hisilicon/hikey/hikey_tbbr.c \
+ plat/hisilicon/hikey/hikey_rotpk.S
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(BUILD_PLAT)/bl1/hikey_rotpk.o: $(ROTPK_HASH)
+$(BUILD_PLAT)/bl2/hikey_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ $(Q)openssl genrsa 2048 > $@ 2>/dev/null
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
# Enable workarounds for selected Cortex-A53 errata.
ERRATA_A53_836870 := 1
ERRATA_A53_843419 := 1
diff --git a/plat/hisilicon/hikey960/hikey960_bl1_setup.c b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
index 6a07f0924..a92857659 100644
--- a/plat/hisilicon/hikey960/hikey960_bl1_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl1_setup.c
@@ -211,6 +211,7 @@ void bl1_platform_setup(void)
hikey960_peri_init();
hikey960_ufs_init();
hikey960_pinmux_init();
+ hikey960_gpio_init();
hikey960_io_setup();
}
diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
index 6e726d2f5..f57dd63ce 100644
--- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c
+++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c
@@ -328,6 +328,7 @@ void bl2_platform_setup(void)
hikey960_tzc_init();
hikey960_peri_init();
hikey960_pinmux_init();
+ hikey960_gpio_init();
hikey960_init_ufs();
hikey960_io_setup();
}
diff --git a/plat/hisilicon/hikey960/hikey960_bl_common.c b/plat/hisilicon/hikey960/hikey960_bl_common.c
index f192c1e0e..0cee69f94 100644
--- a/plat/hisilicon/hikey960/hikey960_bl_common.c
+++ b/plat/hisilicon/hikey960/hikey960_bl_common.c
@@ -8,6 +8,7 @@
#include <delay_timer.h>
#include <hi3660.h>
#include <mmio.h>
+#include <pl061_gpio.h>
#include "hikey960_private.h"
@@ -439,3 +440,34 @@ void hikey960_pinmux_init(void)
/* GPIO213 - PCIE_CLKREQ_N */
mmio_write_32(IOMG_AO_033_REG, 1);
}
+
+void hikey960_gpio_init(void)
+{
+ pl061_gpio_init();
+ pl061_gpio_register(GPIO0_BASE, 0);
+ pl061_gpio_register(GPIO1_BASE, 1);
+ pl061_gpio_register(GPIO2_BASE, 2);
+ pl061_gpio_register(GPIO3_BASE, 3);
+ pl061_gpio_register(GPIO4_BASE, 4);
+ pl061_gpio_register(GPIO5_BASE, 5);
+ pl061_gpio_register(GPIO6_BASE, 6);
+ pl061_gpio_register(GPIO7_BASE, 7);
+ pl061_gpio_register(GPIO8_BASE, 8);
+ pl061_gpio_register(GPIO9_BASE, 9);
+ pl061_gpio_register(GPIO10_BASE, 10);
+ pl061_gpio_register(GPIO11_BASE, 11);
+ pl061_gpio_register(GPIO12_BASE, 12);
+ pl061_gpio_register(GPIO13_BASE, 13);
+ pl061_gpio_register(GPIO14_BASE, 14);
+ pl061_gpio_register(GPIO15_BASE, 15);
+ pl061_gpio_register(GPIO16_BASE, 16);
+ pl061_gpio_register(GPIO17_BASE, 17);
+ pl061_gpio_register(GPIO18_BASE, 18);
+ pl061_gpio_register(GPIO19_BASE, 19);
+ pl061_gpio_register(GPIO20_BASE, 20);
+ pl061_gpio_register(GPIO21_BASE, 21);
+
+ /* PCIE_PERST_N output low */
+ gpio_set_direction(89, GPIO_DIR_OUT);
+ gpio_set_value(89, GPIO_LEVEL_LOW);
+}
diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h
index 30166e56d..e2425fcad 100644
--- a/plat/hisilicon/hikey960/hikey960_private.h
+++ b/plat/hisilicon/hikey960/hikey960_private.h
@@ -32,6 +32,7 @@ void hikey960_regulator_enable(void);
void hikey960_tzc_init(void);
void hikey960_peri_init(void);
void hikey960_pinmux_init(void);
+void hikey960_gpio_init(void);
void set_retention_ticks(unsigned int val);
void clr_retention_ticks(unsigned int val);
void clr_ex(void);
diff --git a/plat/hisilicon/hikey960/include/hi3660.h b/plat/hisilicon/hikey960/include/hi3660.h
index ab7b8aa46..61b80b056 100644
--- a/plat/hisilicon/hikey960/include/hi3660.h
+++ b/plat/hisilicon/hikey960/include/hi3660.h
@@ -240,6 +240,27 @@
#define PCTRL_PERI_CTRL3_REG (PCTRL_REG_BASE + 0x010)
#define PCTRL_PERI_CTRL24_REG (PCTRL_REG_BASE + 0x064)
+#define GPIO0_BASE UL(0xE8A0B000)
+#define GPIO1_BASE UL(0xE8A0C000)
+#define GPIO2_BASE UL(0xE8A0D000)
+#define GPIO3_BASE UL(0xE8A0E000)
+#define GPIO4_BASE UL(0xE8A0F000)
+#define GPIO5_BASE UL(0xE8A10000)
+#define GPIO6_BASE UL(0xE8A11000)
+#define GPIO7_BASE UL(0xE8A12000)
+#define GPIO8_BASE UL(0xE8A13000)
+#define GPIO9_BASE UL(0xE8A14000)
+#define GPIO10_BASE UL(0xE8A15000)
+#define GPIO11_BASE UL(0xE8A16000)
+#define GPIO12_BASE UL(0xE8A17000)
+#define GPIO13_BASE UL(0xE8A18000)
+#define GPIO14_BASE UL(0xE8A19000)
+#define GPIO15_BASE UL(0xE8A1A000)
+#define GPIO16_BASE UL(0xE8A1B000)
+#define GPIO17_BASE UL(0xE8A1C000)
+#define GPIO20_BASE UL(0xE8A1F000)
+#define GPIO21_BASE UL(0xE8A20000)
+
#define TZC_REG_BASE 0xE8A21000
#define TZC_STAT0_REG (TZC_REG_BASE + 0x800)
#define TZC_EN0_REG (TZC_REG_BASE + 0x804)
@@ -316,6 +337,9 @@
#define MASK_UFS_DEVICE_RESET (1 << 16)
#define BIT_UFS_DEVICE_RESET (1 << 0)
+#define GPIO18_BASE UL(0xFF3B4000)
+#define GPIO19_BASE UL(0xFF3B5000)
+
#define IOMG_FIX_REG_BASE 0xFF3B6000
/* GPIO150: LED */
diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h
index beff47c0e..5a6021a85 100644
--- a/plat/hisilicon/hikey960/include/platform_def.h
+++ b/plat/hisilicon/hikey960/include/platform_def.h
@@ -4,10 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
+#include <utils_def.h>
#include "../hikey960_def.h"
/* Special value used to verify platform parameters from BL2 to BL3-1 */
@@ -31,8 +32,8 @@
#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \
PLATFORM_CLUSTER_COUNT + 1)
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
#define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4
@@ -140,4 +141,4 @@
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk
index 8b03e555d..5fa721842 100644
--- a/plat/hisilicon/hikey960/platform.mk
+++ b/plat/hisilicon/hikey960/platform.mk
@@ -22,12 +22,14 @@ endif
CRASH_CONSOLE_BASE := PL011_UART6_BASE
COLD_BOOT_SINGLE_CPU := 1
+PLAT_PL061_MAX_GPIOS := 176
PROGRAMMABLE_RESET_ADDRESS := 1
ENABLE_SVE_FOR_NS := 0
# Process flags
$(eval $(call add_define,HIKEY960_TSP_RAM_LOCATION_ID))
$(eval $(call add_define,CRASH_CONSOLE_BASE))
+$(eval $(call add_define,PLAT_PL061_MAX_GPIOS))
# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
# in the FIP if the platform requires.
@@ -58,6 +60,8 @@ HIKEY960_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
plat/common/plat_gicv2.c
BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \
+ drivers/arm/pl061/pl061_gpio.c \
+ drivers/gpio/gpio.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
drivers/io/io_storage.c \
@@ -71,6 +75,8 @@ BL1_SOURCES += bl1/tbbr/tbbr_img_desc.c \
${HIKEY960_GIC_SOURCES}
BL2_SOURCES += common/desc_image_load.c \
+ drivers/arm/pl061/pl061_gpio.c \
+ drivers/gpio/gpio.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
drivers/io/io_storage.c \
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
index 25eed5938..6fc4f3328 100644
--- a/plat/hisilicon/poplar/bl1_plat_setup.c
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -10,9 +10,9 @@
#include <console.h>
#include <debug.h>
#include <dw_mmc.h>
-#include <emmc.h>
#include <errno.h>
#include <generic_delay_timer.h>
+#include <mmc.h>
#include <mmio.h>
#include <pl061_gpio.h>
#include <platform.h>
@@ -92,6 +92,7 @@ void bl1_plat_arch_setup(void)
void bl1_platform_setup(void)
{
int i;
+ struct mmc_device_info info;
#if !POPLAR_RECOVERY
dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
#endif
@@ -105,7 +106,8 @@ void bl1_platform_setup(void)
#if !POPLAR_RECOVERY
/* SoC-specific emmc register are initialized/configured by bootrom */
INFO("BL1: initializing emmc\n");
- dw_mmc_init(&params);
+ info.mmc_dev_type = MMC_IS_EMMC;
+ dw_mmc_init(&params, &info);
#endif
plat_io_setup();
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
index 2671994a2..041ed4ad5 100644
--- a/plat/hisilicon/poplar/bl2_plat_setup.c
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -11,9 +11,9 @@
#include <debug.h>
#include <desc_image_load.h>
#include <dw_mmc.h>
-#include <emmc.h>
#include <errno.h>
#include <generic_delay_timer.h>
+#include <mmc.h>
#include <mmio.h>
#include <optee_utils.h>
#include <partition/partition.h>
@@ -333,6 +333,8 @@ void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
void bl2_early_platform_setup(meminfo_t *mem_layout)
{
+ struct mmc_device_info info;
+
#if !POPLAR_RECOVERY
dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
#endif
@@ -347,7 +349,8 @@ void bl2_early_platform_setup(meminfo_t *mem_layout)
#if !POPLAR_RECOVERY
/* SoC-specific emmc register are initialized/configured by bootrom */
INFO("BL2: initializing emmc\n");
- dw_mmc_init(&params);
+ info.mmc_dev_type = MMC_IS_EMMC;
+ dw_mmc_init(&params, &info);
#endif
plat_io_setup();
diff --git a/plat/hisilicon/poplar/include/hi3798cv200.h b/plat/hisilicon/poplar/include/hi3798cv200.h
index 125b04841..254b35715 100644
--- a/plat/hisilicon/poplar/include/hi3798cv200.h
+++ b/plat/hisilicon/poplar/include/hi3798cv200.h
@@ -67,11 +67,11 @@
#define EMMC_DESC_SIZE U(0x00100000) /* 1MB */
#define EMMC_INIT_PARAMS(base) \
- { .bus_width = EMMC_BUS_WIDTH_8, \
+ { .bus_width = MMC_BUS_WIDTH_8, \
.clk_rate = 25 * 1000 * 1000, \
.desc_base = (base), \
.desc_size = EMMC_DESC_SIZE, \
- .flags = EMMC_FLAG_CMD23, \
+ .flags = MMC_FLAG_CMD23, \
.reg_base = REG_BASE_MCI, \
}
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index 8e8f009dd..824ca34bf 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <common_def.h>
@@ -131,8 +131,8 @@
/* Power states */
#define PLAT_MAX_PWR_LVL (MPIDR_AFFLVL1)
-#define PLAT_MAX_OFF_STATE 2
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
/* Interrupt controller */
#define PLAT_ARM_GICD_BASE GICD_BASE
@@ -168,4 +168,4 @@
#define PLAT_ARM_G0_IRQ_PROPS(grp)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/hisilicon/poplar/plat_storage.c b/plat/hisilicon/poplar/plat_storage.c
index db52c6762..925274ce4 100644
--- a/plat/hisilicon/poplar/plat_storage.c
+++ b/plat/hisilicon/poplar/plat_storage.c
@@ -7,13 +7,13 @@
#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
-#include <emmc.h>
#include <firmware_image_package.h>
#include <io_block.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
+#include <mmc.h>
#include <mmio.h>
#include <partition/partition.h>
#include <semihosting.h>
@@ -38,10 +38,10 @@ static const io_block_dev_spec_t emmc_dev_spec = {
.length = POPLAR_EMMC_DATA_SIZE,
},
.ops = {
- .read = emmc_read_blocks,
- .write = emmc_write_blocks,
+ .read = mmc_read_blocks,
+ .write = mmc_write_blocks,
},
- .block_size = EMMC_BLOCK_SIZE,
+ .block_size = MMC_BLOCK_SIZE,
};
#else
static const io_dev_connector_t *mmap_dev_con;
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
index 14ffa99ea..3cdbe5999 100644
--- a/plat/hisilicon/poplar/platform.mk
+++ b/plat/hisilicon/poplar/platform.mk
@@ -82,7 +82,7 @@ PLAT_BL_COMMON_SOURCES := \
BL1_SOURCES += \
lib/cpus/aarch64/cortex_a53.S \
drivers/arm/pl061/pl061_gpio.c \
- drivers/emmc/emmc.c \
+ drivers/mmc/mmc.c \
drivers/synopsys/emmc/dw_mmc.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
@@ -94,7 +94,7 @@ BL1_SOURCES += \
BL2_SOURCES += \
drivers/arm/pl061/pl061_gpio.c \
- drivers/emmc/emmc.c \
+ drivers/mmc/mmc.c \
drivers/synopsys/emmc/dw_mmc.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
diff --git a/plat/imx/common/imx8_psci.c b/plat/imx/common/imx8_psci.c
new file mode 100644
index 000000000..22a531bf8
--- /dev/null
+++ b/plat/imx/common/imx8_psci.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <plat_imx8.h>
+#include <sci/sci.h>
+#include <stdbool.h>
+
+void __dead2 imx_system_off(void)
+{
+ sc_pm_set_sys_power_mode(ipc_handle, SC_PM_PW_MODE_OFF);
+ wfi();
+ ERROR("power off failed.\n");
+ panic();
+}
+
+void __dead2 imx_system_reset(void)
+{
+ sc_pm_reset(ipc_handle, SC_PM_RESET_TYPE_BOARD);
+ wfi();
+ ERROR("system reset failed.\n");
+ panic();
+}
+
+int imx_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ /* TODO */
+ return PSCI_E_INVALID_PARAMS;
+}
+
+void imx_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ unsigned int i;
+
+ /* CPU & cluster off, system in retention */
+ for (i = MPIDR_AFFLVL0; i < PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+ req_state->pwr_domain_state[PLAT_MAX_PWR_LVL] = PLAT_MAX_RET_STATE;
+}
+
diff --git a/plat/imx/common/imx8_topology.c b/plat/imx/common/imx8_topology.c
index bcb7d59f0..64145c4ca 100644
--- a/plat/imx/common/imx8_topology.c
+++ b/plat/imx/common/imx8_topology.c
@@ -11,7 +11,8 @@
const unsigned char imx_power_domain_tree_desc[] = {
PWR_DOMAIN_AT_MAX_LVL,
PLATFORM_CLUSTER_COUNT,
- PLATFORM_CORE_COUNT,
+ PLATFORM_CLUSTER0_CORE_COUNT,
+ PLATFORM_CLUSTER1_CORE_COUNT,
};
const unsigned char *plat_get_power_domain_tree_desc(void)
diff --git a/plat/imx/common/include/imx8_lpuart.h b/plat/imx/common/include/imx8_lpuart.h
index 4ff91bda7..33f955df7 100644
--- a/plat/imx/common/include/imx8_lpuart.h
+++ b/plat/imx/common/include/imx8_lpuart.h
@@ -52,7 +52,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct {
console_t console;
diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h
index 27d4c376e..a333bfbe1 100644
--- a/plat/imx/common/include/plat_imx8.h
+++ b/plat/imx/common/include/plat_imx8.h
@@ -8,6 +8,7 @@
#define __PLAT_IMX8_H__
#include <gicv3.h>
+#include <psci.h>
unsigned int plat_calc_core_pos(uint64_t mpidr);
void imx_mailbox_init(uintptr_t base_addr);
@@ -17,4 +18,9 @@ void plat_gic_cpuif_enable(void);
void plat_gic_cpuif_disable(void);
void plat_gic_pcpu_init(void);
+void __dead2 imx_system_off(void);
+void __dead2 imx_system_reset(void);
+int imx_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state);
+void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
#endif /*__PLAT_IMX8_H__ */
diff --git a/plat/imx/common/include/sci/sci_scfw.h b/plat/imx/common/include/sci/sci_scfw.h
index 9d08dad4b..781c69e01 100644
--- a/plat/imx/common/include/sci/sci_scfw.h
+++ b/plat/imx/common/include/sci/sci_scfw.h
@@ -9,7 +9,7 @@
/* Includes */
-#include <types.h>
+#include <stdint.h>
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
diff --git a/plat/imx/common/sci/imx8_mu.h b/plat/imx/common/sci/imx8_mu.h
index 8834a976c..8c7887728 100644
--- a/plat/imx/common/sci/imx8_mu.h
+++ b/plat/imx/common/sci/imx8_mu.h
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <types.h>
+#include <stdint.h>
#define MU_ATR0_OFFSET1 0x0
#define MU_ARR0_OFFSET1 0x10
diff --git a/plat/imx/imx8qm/imx8qm_psci.c b/plat/imx/imx8qm/imx8qm_psci.c
index b9b794bec..8166546d4 100644
--- a/plat/imx/imx8qm/imx8qm_psci.c
+++ b/plat/imx/imx8qm/imx8qm_psci.c
@@ -15,17 +15,18 @@
#include <sci/sci.h>
#include <stdbool.h>
+#define CORE_PWR_STATE(state) \
+ ((state)->pwr_domain_state[MPIDR_AFFLVL0])
+#define CLUSTER_PWR_STATE(state) \
+ ((state)->pwr_domain_state[MPIDR_AFFLVL1])
+#define SYSTEM_PWR_STATE(state) \
+ ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL])
+
const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A53_0, SC_R_A53_1, SC_R_A53_2,
SC_R_A53_3, SC_R_A72_0, SC_R_A72_1,
};
-/* need to enable USE_COHERENT_MEM to avoid coherence issue */
-#if USE_COHERENT_MEM
-static unsigned int a53_cpu_on_number __section("tzfw_coherent_mem");
-static unsigned int a72_cpu_on_number __section("tzfw_coherent_mem");
-#endif
-
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
@@ -34,12 +35,11 @@ int imx_pwr_domain_on(u_register_t mpidr)
cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- tf_printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
+ printf("imx_pwr_domain_on cluster_id %d, cpu_id %d\n", cluster_id, cpu_id);
if (cluster_id == 0) {
- if (a53_cpu_on_number == 0)
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_ON);
-
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_A53,
+ SC_PM_PW_MODE_ON);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
ERROR("cluster0 core %d power on failed!\n", cpu_id);
@@ -52,9 +52,8 @@ int imx_pwr_domain_on(u_register_t mpidr)
ret = PSCI_E_INTERN_FAIL;
}
} else {
- if (a72_cpu_on_number == 0)
- sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_ON);
-
+ sc_pm_set_resource_power_mode(ipc_handle, SC_R_A72,
+ SC_PM_PW_MODE_ON);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id + 4],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
ERROR(" cluster1 core %d power on failed!\n", cpu_id);
@@ -74,17 +73,56 @@ int imx_pwr_domain_on(u_register_t mpidr)
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state)
{
uint64_t mpidr = read_mpidr_el1();
- unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
- if (cluster_id == 0 && a53_cpu_on_number++ == 0)
- cci_enable_snoop_dvm_reqs(0);
- if (cluster_id == 1 && a72_cpu_on_number++ == 0)
- cci_enable_snoop_dvm_reqs(1);
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
plat_gic_pcpu_init();
plat_gic_cpuif_enable();
}
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ plat_gic_cpuif_disable();
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + cluster_id * 4],
+ SC_PM_PW_MODE_OFF,
+ SC_PM_WAKE_SRC_NONE);
+ if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE)
+ cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+ printf("turn off cluster:%d core:%d\n", cluster_id, cpu_id);
+}
+
+void imx_domain_suspend(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ plat_gic_cpuif_disable();
+
+ cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+ sc_pm_set_cpu_resume_addr(ipc_handle,
+ ap_core_index[cpu_id + cluster_id * 4], BL31_BASE);
+ sc_pm_req_cpu_low_power_mode(ipc_handle,
+ ap_core_index[cpu_id + cluster_id * 4],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+}
+
+void imx_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+
+ cci_enable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(mpidr));
+
+ plat_gic_cpuif_enable();
+}
+
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
{
return PSCI_E_SUCCESS;
@@ -93,22 +131,42 @@ int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
static const plat_psci_ops_t imx_plat_psci_ops = {
.pwr_domain_on = imx_pwr_domain_on,
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
+ .pwr_domain_off = imx_pwr_domain_off,
+ .pwr_domain_suspend = imx_domain_suspend,
+ .pwr_domain_suspend_finish = imx_domain_suspend_finish,
+ .get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+ .validate_power_state = imx_validate_power_state,
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+ .system_off = imx_system_off,
+ .system_reset = imx_system_reset,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
- uint64_t mpidr = read_mpidr_el1();
- unsigned int cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
-
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
- if (cluster_id == 0)
- a53_cpu_on_number++;
- else
- a72_cpu_on_number++;
+ /* Request low power mode for cluster/cci, only need to do once */
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A72, SC_PM_PW_MODE_OFF);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A53, SC_PM_PW_MODE_OFF);
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_CCI, SC_PM_PW_MODE_OFF);
+
+ /* Request RUN and LP modes for DDR, system interconnect etc. */
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
+ SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
+ SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
+ SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
+ SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A53,
+ SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
+ SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A72,
+ SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
+ SC_PM_PW_MODE_STBY);
return 0;
}
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index 51c2e1e18..1cf7511a8 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -4,6 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
+
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -22,10 +27,10 @@
#define IMX_PWR_LVL1 MPIDR_AFFLVL1
#define IMX_PWR_LVL2 MPIDR_AFFLVL2
-#define PWR_DOMAIN_AT_MAX_LVL 1
-#define PLAT_MAX_PWR_LVL 2
-#define PLAT_MAX_OFF_STATE 2
-#define PLAT_MAX_RET_STATE 1
+#define PWR_DOMAIN_AT_MAX_LVL U(1)
+#define PLAT_MAX_PWR_LVL U(2)
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
#define BL31_BASE 0x80000000
#define BL31_LIMIT 0x80020000
@@ -62,3 +67,5 @@
#define DEBUG_CONSOLE 0
#define DEBUG_CONSOLE_A53 0
#define PLAT_IMX8QM 1
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index c295e14bf..022ad9902 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -21,6 +21,7 @@ BL31_SOURCES += plat/imx/common/lpuart_console.S \
plat/imx/imx8qm/imx8qm_bl31_setup.c \
plat/imx/imx8qm/imx8qm_psci.c \
plat/imx/common/imx8_topology.c \
+ plat/imx/common/imx8_psci.c \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/xlat_tables/xlat_tables_common.c \
lib/cpus/aarch64/cortex_a53.S \
diff --git a/plat/imx/imx8qx/imx8qx_psci.c b/plat/imx/imx8qx/imx8qx_psci.c
index 47233dc8d..46ea72486 100644
--- a/plat/imx/imx8qx/imx8qx_psci.c
+++ b/plat/imx/imx8qx/imx8qx_psci.c
@@ -18,13 +18,6 @@ const static int ap_core_index[PLATFORM_CORE_COUNT] = {
SC_R_A35_0, SC_R_A35_1, SC_R_A35_2, SC_R_A35_3
};
-plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
- const plat_local_state_t *target_state,
- unsigned int ncpu)
-{
- return 0;
-}
-
int imx_pwr_domain_on(u_register_t mpidr)
{
int ret = PSCI_E_SUCCESS;
@@ -32,7 +25,7 @@ int imx_pwr_domain_on(u_register_t mpidr)
cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
- tf_printf("imx_pwr_domain_on cpu_id %d\n", cpu_id);
+ printf("imx_pwr_domain_on cpu_id %d\n", cpu_id);
if (sc_pm_set_resource_power_mode(ipc_handle, ap_core_index[cpu_id],
SC_PM_PW_MODE_ON) != SC_ERR_NONE) {
@@ -60,10 +53,51 @@ int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint)
return PSCI_E_SUCCESS;
}
+void imx_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ plat_gic_cpuif_disable();
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_NONE);
+ printf("turn off core:%d\n", cpu_id);
+}
+
+void imx_domain_suspend(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ plat_gic_cpuif_disable();
+
+ sc_pm_set_cpu_resume_addr(ipc_handle, ap_core_index[cpu_id], BL31_BASE);
+ sc_pm_req_cpu_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_OFF, SC_PM_WAKE_SRC_GIC);
+}
+
+void imx_domain_suspend_finish(const psci_power_state_t *target_state)
+{
+ u_register_t mpidr = read_mpidr_el1();
+ unsigned int cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ sc_pm_req_low_power_mode(ipc_handle, ap_core_index[cpu_id],
+ SC_PM_PW_MODE_ON);
+
+ plat_gic_cpuif_enable();
+}
+
static const plat_psci_ops_t imx_plat_psci_ops = {
.pwr_domain_on = imx_pwr_domain_on,
.pwr_domain_on_finish = imx_pwr_domain_on_finish,
.validate_ns_entrypoint = imx_validate_ns_entrypoint,
+ .system_off = imx_system_off,
+ .system_reset = imx_system_reset,
+ .pwr_domain_off = imx_pwr_domain_off,
+ .pwr_domain_suspend = imx_domain_suspend,
+ .pwr_domain_suspend_finish = imx_domain_suspend_finish,
+ .get_sys_suspend_power_state = imx_get_sys_suspend_power_state,
+ .validate_power_state = imx_validate_power_state,
};
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
@@ -72,5 +106,17 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
imx_mailbox_init(sec_entrypoint);
*psci_ops = &imx_plat_psci_ops;
+ /* Request low power mode for A35 cluster, only need to do once */
+ sc_pm_req_low_power_mode(ipc_handle, SC_R_A35, SC_PM_PW_MODE_OFF);
+
+ /* Request RUN and LP modes for DDR, system interconnect etc. */
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
+ SC_PM_SYS_IF_DDR, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
+ SC_PM_SYS_IF_MU, SC_PM_PW_MODE_ON, SC_PM_PW_MODE_STBY);
+ sc_pm_req_sys_if_power_mode(ipc_handle, SC_R_A35,
+ SC_PM_SYS_IF_INTERCONNECT, SC_PM_PW_MODE_ON,
+ SC_PM_PW_MODE_STBY);
+
return 0;
}
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 2cd140097..b9fd96c0c 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -4,8 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
@@ -17,11 +19,13 @@
#define PLATFORM_MAX_CPU_PER_CLUSTER 4
#define PLATFORM_CLUSTER_COUNT 1
#define PLATFORM_CORE_COUNT 4
+#define PLATFORM_CLUSTER0_CORE_COUNT 4
+#define PLATFORM_CLUSTER1_CORE_COUNT 0
-#define PWR_DOMAIN_AT_MAX_LVL 1
-#define PLAT_MAX_PWR_LVL 2
-#define PLAT_MAX_OFF_STATE 2
-#define PLAT_MAX_RET_STATE 1
+#define PWR_DOMAIN_AT_MAX_LVL U(1)
+#define PLAT_MAX_PWR_LVL U(2)
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
#define BL31_BASE 0x80000000
#define BL31_LIMIT 0x80020000
@@ -55,4 +59,4 @@
#define DEBUG_CONSOLE_A35 0
#define PLAT_IMX8QX 1
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk
index c16ce6e60..067661890 100644
--- a/plat/imx/imx8qx/platform.mk
+++ b/plat/imx/imx8qx/platform.mk
@@ -20,6 +20,8 @@ BL31_SOURCES += plat/imx/common/lpuart_console.S \
plat/imx/imx8qx/imx8qx_bl31_setup.c \
plat/imx/imx8qx/imx8qx_psci.c \
plat/imx/common/imx8_topology.c \
+ plat/imx/common/imx8_psci.c \
+ plat/common/plat_psci_common.c \
lib/xlat_tables/xlat_tables_common.c \
lib/xlat_tables/aarch64/xlat_tables.c \
lib/cpus/aarch64/cortex_a35.S \
diff --git a/plat/layerscape/board/ls1043/include/ls_def.h b/plat/layerscape/board/ls1043/include/ls_def.h
index 101512943..9c837204e 100644
--- a/plat/layerscape/board/ls1043/include/ls_def.h
+++ b/plat/layerscape/board/ls1043/include/ls_def.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __LS_DEF_H__
-#define __LS_DEF_H__
+#ifndef LS_DEF_H
+#define LS_DEF_H
#include <arch.h>
#include <common_def.h>
@@ -36,14 +36,14 @@
* within the power-state parameter.
*/
/* Local power state for power domains in Run state. */
-#define LS_LOCAL_STATE_RUN 0
+#define LS_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define LS_LOCAL_STATE_RET 1
+#define LS_LOCAL_STATE_RET U(1)
/*
* Local power state for OFF/power-down. Valid for CPU and cluster power
* domains
*/
-#define LS_LOCAL_STATE_OFF 2
+#define LS_LOCAL_STATE_OFF U(2)
#define LS_MAP_NS_DRAM MAP_REGION_FLAT( \
(LS_NS_DRAM_BASE), \
@@ -104,4 +104,4 @@
*/
#define PLAT_PERCPU_BAKERY_LOCK_SIZE (1 * CACHE_WRITEBACK_GRANULE)
-#endif /* __LS_DEF_H__ */
+#endif /* LS_DEF_H */
diff --git a/plat/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h
index 0e1cae606..46b2031e1 100644
--- a/plat/layerscape/board/ls1043/include/platform_def.h
+++ b/plat/layerscape/board/ls1043/include/platform_def.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <common_def.h>
#include <tzc400.h>
@@ -209,4 +209,4 @@
#define MAX_IO_DEVICES 3
#define MAX_IO_HANDLES 4
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/layerscape/board/ls1043/ls1043_psci.c b/plat/layerscape/board/ls1043/ls1043_psci.c
index 1c83df437..b402e7f77 100644
--- a/plat/layerscape/board/ls1043/ls1043_psci.c
+++ b/plat/layerscape/board/ls1043/ls1043_psci.c
@@ -5,15 +5,15 @@
*/
#include <arch_helpers.h>
+#include <assert.h>
#include <debug.h>
+#include <delay_timer.h>
+#include <endian.h>
#include <errno.h>
-#include <assert.h>
+#include <gicv2.h>
+#include <mmio.h>
#include <platform.h>
#include <psci.h>
-#include <mmio.h>
-#include <sys/endian.h>
-#include <gicv2.h>
-#include <delay_timer.h>
#include "platform_def.h"
#define LS_SCFG_BASE 0x01570000
diff --git a/plat/layerscape/common/include/ls_16550.h b/plat/layerscape/common/include/ls_16550.h
index 503a01dfb..8daafbb48 100644
--- a/plat/layerscape/common/include/ls_16550.h
+++ b/plat/layerscape/common/include/ls_16550.h
@@ -65,7 +65,7 @@
#ifndef __ASSEMBLY__
-#include <types.h>
+#include <stdint.h>
typedef struct {
console_t console;
diff --git a/plat/layerscape/common/include/plat_ls.h b/plat/layerscape/common/include/plat_ls.h
index 9d5ec1455..05b9c053b 100644
--- a/plat/layerscape/common/include/plat_ls.h
+++ b/plat/layerscape/common/include/plat_ls.h
@@ -7,8 +7,8 @@
#ifndef __PLAT_LS_H__
#define __PLAT_LS_H__
-#include <sys/types.h>
#include <cpu_data.h>
+#include <stdint.h>
/* BL1 utility functions */
void ls_bl1_platform_setup(void);
diff --git a/plat/layerscape/common/ls_bl1_setup.c b/plat/layerscape/common/ls_bl1_setup.c
index 43f745070..0642b5ef7 100644
--- a/plat/layerscape/common/ls_bl1_setup.c
+++ b/plat/layerscape/common/ls_bl1_setup.c
@@ -59,7 +59,7 @@ void ls_bl1_plat_arch_setup(void)
);
VERBOSE("After setup the page tables\n");
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el3(0);
#endif /* AARCH32 */
diff --git a/plat/layerscape/common/ls_bl2_setup.c b/plat/layerscape/common/ls_bl2_setup.c
index 6e6ad6eb1..4b2dc7245 100644
--- a/plat/layerscape/common/ls_bl2_setup.c
+++ b/plat/layerscape/common/ls_bl2_setup.c
@@ -53,7 +53,7 @@ void ls_bl2_plat_arch_setup(void)
);
#ifdef AARCH32
- enable_mmu_secure(0);
+ enable_mmu_svc_mon(0);
#else
enable_mmu_el1(0);
#endif
diff --git a/plat/layerscape/common/ls_bl31_setup.c b/plat/layerscape/common/ls_bl31_setup.c
index 3016f58e0..25fe407c5 100644
--- a/plat/layerscape/common/ls_bl31_setup.c
+++ b/plat/layerscape/common/ls_bl31_setup.c
@@ -5,6 +5,7 @@
*/
#include <assert.h>
+#include <bl_common.h>
#include <console.h>
#include <mmio.h>
#include <gicv2.h>
@@ -12,8 +13,6 @@
#include "plat_ls.h"
#include "soc.h"
-#define BL31_END (uintptr_t)(&__BL31_END__)
-
/*
* Placeholder variables for copying the arguments that have been passed to
* BL31 from BL2.
@@ -168,7 +167,7 @@ void ls_bl31_platform_setup(void)
/* Enable and initialize the System level generic timer */
mmio_write_32(LS1043_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0) | CNTCR_EN);
+ CNTCR_FCREQ(0U) | CNTCR_EN);
VERBOSE("Leave arm_bl31_platform_setup\n");
}
diff --git a/plat/marvell/a8k/a70x0/board/dram_port.c b/plat/marvell/a8k/a70x0/board/dram_port.c
new file mode 100644
index 000000000..c67025899
--- /dev/null
+++ b/plat/marvell/a8k/a70x0/board/dram_port.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <mv_ddr_if.h>
+#include <plat_marvell.h>
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+}
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+static struct mv_ddr_topology_map board_topology_map = {
+/* FIXME: MISL board 2CS 4Gb x8 devices of micron - 2133P */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0} },
+ SPEED_BIN_DDR_2133P, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_4GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
diff --git a/plat/marvell/a8k/a70x0/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0/board/marvell_plat_config.c
new file mode 100644
index 000000000..917198670
--- /dev/null
+++ b/plat/marvell/a8k/a70x0/board/marvell_plat_config.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map[] = {
+ /* CP0 SPI1 CS0 Direct Mode access */
+ {0xf900, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win,
+ uint32_t *size, uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO_WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#ifndef IMAGE_BLE
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map[] = {
+ /* PEX1_X1 window */
+ {0x00000000f7000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000f8000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x1000000, PEX0_TID},
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000f9000000, 0x1000000, RUNIT_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = iob_memory_map;
+ *size = ARRAY_SIZE(iob_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = { /* IO window */
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+ {0x00000000f2000000, 0xe000000, IO_0_TID},
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifdef IMAGE_BLE
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+#if PLAT_RECOVERY_IMAGE_ENABLE
+struct skip_image skip_im = {
+ .detection_method = GPIO,
+ .info.gpio.num = 33,
+ .info.gpio.button_state = HIGH,
+ .info.test.cp_ap = CP,
+ .info.test.cp_index = 0,
+};
+
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* Return the skip_image configurations */
+ return &skip_im;
+}
+#endif
+#endif
diff --git a/plat/marvell/a8k/a70x0/mvebu_def.h b/plat/marvell/a8k/a70x0/mvebu_def.h
new file mode 100644
index 000000000..a7c5abbb2
--- /dev/null
+++ b/plat/marvell/a8k/a70x0/mvebu_def.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 1 /* A70x0 has single CP0 */
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/a8k/a70x0/platform.mk b/plat/marvell/a8k/a70x0/platform.mk
new file mode 100644
index 000000000..29dfd9537
--- /dev/null
+++ b/plat/marvell/a8k/a70x0/platform.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+include plat/marvell/a8k/common/a8k_common.mk
+
+include plat/marvell/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a70x0_amc/board/dram_port.c b/plat/marvell/a8k/a70x0_amc/board/dram_port.c
new file mode 100644
index 000000000..ab1df465e
--- /dev/null
+++ b/plat/marvell/a8k/a70x0_amc/board/dram_port.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <mv_ddr_if.h>
+#include <plat_marvell.h>
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+}
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+static struct mv_ddr_topology_map board_topology_map = {
+/* FIXME: MISL board 2CS 8Gb x8 devices of micron - 2133P */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0},
+ {0x3, 0x2, 0, 0} },
+ SPEED_BIN_DDR_2400T, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_32BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
diff --git a/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c b/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c
new file mode 100644
index 000000000..ec4124c13
--- /dev/null
+++ b/plat/marvell/a8k/a70x0_amc/board/marvell_plat_config.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win *amb_memory_map;
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+#ifndef IMAGE_BLE
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map[] = {
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x6000000, PEX0_TID},
+ {0x00000000c0000000, 0x30000000, PEX0_TID},
+ {0x0000000800000000, 0x200000000, PEX0_TID},
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = iob_memory_map;
+ *size = ARRAY_SIZE(iob_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+ {0x00000000f2000000, 0xe000000, IO_0_TID},
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000000800000000, 0x200000000, IO_0_TID}, /* IO window */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifdef IMAGE_BLE
+
+struct pci_hw_cfg *plat_get_pcie_hw_data(void)
+{
+ return NULL;
+}
+
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+#if PLAT_RECOVERY_IMAGE_ENABLE
+struct skip_image skip_im = {
+ .detection_method = GPIO,
+ .info.gpio.num = 33,
+ .info.gpio.button_state = HIGH,
+ .info.test.cp_ap = CP,
+ .info.test.cp_index = 0,
+};
+
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* Return the skip_image configurations */
+ return &skip_im;
+}
+#endif
+#endif
diff --git a/plat/marvell/a8k/a70x0_amc/mvebu_def.h b/plat/marvell/a8k/a70x0_amc/mvebu_def.h
new file mode 100644
index 000000000..5c6655283
--- /dev/null
+++ b/plat/marvell/a8k/a70x0_amc/mvebu_def.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 1 /* A70x0 has single CP0 */
+
+/***********************************************************************
+ * Required platform porting definitions common to all
+ * Management Compute SubSystems (MSS)
+ ***********************************************************************
+ */
+/*
+ * Load address of SCP_BL2
+ * 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.
+ */
+#ifdef SCP_IMAGE
+#define SCP_BL2_BASE BL31_BASE
+#endif
+
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/a8k/a70x0_amc/platform.mk b/plat/marvell/a8k/a70x0_amc/platform.mk
new file mode 100644
index 000000000..29dfd9537
--- /dev/null
+++ b/plat/marvell/a8k/a70x0_amc/platform.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_7K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+include plat/marvell/a8k/common/a8k_common.mk
+
+include plat/marvell/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a80x0/board/dram_port.c b/plat/marvell/a8k/a80x0/board/dram_port.c
new file mode 100644
index 000000000..c720c117a
--- /dev/null
+++ b/plat/marvell/a8k/a80x0/board/dram_port.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <a8k_i2c.h>
+#include <debug.h>
+#include <mmio.h>
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+#define MVEBU_AP_MPP_CTRL0_7_REG MVEBU_AP_MPP_REGS(0)
+#define MVEBU_AP_MPP_CTRL4_OFFS 16
+#define MVEBU_AP_MPP_CTRL5_OFFS 20
+#define MVEBU_AP_MPP_CTRL4_I2C0_SDA_ENA 0x3
+#define MVEBU_AP_MPP_CTRL5_I2C0_SCK_ENA 0x3
+
+#define MVEBU_CP_MPP_CTRL37_OFFS 20
+#define MVEBU_CP_MPP_CTRL38_OFFS 24
+#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
+#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
+
+#define MVEBU_MPP_CTRL_MASK 0xf
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+static struct mv_ddr_topology_map board_topology_map = {
+ /* MISL board with 1CS 8Gb x4 devices of Micron 2400T */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0} },
+ /* TODO: double check if the speed bin is 2400T */
+ SPEED_BIN_DDR_2400T, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_64BIT_ECC_PUP8_BUS_MASK, /* subphys mask */
+ MV_DDR_CFG_SPD, /* ddr configuration data source */
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
+
+static void mpp_config(void)
+{
+ uintptr_t reg;
+ uint32_t val;
+
+ reg = MVEBU_CP_MPP_REGS(0, 4);
+ /* configure CP0 MPP 37 and 38 to i2c */
+ val = mmio_read_32(reg);
+ val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
+ val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA <<
+ MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA <<
+ MVEBU_CP_MPP_CTRL38_OFFS);
+ mmio_write_32(reg, val);
+}
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+ struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+ INFO("Gathering DRAM information\n");
+
+ if (tm->cfg_src == MV_DDR_CFG_SPD) {
+ /* configure MPPs to enable i2c */
+ mpp_config();
+
+ /* initialize i2c */
+ i2c_init((void *)MVEBU_CP0_I2C_BASE);
+
+ /* select SPD memory page 0 to access DRAM configuration */
+ i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);
+
+ /* read data from spd */
+ i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
+ sizeof(tm->spd_data.all_bytes));
+ }
+}
diff --git a/plat/marvell/a8k/a80x0/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0/board/marvell_plat_config.c
new file mode 100644
index 000000000..43beffabf
--- /dev/null
+++ b/plat/marvell/a8k/a80x0/board/marvell_plat_config.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map[] = {
+ /* CP1 SPI1 CS0 Direct Mode access */
+ {0xf900, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+ /* CP1 (MCI0) internal regs */
+ {0x00000000f4000000, 0x2000000, MCI_0_TID},
+#ifndef IMAGE_BLE
+ /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/
+ {0x00000000f9000000, 0x2000000, MCI_0_TID},
+ /* PCIe1 on CP1*/
+ {0x00000000fb000000, 0x1000000, MCI_0_TID},
+ /* PCIe2 on CP1*/
+ {0x00000000fc000000, 0x1000000, MCI_0_TID},
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+ /* CP0 */
+ /* PEX1_X1 window */
+ {0x00000000f7000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000f8000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x1000000, PEX0_TID}
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+ /* CP1 */
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000f9000000, 0x1000000, RUNIT_TID},
+ /* PEX1_X1 window */
+ {0x00000000fb000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000fc000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000fa000000, 0x1000000, PEX0_TID}
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = iob_memory_map_cp0;
+ *size = ARRAY_SIZE(iob_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = iob_memory_map_cp1;
+ *size = ARRAY_SIZE(iob_memory_map_cp1);
+ return 0;
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+ {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * SoC PM configuration
+ *****************************************************************************
+ */
+/* CP GPIO should be used and the GPIOs should be within same GPIO register */
+struct power_off_method pm_cfg = {
+ .type = PMIC_GPIO,
+ .cfg.gpio.pin_count = 1,
+ .cfg.gpio.info = {{0, 35} },
+ .cfg.gpio.step_count = 7,
+ .cfg.gpio.seq = {1, 0, 1, 0, 1, 0, 1},
+ .cfg.gpio.delay_ms = 10,
+};
+
+void *plat_marvell_get_pm_cfg(void)
+{
+ /* Return the PM configurations */
+ return &pm_cfg;
+}
+
+/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */
+#else
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+#if PLAT_RECOVERY_IMAGE_ENABLE
+struct skip_image skip_im = {
+ .detection_method = GPIO,
+ .info.gpio.num = 33,
+ .info.gpio.button_state = HIGH,
+ .info.test.cp_ap = CP,
+ .info.test.cp_index = 0,
+};
+
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* Return the skip_image configurations */
+ return &skip_im;
+}
+#endif
+#endif
diff --git a/plat/marvell/a8k/a80x0/mvebu_def.h b/plat/marvell/a8k/a80x0/mvebu_def.h
new file mode 100644
index 000000000..5bff12ce5
--- /dev/null
+++ b/plat/marvell/a8k/a80x0/mvebu_def.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */
+#define I2C_SPD_ADDR 0x53 /* Access SPD data */
+#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/a8k/a80x0/platform.mk b/plat/marvell/a8k/a80x0/platform.mk
new file mode 100644
index 000000000..0fe235b67
--- /dev/null
+++ b/plat/marvell/a8k/a80x0/platform.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+include plat/marvell/a8k/common/a8k_common.mk
+
+include plat/marvell/common/marvell_common.mk
diff --git a/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c b/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c
new file mode 100644
index 000000000..b455b837b
--- /dev/null
+++ b/plat/marvell/a8k/a80x0_mcbin/board/dram_port.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <a8k_i2c.h>
+#include <debug.h>
+#include <mmio.h>
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+#define MVEBU_CP_MPP_CTRL37_OFFS 20
+#define MVEBU_CP_MPP_CTRL38_OFFS 24
+#define MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA 0x2
+#define MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA 0x2
+
+#define MVEBU_MPP_CTRL_MASK 0xf
+
+/*
+ * This struct provides the DRAM training code with
+ * the appropriate board DRAM configuration
+ */
+static struct mv_ddr_topology_map board_topology_map = {
+ /* Board with 1CS 8Gb x4 devices of Micron 2400T */
+ DEBUG_LEVEL_ERROR,
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X subphys */
+ { { { {0x1, 0x0, 0, 0}, /* FIXME: change the cs mask for all 64 bit */
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0},
+ {0x1, 0x0, 0, 0} },
+ /* TODO: double check if the speed bin is 2400T */
+ SPEED_BIN_DDR_2400T, /* speed_bin */
+ MV_DDR_DEV_WIDTH_8BIT, /* sdram device width */
+ MV_DDR_DIE_CAP_8GBIT, /* die capacity */
+ MV_DDR_FREQ_SAR, /* frequency */
+ 0, 0, /* cas_l, cas_wl */
+ MV_DDR_TEMP_LOW} }, /* temperature */
+ MV_DDR_64BIT_BUS_MASK, /* subphys mask */
+ MV_DDR_CFG_SPD, /* ddr configuration data source */
+ { {0} }, /* raw spd data */
+ {0}, /* timing parameters */
+ { /* electrical configuration */
+ { /* memory electrical configuration */
+ MV_DDR_RTT_NOM_PARK_RZQ_DISABLE, /* rtt_nom */
+ {
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV4, /* rtt_park 1cs */
+ MV_DDR_RTT_NOM_PARK_RZQ_DIV1 /* rtt_park 2cs */
+ },
+ {
+ MV_DDR_RTT_WR_DYN_ODT_OFF, /* rtt_wr 1cs */
+ MV_DDR_RTT_WR_RZQ_DIV2 /* rtt_wr 2cs */
+ },
+ MV_DDR_DIC_RZQ_DIV7 /* dic */
+ },
+ { /* phy electrical configuration */
+ MV_DDR_OHM_30, /* data_drv_p */
+ MV_DDR_OHM_30, /* data_drv_n */
+ MV_DDR_OHM_30, /* ctrl_drv_p */
+ MV_DDR_OHM_30, /* ctrl_drv_n */
+ {
+ MV_DDR_OHM_60, /* odt_p 1cs */
+ MV_DDR_OHM_120 /* odt_p 2cs */
+ },
+ {
+ MV_DDR_OHM_60, /* odt_n 1cs */
+ MV_DDR_OHM_120 /* odt_n 2cs */
+ },
+ },
+ { /* mac electrical configuration */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_pattern */
+ MV_DDR_ODT_CFG_ALWAYS_ON, /* odtcfg_write */
+ MV_DDR_ODT_CFG_NORMAL, /* odtcfg_read */
+ },
+ }
+};
+
+struct mv_ddr_topology_map *mv_ddr_topology_map_get(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
+
+static void mpp_config(void)
+{
+ uint32_t val;
+ uintptr_t reg = MVEBU_CP_MPP_REGS(0, 4);
+
+ /* configure CP0 MPP 37 and 38 to i2c */
+ val = mmio_read_32(reg);
+ val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS));
+ val |= (MVEBU_CP_MPP_CTRL37_I2C0_SCK_ENA << MVEBU_CP_MPP_CTRL37_OFFS) |
+ (MVEBU_CP_MPP_CTRL38_I2C0_SDA_ENA << MVEBU_CP_MPP_CTRL38_OFFS);
+ mmio_write_32(reg, val);
+}
+
+/*
+ * This function may modify the default DRAM parameters
+ * based on information received from SPD or bootloader
+ * configuration located on non volatile storage
+ */
+void plat_marvell_dram_update_topology(void)
+{
+ struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get();
+
+ INFO("Gathering DRAM information\n");
+
+ if (tm->cfg_src == MV_DDR_CFG_SPD) {
+ /* configure MPPs to enable i2c */
+ mpp_config();
+ /* initialize the i2c */
+ i2c_init((void *)MVEBU_CP0_I2C_BASE);
+ /* select SPD memory page 0 to access DRAM configuration */
+ i2c_write(I2C_SPD_P0_ADDR, 0x0, 1, tm->spd_data.all_bytes, 1);
+ /* read data from spd */
+ i2c_read(I2C_SPD_ADDR, 0x0, 1, tm->spd_data.all_bytes,
+ sizeof(tm->spd_data.all_bytes));
+ }
+}
diff --git a/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c b/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c
new file mode 100644
index 000000000..079bd8fef
--- /dev/null
+++ b/plat/marvell/a8k/a80x0_mcbin/board/marvell_plat_config.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+#include <delay_timer.h>
+#include <mmio.h>
+/*
+ * If bootrom is currently at BLE there's no need to include the memory
+ * maps structure at this point
+ */
+#include <mvebu_def.h>
+#ifndef IMAGE_BLE
+
+/*****************************************************************************
+ * GPIO Configuration
+ *****************************************************************************
+ */
+#define MPP_CONTROL_REGISTER 0xf2440018
+#define MPP_CONTROL_MPP_SEL_52_MASK 0xf0000
+#define GPIO_DATA_OUT1_REGISTER 0xf2440140
+#define GPIO_DATA_OUT_EN_CTRL1_REGISTER 0xf2440144
+#define GPIO52_MASK 0x100000
+
+/* Reset PCIe via GPIO number 52 */
+int marvell_gpio_config(void)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32(MPP_CONTROL_REGISTER);
+ reg |= MPP_CONTROL_MPP_SEL_52_MASK;
+ mmio_write_32(MPP_CONTROL_REGISTER, reg);
+
+ reg = mmio_read_32(GPIO_DATA_OUT1_REGISTER);
+ reg |= GPIO52_MASK;
+ mmio_write_32(GPIO_DATA_OUT1_REGISTER, reg);
+
+ reg = mmio_read_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER);
+ reg &= ~GPIO52_MASK;
+ mmio_write_32(GPIO_DATA_OUT_EN_CTRL1_REGISTER, reg);
+ udelay(100);
+
+ return 0;
+}
+
+/*****************************************************************************
+ * AMB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win amb_memory_map[] = {
+ /* CP1 SPI1 CS0 Direct Mode access */
+ {0xf900, 0x1000000, AMB_SPI1_CS0_ID},
+};
+
+int marvell_get_amb_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ *win = amb_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(amb_memory_map);
+
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * IO WIN Configuration
+ *****************************************************************************
+ */
+struct addr_map_win io_win_memory_map[] = {
+ /* CP1 (MCI0) internal regs */
+ {0x00000000f4000000, 0x2000000, MCI_0_TID},
+#ifndef IMAGE_BLE
+ /* PCIe0 and SPI1_CS0 (RUNIT) on CP1*/
+ {0x00000000f9000000, 0x2000000, MCI_0_TID},
+ /* PCIe1 on CP1*/
+ {0x00000000fb000000, 0x1000000, MCI_0_TID},
+ /* PCIe2 on CP1*/
+ {0x00000000fc000000, 0x1000000, MCI_0_TID},
+ /* MCI 0 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(0), 0x100000, MCI_0_TID},
+ /* MCI 1 indirect window */
+ {MVEBU_MCI_REG_BASE_REMAP(1), 0x100000, MCI_1_TID},
+#endif
+};
+
+uint32_t marvell_get_io_win_gcr_target(int ap_index)
+{
+ return PIDI_TID;
+}
+
+int marvell_get_io_win_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = io_win_memory_map;
+ if (*win == NULL)
+ *size = 0;
+ else
+ *size = ARRAY_SIZE(io_win_memory_map);
+
+ return 0;
+}
+
+#ifndef IMAGE_BLE
+/*****************************************************************************
+ * IOB Configuration
+ *****************************************************************************
+ */
+struct addr_map_win iob_memory_map_cp0[] = {
+ /* CP0 */
+ /* PEX1_X1 window */
+ {0x00000000f7000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000f8000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000f6000000, 0x1000000, PEX0_TID},
+ {0x00000000c0000000, 0x30000000, PEX0_TID},
+ {0x0000000800000000, 0x100000000, PEX0_TID},
+};
+
+struct addr_map_win iob_memory_map_cp1[] = {
+ /* CP1 */
+ /* SPI1_CS0 (RUNIT) window */
+ {0x00000000f9000000, 0x1000000, RUNIT_TID},
+ /* PEX1_X1 window */
+ {0x00000000fb000000, 0x1000000, PEX1_TID},
+ /* PEX2_X1 window */
+ {0x00000000fc000000, 0x1000000, PEX2_TID},
+ /* PEX0_X4 window */
+ {0x00000000fa000000, 0x1000000, PEX0_TID}
+};
+
+int marvell_get_iob_memory_map(struct addr_map_win **win, uint32_t *size,
+ uintptr_t base)
+{
+ switch (base) {
+ case MVEBU_CP_REGS_BASE(0):
+ *win = iob_memory_map_cp0;
+ *size = ARRAY_SIZE(iob_memory_map_cp0);
+ return 0;
+ case MVEBU_CP_REGS_BASE(1):
+ *win = iob_memory_map_cp1;
+ *size = ARRAY_SIZE(iob_memory_map_cp1);
+ return 0;
+ default:
+ *size = 0;
+ *win = 0;
+ return 1;
+ }
+}
+#endif
+
+/*****************************************************************************
+ * CCU Configuration
+ *****************************************************************************
+ */
+struct addr_map_win ccu_memory_map[] = {
+#ifdef IMAGE_BLE
+ {0x00000000f2000000, 0x4000000, IO_0_TID}, /* IO window */
+#else
+ {0x00000000f2000000, 0xe000000, IO_0_TID}, /* IO window */
+ {0x00000000c0000000, 0x30000000, IO_0_TID}, /* IO window */
+ {0x0000000800000000, 0x100000000, IO_0_TID}, /* IO window */
+#endif
+};
+
+uint32_t marvell_get_ccu_gcr_target(int ap)
+{
+ return DRAM_0_TID;
+}
+
+int marvell_get_ccu_memory_map(int ap_index, struct addr_map_win **win,
+ uint32_t *size)
+{
+ *win = ccu_memory_map;
+ *size = ARRAY_SIZE(ccu_memory_map);
+
+ return 0;
+}
+
+/* In reference to #ifndef IMAGE_BLE, this part is used for BLE only. */
+
+/*****************************************************************************
+ * SKIP IMAGE Configuration
+ *****************************************************************************
+ */
+void *plat_marvell_get_skip_image_data(void)
+{
+ /* No recovery button on A8k-MCBIN board */
+ return NULL;
+}
diff --git a/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h b/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h
new file mode 100644
index 000000000..5bff12ce5
--- /dev/null
+++ b/plat/marvell/a8k/a80x0_mcbin/mvebu_def.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MVEBU_DEF_H__
+#define __MVEBU_DEF_H__
+
+#include <a8k_plat_def.h>
+
+#define CP_COUNT 2 /* A80x0 has both CP0 & CP1 */
+#define I2C_SPD_ADDR 0x53 /* Access SPD data */
+#define I2C_SPD_P0_ADDR 0x36 /* Select SPD data page 0 */
+
+#endif /* __MVEBU_DEF_H__ */
diff --git a/plat/marvell/a8k/a80x0_mcbin/platform.mk b/plat/marvell/a8k/a80x0_mcbin/platform.mk
new file mode 100644
index 000000000..0fe235b67
--- /dev/null
+++ b/plat/marvell/a8k/a80x0_mcbin/platform.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PCI_EP_SUPPORT := 0
+
+DOIMAGE_SEC := tools/doimage/secure/sec_img_8K.cfg
+
+MARVELL_MOCHI_DRV := drivers/marvell/mochi/apn806_setup.c
+
+include plat/marvell/a8k/common/a8k_common.mk
+
+include plat/marvell/common/marvell_common.mk
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
new file mode 100644
index 000000000..3bcce96b2
--- /dev/null
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -0,0 +1,122 @@
+#
+# Copyright (C) 2016 - 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+
+include tools/doimage/doimage.mk
+
+PLAT_FAMILY := a8k
+PLAT_FAMILY_BASE := plat/marvell/$(PLAT_FAMILY)
+PLAT_INCLUDE_BASE := include/plat/marvell/$(PLAT_FAMILY)
+PLAT_COMMON_BASE := $(PLAT_FAMILY_BASE)/common
+MARVELL_DRV_BASE := drivers/marvell
+MARVELL_COMMON_BASE := plat/marvell/common
+
+ERRATA_A72_859971 := 1
+
+# Enable MSS support for a8k family
+MSS_SUPPORT := 1
+
+# Disable EL3 cache for power management
+BL31_CACHE_DISABLE := 1
+$(eval $(call add_define,BL31_CACHE_DISABLE))
+
+$(eval $(call add_define,PCI_EP_SUPPORT))
+$(eval $(call assert_boolean,PCI_EP_SUPPORT))
+
+DOIMAGEPATH ?= tools/doimage
+DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage
+
+ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin
+DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS)
+
+# This define specifies DDR type for BLE
+$(eval $(call add_define,CONFIG_DDR4))
+
+MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ plat/common/plat_gicv2.c
+
+ATF_INCLUDES := -Iinclude/common/tbbr
+
+PLAT_INCLUDES := -I$(PLAT_FAMILY_BASE)/$(PLAT) \
+ -I$(PLAT_COMMON_BASE)/include \
+ -I$(PLAT_INCLUDE_BASE)/common \
+ -Iinclude/drivers/marvell \
+ -Iinclude/drivers/marvell/mochi \
+ $(ATF_INCLUDES)
+
+PLAT_BL_COMMON_SOURCES := $(PLAT_COMMON_BASE)/aarch64/a8k_common.c \
+ drivers/console/aarch64/console.S \
+ drivers/ti/uart/aarch64/16550_console.S
+
+BLE_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/dram_port.c \
+ $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+
+MARVELL_MOCHI_DRV += $(MARVELL_DRV_BASE)/mochi/cp110_setup.c
+
+BLE_SOURCES := $(PLAT_COMMON_BASE)/plat_ble_setup.c \
+ $(MARVELL_MOCHI_DRV) \
+ $(MARVELL_DRV_BASE)/i2c/a8k_i2c.c \
+ $(PLAT_COMMON_BASE)/plat_pm.c \
+ $(MARVELL_DRV_BASE)/thermal.c \
+ $(PLAT_COMMON_BASE)/plat_thermal.c \
+ $(BLE_PORTING_SOURCES) \
+ $(MARVELL_DRV_BASE)/ccu.c \
+ $(MARVELL_DRV_BASE)/io_win.c
+
+BL1_SOURCES += $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
+ lib/cpus/aarch64/cortex_a72.S
+
+MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \
+ $(MARVELL_DRV_BASE)/iob.c \
+ $(MARVELL_DRV_BASE)/mci.c \
+ $(MARVELL_DRV_BASE)/amb_adec.c \
+ $(MARVELL_DRV_BASE)/ccu.c \
+ $(MARVELL_DRV_BASE)/cache_llc.c \
+ $(MARVELL_DRV_BASE)/comphy/phy-comphy-cp110.c
+
+BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+
+BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \
+ $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
+ $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \
+ $(PLAT_COMMON_BASE)/plat_pm.c \
+ $(PLAT_COMMON_BASE)/plat_bl31_setup.c \
+ $(MARVELL_COMMON_BASE)/marvell_gicv2.c \
+ $(MARVELL_COMMON_BASE)/mrvl_sip_svc.c \
+ $(MARVELL_COMMON_BASE)/marvell_ddr_info.c \
+ $(BL31_PORTING_SOURCES) \
+ $(MARVELL_DRV) \
+ $(MARVELL_MOCHI_DRV) \
+ $(MARVELL_GIC_SOURCES)
+
+# Add trace functionality for PM
+BL31_SOURCES += $(PLAT_COMMON_BASE)/plat_pm_trace.c
+
+# Disable the PSCI platform compatibility layer (allows porting
+# from Old Platform APIs to the new APIs).
+# It is not needed since Marvell platform already used the new platform APIs.
+ENABLE_PLAT_COMPAT := 0
+
+# Force builds with BL2 image on a80x0 platforms
+ifndef SCP_BL2
+ $(error "Error: SCP_BL2 image is mandatory for a8k family")
+endif
+
+# MSS (SCP) build
+include $(PLAT_COMMON_BASE)/mss/mss_a8k.mk
+
+# BLE (ROM context execution code, AKA binary extension)
+BLE_PATH ?= ble
+
+include ${BLE_PATH}/ble.mk
+$(eval $(call MAKE_BL,e))
+
+mrvl_flash: ${BUILD_PLAT}/${FIP_NAME} ${DOIMAGETOOL} ${BUILD_PLAT}/ble.bin
+ $(shell truncate -s %128K ${BUILD_PLAT}/bl1.bin)
+ $(shell cat ${BUILD_PLAT}/bl1.bin ${BUILD_PLAT}/${FIP_NAME} > ${BUILD_PLAT}/${BOOT_IMAGE})
+ ${DOIMAGETOOL} ${DOIMAGE_FLAGS} ${BUILD_PLAT}/${BOOT_IMAGE} ${BUILD_PLAT}/${FLASH_IMAGE}
+
diff --git a/plat/marvell/a8k/common/aarch64/a8k_common.c b/plat/marvell/a8k/common/aarch64/a8k_common.c
new file mode 100644
index 000000000..7c2bf318f
--- /dev/null
+++ b/plat/marvell/a8k/common/aarch64/a8k_common.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <plat_marvell.h>
+
+
+/* MMU entry for internal (register) space access */
+#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
+ DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ */
+#if IMAGE_BL1
+const mmap_region_t plat_marvell_mmap[] = {
+ MARVELL_MAP_SHARED_RAM,
+ MAP_DEVICE0,
+ {0}
+};
+#endif
+#if IMAGE_BL2
+const mmap_region_t plat_marvell_mmap[] = {
+ MARVELL_MAP_SHARED_RAM,
+ MAP_DEVICE0,
+ MARVELL_MAP_DRAM,
+ {0}
+};
+#endif
+
+#if IMAGE_BL2U
+const mmap_region_t plat_marvell_mmap[] = {
+ MAP_DEVICE0,
+ {0}
+};
+#endif
+
+#if IMAGE_BLE
+const mmap_region_t plat_marvell_mmap[] = {
+ MAP_DEVICE0,
+ {0}
+};
+#endif
+
+#if IMAGE_BL31
+const mmap_region_t plat_marvell_mmap[] = {
+ MARVELL_MAP_SHARED_RAM,
+ MAP_DEVICE0,
+ MARVELL_MAP_DRAM,
+ {0}
+};
+#endif
+#if IMAGE_BL32
+const mmap_region_t plat_marvell_mmap[] = {
+ MAP_DEVICE0,
+ {0}
+};
+#endif
+
+MARVELL_CASSERT_MMAP;
diff --git a/plat/marvell/a8k/common/aarch64/plat_arch_config.c b/plat/marvell/a8k/common/aarch64/plat_arch_config.c
new file mode 100644
index 000000000..866733145
--- /dev/null
+++ b/plat/marvell/a8k/common/aarch64/plat_arch_config.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <platform.h>
+#include <arch_helpers.h>
+#include <mmio.h>
+#include <debug.h>
+#include <cache_llc.h>
+
+
+#define CCU_HTC_ASET (MVEBU_CCU_BASE(MVEBU_AP0) + 0x264)
+#define MVEBU_IO_AFFINITY (0xF00)
+
+
+static void plat_enable_affinity(void)
+{
+ int cluster_id;
+ int affinity;
+
+ /* set CPU Affinity */
+ cluster_id = plat_my_core_pos() / PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ affinity = (MVEBU_IO_AFFINITY | (1 << cluster_id));
+ mmio_write_32(CCU_HTC_ASET, affinity);
+
+ /* set barier */
+ isb();
+}
+
+void marvell_psci_arch_init(int die_index)
+{
+#if LLC_ENABLE
+ /* check if LLC is in exclusive mode
+ * as L2 is configured to UniqueClean eviction
+ * (in a8k reset handler)
+ */
+ if (llc_is_exclusive(0) == 0)
+ ERROR("LLC should be configured to exclusice mode\n");
+#endif
+
+ /* Enable Affinity */
+ plat_enable_affinity();
+}
diff --git a/plat/marvell/a8k/common/aarch64/plat_helpers.S b/plat/marvell/a8k/common/aarch64/plat_helpers.S
new file mode 100644
index 000000000..fadc4c26b
--- /dev/null
+++ b/plat/marvell/a8k/common/aarch64/plat_helpers.S
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+#include <marvell_pm.h>
+
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_get_my_entrypoint
+ .globl plat_is_my_cpu_primary
+ .globl plat_reset_handler
+
+ /* -----------------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * This function performs any platform specific actions
+ * needed for a secondary cpu after a cold reset. Right
+ * now this is a stub function.
+ * -----------------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ mov x0, #0
+ ret
+endfunc plat_secondary_cold_boot_setup
+
+ /* ---------------------------------------------------------------------
+ * unsigned long plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish
+ * between a cold and warm boot
+ * For a cold boot, return 0.
+ * For a warm boot, read the mailbox and return the address it contains.
+ *
+ * ---------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ /* Read first word and compare it with magic num */
+ mov_imm x0, PLAT_MARVELL_MAILBOX_BASE
+ ldr x1, [x0]
+ mov_imm x2, MVEBU_MAILBOX_MAGIC_NUM
+ cmp x1, x2
+ beq warm_boot /* If compare failed, return 0, i.e. cold boot */
+ mov x0, #0
+ ret
+warm_boot:
+ mov_imm x1, MBOX_IDX_SEC_ADDR /* Get the jump address */
+ subs x1, x1, #1
+ mov x2, #(MBOX_IDX_SEC_ADDR * 8)
+ lsl x3, x2, x1
+ add x0, x0, x3
+ ldr x0, [x0]
+ ret
+endfunc plat_get_my_entrypoint
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary
+ * cpu.
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
+ and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ cmp x0, #MVEBU_PRIMARY_CPU
+ cset w0, eq
+ ret
+endfunc plat_is_my_cpu_primary
+
+ /* -----------------------------------------------------
+ * void plat_reset_handler (void);
+ *
+ * Platform specific configuration right after cpu is
+ * is our of reset.
+ *
+ * The plat_reset_handler can clobber x0 - x18, x30.
+ * -----------------------------------------------------
+ */
+func plat_reset_handler
+ /*
+ * Note: the configurations below should be done before MMU,
+ * I Cache and L2are enabled.
+ * The reset handler is executed right after reset
+ * and before Caches are enabled.
+ */
+
+ /* Enable L1/L2 ECC and Parity */
+ mrs x5, s3_1_c11_c0_2 /* L2 Ctrl */
+ orr x5, x5, #(1 << 21) /* Enable L1/L2 cache ECC & Parity */
+ msr s3_1_c11_c0_2, x5 /* L2 Ctrl */
+
+#if LLC_ENABLE
+ /*
+ * Enable L2 UniqueClean evictions
+ * Note: this configuration assumes that LLC is configured
+ * in exclusive mode.
+ * Later on in the code this assumption will be validated
+ */
+ mrs x5, s3_1_c15_c0_0 /* L2 Ctrl */
+ orr x5, x5, #(1 << 14) /* Enable UniqueClean evictions with data */
+ msr s3_1_c15_c0_0, x5 /* L2 Ctrl */
+#endif
+
+ /* Instruction Barrier to allow msr command completion */
+ isb
+
+ ret
+endfunc plat_reset_handler
diff --git a/plat/marvell/a8k/common/include/a8k_plat_def.h b/plat/marvell/a8k/common/include/a8k_plat_def.h
new file mode 100644
index 000000000..4ed8c7e6a
--- /dev/null
+++ b/plat/marvell/a8k/common/include/a8k_plat_def.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __A8K_PLAT_DEF_H__
+#define __A8K_PLAT_DEF_H__
+
+#include <marvell_def.h>
+
+#define MVEBU_PRIMARY_CPU 0x0
+#define MVEBU_AP0 0x0
+
+/* APN806 revision ID */
+#define MVEBU_CSS_GWD_CTRL_IIDR2_REG (MVEBU_REGS_BASE + 0x610FCC)
+#define GWD_IIDR2_REV_ID_OFFSET 12
+#define GWD_IIDR2_REV_ID_MASK 0xF
+#define GWD_IIDR2_CHIP_ID_OFFSET 20
+#define GWD_IIDR2_CHIP_ID_MASK (0xFFF << GWD_IIDR2_CHIP_ID_OFFSET)
+
+#define CHIP_ID_AP806 0x806
+#define CHIP_ID_AP807 0x807
+
+#define COUNTER_FREQUENCY 25000000
+
+#define MVEBU_REGS_BASE 0xF0000000
+#define MVEBU_REGS_BASE_MASK 0xF0000000
+#define MVEBU_REGS_BASE_AP(ap) MVEBU_REGS_BASE
+#define MVEBU_CP_REGS_BASE(cp_index) (0xF2000000 + (cp_index) * 0x2000000)
+#define MVEBU_RFU_BASE (MVEBU_REGS_BASE + 0x6F0000)
+#define MVEBU_IO_WIN_BASE(ap_index) (MVEBU_RFU_BASE)
+#define MVEBU_IO_WIN_GCR_OFFSET (0x70)
+#define MVEBU_IO_WIN_MAX_WINS (7)
+
+/* Misc SoC configurations Base */
+#define MVEBU_MISC_SOC_BASE (MVEBU_REGS_BASE + 0x6F4300)
+
+#define MVEBU_CCU_BASE(ap_index) (MVEBU_REGS_BASE + 0x4000)
+#define MVEBU_CCU_MAX_WINS (8)
+
+#define MVEBU_LLC_BASE(ap_index) (MVEBU_REGS_BASE + 0x8000)
+#define MVEBU_DRAM_MAC_BASE (MVEBU_REGS_BASE + 0x20000)
+#define MVEBU_DRAM_PHY_BASE (MVEBU_REGS_BASE + 0x20000)
+#define MVEBU_SMMU_BASE (MVEBU_REGS_BASE + 0x100000)
+#define MVEBU_CP_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \
+ 0x440000 + ((n) << 2))
+#define MVEBU_PM_MPP_REGS(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \
+ 0x440000 + ((n / 8) << 2))
+#define MVEBU_CP_GPIO_DATA_OUT(cp_index, n) \
+ (MVEBU_CP_REGS_BASE(cp_index) + \
+ 0x440100 + ((n > 32) ? 0x40 : 0x00))
+#define MVEBU_CP_GPIO_DATA_OUT_EN(cp_index, n) \
+ (MVEBU_CP_REGS_BASE(cp_index) + \
+ 0x440104 + ((n > 32) ? 0x40 : 0x00))
+#define MVEBU_CP_GPIO_DATA_IN(cp_index, n) (MVEBU_CP_REGS_BASE(cp_index) + \
+ 0x440110 + ((n > 32) ? 0x40 : 0x00))
+#define MVEBU_AP_MPP_REGS(n) (MVEBU_RFU_BASE + 0x4000 + ((n) << 2))
+#define MVEBU_AP_GPIO_REGS (MVEBU_RFU_BASE + 0x5040)
+#define MVEBU_AP_GPIO_DATA_IN (MVEBU_AP_GPIO_REGS + 0x10)
+#define MVEBU_AP_I2C_BASE (MVEBU_REGS_BASE + 0x511000)
+#define MVEBU_CP0_I2C_BASE (MVEBU_CP_REGS_BASE(0) + 0x701000)
+#define MVEBU_AP_EXT_TSEN_BASE (MVEBU_RFU_BASE + 0x8084)
+
+#define MVEBU_AP_MC_TRUSTZONE_REG_LOW(ap, win) (MVEBU_REGS_BASE_AP(ap) + \
+ 0x20080 + ((win) * 0x8))
+#define MVEBU_AP_MC_TRUSTZONE_REG_HIGH(ap, win) (MVEBU_REGS_BASE_AP(ap) + \
+ 0x20084 + ((win) * 0x8))
+
+/* MCI indirect access definitions */
+#define MCI_MAX_UNIT_ID 2
+/* SoC RFU / IHBx4 Control */
+#define MCIX4_REG_START_ADDRESS_REG(unit_id) (MVEBU_RFU_BASE + \
+ 0x4218 + (unit_id * 0x20))
+#define MCI_REMAP_OFF_SHIFT 8
+
+#define MVEBU_MCI_REG_BASE_REMAP(index) (0xFD000000 + \
+ ((index) * 0x1000000))
+
+#define MVEBU_PCIE_X4_MAC_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x600000)
+#define MVEBU_COMPHY_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x441000)
+#define MVEBU_HPIPE_BASE(x) (MVEBU_CP_REGS_BASE(x) + 0x120000)
+#define MVEBU_CP_DFX_OFFSET (0x400200)
+
+/*****************************************************************************
+ * MVEBU memory map related constants
+ *****************************************************************************
+ */
+/* Aggregate of all devices in the first GB */
+#define DEVICE0_BASE MVEBU_REGS_BASE
+#define DEVICE0_SIZE 0x10000000
+
+/*****************************************************************************
+ * GIC-400 & interrupt handling related constants
+ *****************************************************************************
+ */
+/* Base MVEBU compatible GIC memory map */
+#define MVEBU_GICD_BASE 0x210000
+#define MVEBU_GICC_BASE 0x220000
+
+
+/*****************************************************************************
+ * AXI Configuration
+ *****************************************************************************
+ */
+#define MVEBU_AXI_ATTR_ARCACHE_OFFSET 4
+#define MVEBU_AXI_ATTR_ARCACHE_MASK (0xF << \
+ MVEBU_AXI_ATTR_ARCACHE_OFFSET)
+#define MVEBU_AXI_ATTR_ARDOMAIN_OFFSET 12
+#define MVEBU_AXI_ATTR_ARDOMAIN_MASK (0x3 << \
+ MVEBU_AXI_ATTR_ARDOMAIN_OFFSET)
+#define MVEBU_AXI_ATTR_AWCACHE_OFFSET 20
+#define MVEBU_AXI_ATTR_AWCACHE_MASK (0xF << \
+ MVEBU_AXI_ATTR_AWCACHE_OFFSET)
+#define MVEBU_AXI_ATTR_AWDOMAIN_OFFSET 28
+#define MVEBU_AXI_ATTR_AWDOMAIN_MASK (0x3 << \
+ MVEBU_AXI_ATTR_AWDOMAIN_OFFSET)
+
+/* SATA MBUS to AXI configuration */
+#define MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET 1
+#define MVEBU_SATA_M2A_AXI_ARCACHE_MASK (0xF << \
+ MVEBU_SATA_M2A_AXI_ARCACHE_OFFSET)
+#define MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET 5
+#define MVEBU_SATA_M2A_AXI_AWCACHE_MASK (0xF << \
+ MVEBU_SATA_M2A_AXI_AWCACHE_OFFSET)
+
+/* ARM cache attributes */
+#define CACHE_ATTR_BUFFERABLE 0x1
+#define CACHE_ATTR_CACHEABLE 0x2
+#define CACHE_ATTR_READ_ALLOC 0x4
+#define CACHE_ATTR_WRITE_ALLOC 0x8
+/* Domain */
+#define DOMAIN_NON_SHAREABLE 0x0
+#define DOMAIN_INNER_SHAREABLE 0x1
+#define DOMAIN_OUTER_SHAREABLE 0x2
+#define DOMAIN_SYSTEM_SHAREABLE 0x3
+
+/************************************************************************
+ * Required platform porting definitions common to all
+ * Management Compute SubSystems (MSS)
+ ************************************************************************
+ */
+/*
+ * Load address of SCP_BL2
+ * 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.
+ */
+#ifdef SCP_IMAGE
+#define SCP_BL2_BASE BL31_BASE
+#endif
+
+#ifndef __ASSEMBLER__
+enum ap806_sar_target_dev {
+ SAR_PIDI_MCIX2 = 0x0,
+ SAR_MCIX4 = 0x1,
+ SAR_SPI = 0x2,
+ SAR_SD = 0x3,
+ SAR_PIDI_MCIX2_BD = 0x4, /* BootRom disabled */
+ SAR_MCIX4_DB = 0x5, /* BootRom disabled */
+ SAR_SPI_DB = 0x6, /* BootRom disabled */
+ SAR_EMMC = 0x7
+};
+
+enum io_win_target_ids {
+ MCI_0_TID = 0x0,
+ MCI_1_TID = 0x1,
+ MCI_2_TID = 0x2,
+ PIDI_TID = 0x3,
+ SPI_TID = 0x4,
+ STM_TID = 0x5,
+ BOOTROM_TID = 0x6,
+ IO_WIN_MAX_TID
+};
+
+enum ccu_target_ids {
+ IO_0_TID = 0x00,
+ DRAM_0_TID = 0x03,
+ IO_1_TID = 0x0F,
+ CFG_REG_TID = 0x10,
+ RAR_TID = 0x20,
+ SRAM_TID = 0x40,
+ DRAM_1_TID = 0xC0,
+ CCU_MAX_TID,
+ INVALID_TID = 0xFF
+};
+#endif /* __ASSEMBLER__ */
+
+#endif /* __A8K_PLAT_DEF_H__ */
diff --git a/plat/marvell/a8k/common/include/ddr_info.h b/plat/marvell/a8k/common/include/ddr_info.h
new file mode 100644
index 000000000..e19036a26
--- /dev/null
+++ b/plat/marvell/a8k/common/include/ddr_info.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#define DRAM_MAX_IFACE 1
+#define DRAM_CH0_MMAP_LOW_OFFSET 0x20200
diff --git a/plat/marvell/a8k/common/include/plat_macros.S b/plat/marvell/a8k/common/include/plat_macros.S
new file mode 100644
index 000000000..2a6ccf27c
--- /dev/null
+++ b/plat/marvell/a8k/common/include/plat_macros.S
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PLAT_MACROS_S__
+#define __PLAT_MACROS_S__
+
+#include <marvell_macros.S>
+
+/*
+ * Required platform porting macros
+ * (Provided by included headers)
+ */
+.macro plat_crash_print_regs
+.endm
+
+#endif /* __PLAT_MACROS_S__ */
diff --git a/plat/marvell/a8k/common/include/platform_def.h b/plat/marvell/a8k/common/include/platform_def.h
new file mode 100644
index 000000000..f7bd23fa2
--- /dev/null
+++ b/plat/marvell/a8k/common/include/platform_def.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PLATFORM_DEF_H__
+#define __PLATFORM_DEF_H__
+
+#include <board_marvell_def.h>
+#include <gic_common.h>
+#include <interrupt_props.h>
+#include <mvebu_def.h>
+#ifndef __ASSEMBLY__
+#include <stdio.h>
+#endif /* __ASSEMBLY__ */
+
+/*
+ * Most platform porting definitions provided by included headers
+ */
+
+/*
+ * DRAM Memory layout:
+ * +-----------------------+
+ * : :
+ * : Linux :
+ * 0x04X00000-->+-----------------------+
+ * | BL3-3(u-boot) |>>}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+ * |-----------------------| } |
+ * | BL3-[0,1, 2] | }---------------------------------> |
+ * |-----------------------| } || |
+ * | BL2 | }->FIP (loaded by || |
+ * |-----------------------| } BootROM to DRAM) || |
+ * | FIP_TOC | } || |
+ * 0x04120000-->|-----------------------| || |
+ * | BL1 (RO) | || |
+ * 0x04100000-->+-----------------------+ || |
+ * : : || |
+ * : Trusted SRAM section : \/ |
+ * 0x04040000-->+-----------------------+ Replaced by BL2 +----------------+ |
+ * | BL1 (RW) | <<<<<<<<<<<<<<<< | BL3-1 NOBITS | |
+ * 0x04037000-->|-----------------------| <<<<<<<<<<<<<<<< |----------------| |
+ * | | <<<<<<<<<<<<<<<< | BL3-1 PROGBITS | |
+ * 0x04023000-->|-----------------------| +----------------+ |
+ * | BL2 | |
+ * |-----------------------| |
+ * | | |
+ * 0x04001000-->|-----------------------| |
+ * | Shared | |
+ * 0x04000000-->+-----------------------+ |
+ * : : |
+ * : Linux : |
+ * : : |
+ * |-----------------------| |
+ * | | U-Boot(BL3-3) Loaded by BL2 |
+ * | U-Boot | <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+ * 0x00000000-->+-----------------------+
+ *
+ * Trusted SRAM section 0x4000000..0x4200000:
+ * ----------------------------------------
+ * SRAM_BASE = 0x4001000
+ * BL2_BASE = 0x4006000
+ * BL2_LIMIT = BL31_BASE
+ * BL31_BASE = 0x4023000 = (64MB + 256KB - 0x1D000)
+ * BL31_PROGBITS_LIMIT = BL1_RW_BASE
+ * BL1_RW_BASE = 0x4037000 = (64MB + 256KB - 0x9000)
+ * BL1_RW_LIMIT = BL31_LIMIT = 0x4040000
+ *
+ *
+ * PLAT_MARVELL_FIP_BASE = 0x4120000
+ */
+
+/*
+ * Since BL33 is loaded by BL2 (and validated by BL31) to DRAM offset 0,
+ * it is allowed to load/copy images to 'NULL' pointers
+ */
+#if defined(IMAGE_BL2) || defined(IMAGE_BL31)
+#define PLAT_ALLOW_ZERO_ADDR_COPY
+#endif
+
+#define PLAT_MARVELL_SRAM_BASE 0xFFE1C048
+#define PLAT_MARVELL_SRAM_END 0xFFE78000
+
+#define PLAT_MARVELL_ATF_BASE 0x4000000
+#define PLAT_MARVELL_ATF_LOAD_ADDR (PLAT_MARVELL_ATF_BASE + \
+ 0x100000)
+
+#define PLAT_MARVELL_FIP_BASE (PLAT_MARVELL_ATF_LOAD_ADDR + \
+ 0x20000)
+#define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000
+
+#define PLAT_MARVELL_NORTHB_COUNT 1
+
+#define PLAT_MARVELL_CLUSTER_COUNT 2
+#define PLAT_MARVELL_CLUSTER_CORE_COUNT 2
+
+#define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \
+ PLAT_MARVELL_CLUSTER_CORE_COUNT)
+
+/* DRAM[2MB..66MB] is used as Trusted ROM */
+#define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR
+/* 64 MB TODO: reduce this to minimum needed according to fip image size */
+#define PLAT_MARVELL_TRUSTED_ROM_SIZE 0x04000000
+/* Reserve 16M for SCP (Secure PayLoad) Trusted DRAM */
+#define PLAT_MARVELL_TRUSTED_DRAM_BASE 0x04400000
+#define PLAT_MARVELL_TRUSTED_DRAM_SIZE 0x01000000 /* 16 MB */
+
+/*
+ * PLAT_ARM_MAX_BL1_RW_SIZE is calculated using the current BL1 RW debug size
+ * plus a little space for growth.
+ */
+#define PLAT_MARVELL_MAX_BL1_RW_SIZE 0xA000
+
+/*
+ * PLAT_ARM_MAX_BL2_SIZE is calculated using the current BL2 debug size plus a
+ * little space for growth.
+ */
+#define PLAT_MARVELL_MAX_BL2_SIZE 0xF000
+
+/*
+ * PLAT_ARM_MAX_BL31_SIZE is calculated using the current BL31 debug size plus a
+ * little space for growth.
+ */
+#define PLAT_MARVEL_MAX_BL31_SIZE 0x5D000
+
+#define PLAT_MARVELL_CPU_ENTRY_ADDR BL1_RO_BASE
+
+/* GIC related definitions */
+#define PLAT_MARVELL_GICD_BASE (MVEBU_REGS_BASE + MVEBU_GICD_BASE)
+#define PLAT_MARVELL_GICC_BASE (MVEBU_REGS_BASE + MVEBU_GICC_BASE)
+
+#define PLAT_MARVELL_G0_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_MARVELL_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(MARVELL_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
+ GIC_INTR_CFG_LEVEL)
+
+#define PLAT_MARVELL_SHARED_RAM_CACHED 1
+
+/*
+ * Load address of BL3-3 for this platform port
+ */
+#define PLAT_MARVELL_NS_IMAGE_OFFSET 0x0
+
+/* System Reference Clock*/
+#define PLAT_REF_CLK_IN_HZ COUNTER_FREQUENCY
+
+/*
+ * PL011 related constants
+ */
+#define PLAT_MARVELL_BOOT_UART_BASE (MVEBU_REGS_BASE + 0x512000)
+#define PLAT_MARVELL_BOOT_UART_CLK_IN_HZ 200000000
+
+#define PLAT_MARVELL_CRASH_UART_BASE PLAT_MARVELL_BOOT_UART_BASE
+#define PLAT_MARVELL_CRASH_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+
+#define PLAT_MARVELL_BL31_RUN_UART_BASE PLAT_MARVELL_BOOT_UART_BASE
+#define PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ
+
+/* Recovery image enable */
+#define PLAT_RECOVERY_IMAGE_ENABLE 0
+
+/* Required platform porting definitions */
+#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
+
+/* System timer related constants */
+#define PLAT_MARVELL_NSTIMER_FRAME_ID 1
+
+/* Mailbox base address (note the lower memory space
+ * is reserved for BLE data)
+ */
+#define PLAT_MARVELL_MAILBOX_BASE (MARVELL_TRUSTED_SRAM_BASE \
+ + 0x400)
+#define PLAT_MARVELL_MAILBOX_SIZE 0x100
+#define PLAT_MARVELL_MAILBOX_MAGIC_NUM 0x6D72766C /* mrvl */
+
+/* Securities */
+#define IRQ_SEC_OS_TICK_INT MARVELL_IRQ_SEC_PHY_TIMER
+
+#define TRUSTED_DRAM_BASE PLAT_MARVELL_TRUSTED_DRAM_BASE
+#define TRUSTED_DRAM_SIZE PLAT_MARVELL_TRUSTED_DRAM_SIZE
+
+#define BL32_BASE TRUSTED_DRAM_BASE
+
+#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/marvell/a8k/common/mss/mss_a8k.mk b/plat/marvell/a8k/common/mss/mss_a8k.mk
new file mode 100644
index 000000000..58f23d8dd
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_a8k.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+PLAT_MARVELL := plat/marvell
+A8K_MSS_SOURCE := $(PLAT_MARVELL)/a8k/common/mss
+
+BL2_SOURCES += $(A8K_MSS_SOURCE)/mss_bl2_setup.c
+
+BL31_SOURCES += $(A8K_MSS_SOURCE)/mss_pm_ipc.c
+
+PLAT_INCLUDES += -I$(A8K_MSS_SOURCE)
+
+ifneq (${SCP_BL2},)
+# This define is used to inidcate the SCP image is present
+$(eval $(call add_define,SCP_IMAGE))
+endif
diff --git a/plat/marvell/a8k/common/mss/mss_bl2_setup.c b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
new file mode 100644
index 000000000..21541855b
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_bl2_setup.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+#include <bl_common.h>
+#include <ccu.h>
+#include <cp110_setup.h>
+#include <debug.h>
+#include <marvell_plat_priv.h> /* timer functionality */
+#include <mmio.h>
+#include <platform_def.h>
+
+#include "mss_scp_bootloader.h"
+
+/* IO windows configuration */
+#define IOW_GCR_OFFSET (0x70)
+
+/* MSS windows configuration */
+#define MSS_AEBR(base) (base + 0x160)
+#define MSS_AIBR(base) (base + 0x164)
+#define MSS_AEBR_MASK 0xFFF
+#define MSS_AIBR_MASK 0xFFF
+
+#define MSS_EXTERNAL_SPACE 0x50000000
+#define MSS_EXTERNAL_ACCESS_BIT 28
+#define MSS_EXTERNAL_ADDR_MASK 0xfffffff
+#define MSS_INTERNAL_ACCESS_BIT 28
+
+struct addr_map_win ccu_mem_map[] = {
+ {MVEBU_CP_REGS_BASE(0), 0x4000000, IO_0_TID}
+};
+
+/* Since the scp_bl2 image can contain firmware for cp1 and cp0 coprocessors,
+ * the access to cp0 and cp1 need to be provided. More precisely it is
+ * required to:
+ * - get the information about device id which is stored in CP0 registers
+ * (to distinguish between cases where we have cp0 and cp1 or standalone cp0)
+ * - get the access to cp which is needed for loading fw for cp0/cp1
+ * coprocessors
+ * This function configures ccu windows accordingly.
+ *
+ * Note: there is no need to restore previous ccu configuration, since in next
+ * phase (BL31) the init_ccu will be called (via apn806_init/
+ * bl31_plat_arch_setu) and therefore the ccu configuration will be overwritten.
+ */
+static int bl2_plat_mmap_init(void)
+{
+ int cfg_num, win_id, cfg_idx;
+
+ cfg_num = ARRAY_SIZE(ccu_mem_map);
+
+ /* CCU window-0 should not be counted - it's already used */
+ if (cfg_num > (MVEBU_CCU_MAX_WINS - 1)) {
+ ERROR("BL2: %s: trying to open too many windows\n", __func__);
+ return -1;
+ }
+
+ /* Enable required CCU windows
+ * Do not touch CCU window 0,
+ * it's used for the internal registers access
+ */
+ for (cfg_idx = 0, win_id = 1; cfg_idx < cfg_num; cfg_idx++, win_id++) {
+ /* Enable required CCU windows */
+ ccu_win_check(&ccu_mem_map[cfg_idx]);
+ ccu_enable_win(MVEBU_AP0, &ccu_mem_map[cfg_idx], win_id);
+ }
+
+ /* Set the default target id to PIDI */
+ mmio_write_32(MVEBU_IO_WIN_BASE(MVEBU_AP0) + IOW_GCR_OFFSET, PIDI_TID);
+
+ return 0;
+}
+
+/*****************************************************************************
+ * Transfer SCP_BL2 from Trusted RAM using the SCP Download protocol.
+ * Return 0 on success, -1 otherwise.
+ *****************************************************************************
+ */
+int bl2_plat_handle_scp_bl2(image_info_t *scp_bl2_image_info)
+{
+ int ret;
+
+ INFO("BL2: Initiating SCP_BL2 transfer to SCP\n");
+
+ /* initialize time (for delay functionality) */
+ plat_delay_timer_init();
+
+ ret = bl2_plat_mmap_init();
+ if (ret != 0)
+ return ret;
+
+ ret = scp_bootloader_transfer((void *)scp_bl2_image_info->image_base,
+ scp_bl2_image_info->image_size);
+
+ if (ret == 0)
+ INFO("BL2: SCP_BL2 transferred to SCP\n");
+ else
+ ERROR("BL2: SCP_BL2 transfer failure\n");
+
+ return ret;
+}
+
+uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx)
+{
+ return MVEBU_CP_REGS_BASE(cp_idx) + 0x280000;
+}
+
+uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx)
+{
+ return MVEBU_REGS_BASE + 0x580000;
+}
+
+uint32_t bl2_plat_get_cp_count(int ap_idx)
+{
+ uint32_t revision = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
+ /* A8040: two CPs.
+ * A7040: one CP.
+ */
+ if (revision == MVEBU_80X0_DEV_ID ||
+ revision == MVEBU_80X0_CP115_DEV_ID)
+ return 2;
+ else
+ return 1;
+}
+
+uint32_t bl2_plat_get_ap_count(void)
+{
+ /* A8040 and A7040 have only one AP */
+ return 1;
+}
+
+void bl2_plat_configure_mss_windows(uintptr_t mss_regs)
+{
+ /* set AXI External and Internal Address Bus extension */
+ mmio_write_32(MSS_AEBR(mss_regs),
+ ((0x0 >> MSS_EXTERNAL_ACCESS_BIT) & MSS_AEBR_MASK));
+ mmio_write_32(MSS_AIBR(mss_regs),
+ ((mss_regs >> MSS_INTERNAL_ACCESS_BIT) & MSS_AIBR_MASK));
+}
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.c b/plat/marvell/a8k/common/mss/mss_pm_ipc.c
new file mode 100644
index 000000000..6ff4abcca
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_pm_ipc.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <debug.h>
+#include <mmio.h>
+#include <psci.h>
+#include <string.h>
+
+#include <mss_pm_ipc.h>
+
+/*
+ * SISR is 32 bit interrupt register representing 32 interrupts
+ *
+ * +======+=============+=============+
+ * + Bits + 31 + 30 - 00 +
+ * +======+=============+=============+
+ * + Desc + MSS Msg Int + Reserved +
+ * +======+=============+=============+
+ */
+#define MSS_SISR (MVEBU_REGS_BASE + 0x5800D0)
+#define MSS_SISTR (MVEBU_REGS_BASE + 0x5800D8)
+
+#define MSS_MSG_INT_MASK (0x80000000)
+#define MSS_TIMER_BASE (MVEBU_REGS_BASE_MASK + 0x580110)
+#define MSS_TRIGGER_TIMEOUT (1000)
+
+/*****************************************************************************
+ * mss_pm_ipc_msg_send
+ *
+ * DESCRIPTION: create and transmit IPC message
+ *****************************************************************************
+ */
+int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id,
+ const psci_power_state_t *target_state)
+{
+ /* Transmit IPC message */
+#ifndef DISABLE_CLUSTER_LEVEL
+ mv_pm_ipc_msg_tx(channel_id, msg_id,
+ (unsigned int)target_state->pwr_domain_state[
+ MPIDR_AFFLVL1]);
+#else
+ mv_pm_ipc_msg_tx(channel_id, msg_id, 0);
+#endif
+
+ return 0;
+}
+
+/*****************************************************************************
+ * mss_pm_ipc_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC message interrupt to MSS
+ *****************************************************************************
+ */
+int mss_pm_ipc_msg_trigger(void)
+{
+ unsigned int timeout;
+ unsigned int t_end;
+ unsigned int t_start = mmio_read_32(MSS_TIMER_BASE);
+
+ mmio_write_32(MSS_SISR, MSS_MSG_INT_MASK);
+
+ do {
+ /* wait while SCP process incoming interrupt */
+ if (mmio_read_32(MSS_SISTR) != MSS_MSG_INT_MASK)
+ break;
+
+ /* check timeout */
+ t_end = mmio_read_32(MSS_TIMER_BASE);
+
+ timeout = ((t_start > t_end) ?
+ (t_start - t_end) : (t_end - t_start));
+ if (timeout > MSS_TRIGGER_TIMEOUT) {
+ ERROR("PM MSG Trigger Timeout\n");
+ break;
+ }
+
+ } while (1);
+
+ return 0;
+}
diff --git a/plat/marvell/a8k/common/mss/mss_pm_ipc.h b/plat/marvell/a8k/common/mss/mss_pm_ipc.h
new file mode 100644
index 000000000..0f6945707
--- /dev/null
+++ b/plat/marvell/a8k/common/mss/mss_pm_ipc.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MSS_PM_IPC_H
+#define __MSS_PM_IPC_H
+
+#include <mss_ipc_drv.h>
+
+/* Currently MSS does not support Cluster level Power Down */
+#define DISABLE_CLUSTER_LEVEL
+
+
+/*****************************************************************************
+ * mss_pm_ipc_msg_send
+ *
+ * DESCRIPTION: create and transmit IPC message
+ *****************************************************************************
+ */
+int mss_pm_ipc_msg_send(unsigned int channel_id, unsigned int msg_id,
+ const psci_power_state_t *target_state);
+
+/*****************************************************************************
+ * mss_pm_ipc_msg_trigger
+ *
+ * DESCRIPTION: Trigger IPC message interrupt to MSS
+ *****************************************************************************
+ */
+int mss_pm_ipc_msg_trigger(void);
+
+
+#endif /* __MSS_PM_IPC_H */
diff --git a/plat/marvell/a8k/common/plat_bl1_setup.c b/plat/marvell/a8k/common/plat_bl1_setup.c
new file mode 100644
index 000000000..5d8510279
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_bl1_setup.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <mmio.h>
+#include <plat_marvell.h>
+
+void marvell_bl1_setup_mpps(void)
+{
+ /* Enable UART MPPs.
+ ** In a normal system, this is done by Bootrom.
+ */
+ mmio_write_32(MVEBU_AP_MPP_REGS(1), 0x3000);
+ mmio_write_32(MVEBU_AP_MPP_REGS(2), 0x3000);
+}
diff --git a/plat/marvell/a8k/common/plat_bl31_setup.c b/plat/marvell/a8k/common/plat_bl31_setup.c
new file mode 100644
index 000000000..6c85fcc37
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_bl31_setup.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+#include <ap_setup.h>
+#include <cp110_setup.h>
+#include <debug.h>
+#include <marvell_plat_priv.h>
+#include <marvell_pm.h>
+#include <mmio.h>
+#include <mci.h>
+#include <plat_marvell.h>
+
+#include <mss_ipc_drv.h>
+#include <mss_mem.h>
+
+/* In Armada-8k family AP806/AP807, CP0 connected to PIDI
+ * and CP1 connected to IHB via MCI #0
+ */
+#define MVEBU_MCI0 0
+
+static _Bool pm_fw_running;
+
+/* Set a weak stub for platforms that don't need to configure GPIO */
+#pragma weak marvell_gpio_config
+int marvell_gpio_config(void)
+{
+ return 0;
+}
+
+static void marvell_bl31_mpp_init(int cp)
+{
+ uint32_t reg;
+
+ /* need to do for CP#0 only */
+ if (cp)
+ return;
+
+
+ /*
+ * Enable CP0 I2C MPPs (MPP: 37-38)
+ * U-Boot rely on proper MPP settings for I2C EEPROM usage
+ * (only for CP0)
+ */
+ reg = mmio_read_32(MVEBU_CP_MPP_REGS(0, 4));
+ mmio_write_32(MVEBU_CP_MPP_REGS(0, 4), reg | 0x2200000);
+}
+
+void marvell_bl31_mss_init(void)
+{
+ struct mss_pm_ctrl_block *mss_pm_crtl =
+ (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE;
+
+ /* Check that the image was loaded successfully */
+ if (mss_pm_crtl->handshake != HOST_ACKNOWLEDGMENT) {
+ NOTICE("MSS PM is not supported in this build\n");
+ return;
+ }
+
+ /* If we got here it means that the PM firmware is running */
+ pm_fw_running = 1;
+
+ INFO("MSS IPC init\n");
+
+ if (mss_pm_crtl->ipc_state == IPC_INITIALIZED)
+ mv_pm_ipc_init(mss_pm_crtl->ipc_base_address | MVEBU_REGS_BASE);
+}
+
+_Bool is_pm_fw_running(void)
+{
+ return pm_fw_running;
+}
+
+/* This function overruns the same function in marvell_bl31_setup.c */
+void bl31_plat_arch_setup(void)
+{
+ int cp;
+ uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
+
+ /* initialize the timer for mdelay/udelay functionality */
+ plat_delay_timer_init();
+
+ /* configure apn806 */
+ ap_init();
+
+ /* In marvell_bl31_plat_arch_setup, el3 mmu is configured.
+ * el3 mmu configuration MUST be called after apn806_init, if not,
+ * this will cause an hang in init_io_win
+ * (after setting the IO windows GCR values).
+ */
+ if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM ||
+ mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE)
+ marvell_bl31_plat_arch_setup();
+
+ for (cp = 0; cp < CP_COUNT; cp++) {
+ /* configure cp110 for CP0*/
+ if (cp == 1)
+ mci_initialize(MVEBU_MCI0);
+
+ /* initialize MCI & CP1 */
+ cp110_init(MVEBU_CP_REGS_BASE(cp),
+ STREAM_ID_BASE + (cp * MAX_STREAM_ID_PER_CP));
+
+ /* Should be called only after setting IOB windows */
+ marvell_bl31_mpp_init(cp);
+ }
+
+ /* initialize IPC between MSS and ATF */
+ if (mailbox[MBOX_IDX_MAGIC] != MVEBU_MAILBOX_MAGIC_NUM ||
+ mailbox[MBOX_IDX_SUSPEND_MAGIC] != MVEBU_MAILBOX_SUSPEND_STATE)
+ marvell_bl31_mss_init();
+
+ /* Configure GPIO */
+ marvell_gpio_config();
+}
diff --git a/plat/marvell/a8k/common/plat_ble_setup.c b/plat/marvell/a8k/common/plat_ble_setup.c
new file mode 100644
index 000000000..0cd62cbdb
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_ble_setup.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+#include <ap_setup.h>
+#include <aro.h>
+#include <ccu.h>
+#include <cp110_setup.h>
+#include <debug.h>
+#include <io_win.h>
+#include <mv_ddr_if.h>
+#include <mvebu_def.h>
+#include <plat_marvell.h>
+
+/* Register for skip image use */
+#define SCRATCH_PAD_REG2 0xF06F00A8
+#define SCRATCH_PAD_SKIP_VAL 0x01
+#define NUM_OF_GPIO_PER_REG 32
+
+#define MMAP_SAVE_AND_CONFIG 0
+#define MMAP_RESTORE_SAVED 1
+
+/* SAR clock settings */
+#define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000)
+#define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\
+ ((r) << 2))
+
+#define SAR_CLOCK_FREQ_MODE_OFFSET (0)
+#define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET)
+#define SAR_PIDI_LOW_SPEED_OFFSET (20)
+#define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET)
+#define SAR_PIDI_LOW_SPEED_SHIFT (15)
+#define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT)
+
+#define FREQ_MODE_AP_SAR_REG_NUM (0)
+#define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \
+ SAR_CLOCK_FREQ_MODE_OFFSET)
+
+#define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130)
+#define AVS_ENABLE_OFFSET (0)
+#define AVS_SOFT_RESET_OFFSET (2)
+#define AVS_LOW_VDD_LIMIT_OFFSET (4)
+#define AVS_HIGH_VDD_LIMIT_OFFSET (12)
+#define AVS_TARGET_DELTA_OFFSET (21)
+#define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET)
+#define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET)
+/* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */
+#define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \
+ (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \
+ (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \
+ (0x1 << AVS_SOFT_RESET_OFFSET) | \
+ (0x1 << AVS_ENABLE_OFFSET))
+/* VDD limit is 1.0V for all A80x0 devices */
+#define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \
+ (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \
+ (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \
+ (0x1 << AVS_SOFT_RESET_OFFSET) | \
+ (0x1 << AVS_ENABLE_OFFSET))
+
+#define AVS_A3900_CLK_VALUE ((0x80 << 24) | \
+ (0x2c2 << 13) | \
+ (0x2c2 << 3) | \
+ (0x1 << AVS_SOFT_RESET_OFFSET) | \
+ (0x1 << AVS_ENABLE_OFFSET))
+
+#define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8)
+#define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6
+#define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS)
+
+/* Notify bootloader on DRAM setup */
+#define AP807_CPU_ARO_0_CTRL_0 (MVEBU_RFU_BASE + 0x82A8)
+#define AP807_CPU_ARO_1_CTRL_0 (MVEBU_RFU_BASE + 0x8D00)
+
+/* 0 - ARO clock is enabled, 1 - ARO clock is disabled */
+#define AP807_CPU_ARO_CLK_EN_OFFSET 0
+#define AP807_CPU_ARO_CLK_EN_MASK (0x1 << AP807_CPU_ARO_CLK_EN_OFFSET)
+
+/* 0 - ARO is the clock source, 1 - PLL is the clock source */
+#define AP807_CPU_ARO_SEL_PLL_OFFSET 5
+#define AP807_CPU_ARO_SEL_PLL_MASK (0x1 << AP807_CPU_ARO_SEL_PLL_OFFSET)
+
+/*
+ * - AVS work points in the LD0 eFuse:
+ * SVC1 work point: LD0[88:81]
+ * SVC2 work point: LD0[96:89]
+ * SVC3 work point: LD0[104:97]
+ * SVC4 work point: LD0[112:105]
+ * - Identification information in the LD-0 eFuse:
+ * DRO: LD0[74:65] - Not used by the SW
+ * Revision: LD0[78:75] - Not used by the SW
+ * Bin: LD0[80:79] - Not used by the SW
+ * SW Revision: LD0[115:113]
+ * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1
+ * resulting in 2 CPUs active only (7020)
+ */
+#define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00)
+/* Bits [94:63] - 32 data bits total */
+#define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8)
+/* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */
+#define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC)
+/* Bits [220:189] - 32 data bits total */
+#define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18)
+/* Offsets for the above 2 fields combined into single 64-bit value [125:63] */
+#define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */
+#define EFUSE_AP_LD0_DRO_MASK 0x3FF
+#define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */
+#define EFUSE_AP_LD0_REVID_MASK 0xF
+#define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */
+#define EFUSE_AP_LD0_BIN_MASK 0x3
+#define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */
+#define EFUSE_AP_LD0_SWREV_MASK 0x7
+
+#define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */
+#define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */
+#define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */
+#define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */
+#define EFUSE_AP_LD0_WP_MASK 0xFF
+
+#define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4
+
+/* Return the AP revision of the chip */
+static unsigned int ble_get_ap_type(void)
+{
+ unsigned int chip_rev_id;
+
+ chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG);
+ chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >>
+ GWD_IIDR2_CHIP_ID_OFFSET);
+
+ return chip_rev_id;
+}
+
+/******************************************************************************
+ * The routine allows to save the CCU and IO windows configuration during DRAM
+ * setup and restore them afterwards before exiting the BLE stage.
+ * Such window configuration is required since not all default settings coming
+ * from the HW and the BootROM allow access to peripherals connected to
+ * all available CPn components.
+ * For instance, when the boot device is located on CP0, the IO window to CP1
+ * is not opened automatically by the HW and if the DRAM SPD is located on CP1
+ * i2c channel, it cannot be read at BLE stage.
+ * Therefore the DRAM init procedure have to provide access to all available
+ * CPn peripherals during the BLE stage by setting the CCU IO window to all
+ * CPnph addresses and by enabling the IO windows accordingly.
+ * Additionally this function configures the CCU GCR to DRAM, which allows
+ * usage or more than 4GB DRAM as it configured by the default CCU DRAM window.
+ *
+ * IN:
+ * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it
+ * MMAP_RESTORE_SAVED - restore saved configuration
+ * OUT:
+ * NONE
+ ****************************************************************************
+ */
+static void ble_plat_mmap_config(int restore)
+{
+ if (restore == MMAP_RESTORE_SAVED) {
+ /* Restore all orig. settings that were modified by BLE stage */
+ ccu_restore_win_all(MVEBU_AP0);
+ /* Restore CCU */
+ iow_restore_win_all(MVEBU_AP0);
+ return;
+ }
+
+ /* Store original values */
+ ccu_save_win_all(MVEBU_AP0);
+ /* Save CCU */
+ iow_save_win_all(MVEBU_AP0);
+
+ init_ccu(MVEBU_AP0);
+ /* The configuration saved, now all the changes can be done */
+ init_io_win(MVEBU_AP0);
+}
+
+/****************************************************************************
+ * Setup Adaptive Voltage Switching - this is required for some platforms
+ ****************************************************************************
+ */
+static void ble_plat_avs_config(void)
+{
+ uint32_t reg_val, device_id;
+
+ /* Check which SoC is running and act accordingly */
+ if (ble_get_ap_type() == CHIP_ID_AP807) {
+ VERBOSE("AVS: Setting AP807 AVS CTRL to 0x%x\n",
+ AVS_A3900_CLK_VALUE);
+ mmio_write_32(AVS_EN_CTRL_REG, AVS_A3900_CLK_VALUE);
+ return;
+ }
+
+ /* Check which SoC is running and act accordingly */
+ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
+ switch (device_id) {
+ case MVEBU_80X0_DEV_ID:
+ case MVEBU_80X0_CP115_DEV_ID:
+ /* Set the new AVS value - fix the default one on A80x0 */
+ mmio_write_32(AVS_EN_CTRL_REG, AVS_A8K_CLK_VALUE);
+ break;
+ case MVEBU_70X0_DEV_ID:
+ case MVEBU_70X0_CP115_DEV_ID:
+ /* Only fix AVS for CPU clocks lower than 1600MHz on A70x0 */
+ reg_val = mmio_read_32(MVEBU_AP_SAR_REG_BASE(
+ FREQ_MODE_AP_SAR_REG_NUM));
+ reg_val &= SAR_CLOCK_FREQ_MODE_MASK;
+ reg_val >>= SAR_CLOCK_FREQ_MODE_OFFSET;
+ if ((reg_val > CPU_1600_DDR_900_RCLK_900_2) &&
+ (reg_val < CPU_DDR_RCLK_INVALID))
+ mmio_write_32(AVS_EN_CTRL_REG, AVS_A7K_LOW_CLK_VALUE);
+ break;
+ default:
+ ERROR("Unsupported Device ID 0x%x\n", device_id);
+ }
+}
+
+/****************************************************************************
+ * SVC flow - v0.10
+ * The feature is intended to configure AVS value according to eFuse values
+ * that are burned individually for each SoC during the test process.
+ * Primary AVS value is stored in HD efuse and processed on power on
+ * by the HW engine
+ * Secondary AVS value is located in LD efuse and contains 4 work points for
+ * various CPU frequencies.
+ * The Secondary AVS value is only taken into account if the SW Revision stored
+ * in the efuse is greater than 0 and the CPU is running in a certain speed.
+ ****************************************************************************
+ */
+static void ble_plat_svc_config(void)
+{
+ uint32_t reg_val, avs_workpoint, freq_pidi_mode;
+ uint64_t efuse;
+ uint32_t device_id, single_cluster;
+ uint8_t svc[4], perr[4], i, sw_ver;
+
+ /* Due to a bug in A3900 device_id skip SVC config
+ * TODO: add SVC config once it is decided for a3900
+ */
+ if (ble_get_ap_type() == CHIP_ID_AP807) {
+ NOTICE("SVC: SVC is not supported on AP807\n");
+ ble_plat_avs_config();
+ return;
+ }
+
+ /* Set access to LD0 */
+ reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG);
+ reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS;
+ mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val);
+
+ /* Obtain the value of LD0[125:63] */
+ efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS);
+ efuse <<= 32;
+ efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS);
+
+ /* SW Revision:
+ * Starting from SW revision 1 the SVC flow is supported.
+ * SW version 0 (efuse not programmed) should follow the
+ * regular AVS update flow.
+ */
+ sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK;
+ if (sw_ver < 1) {
+ NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver);
+ ble_plat_avs_config();
+ return;
+ }
+
+ /* Frequency mode from SAR */
+ freq_pidi_mode = SAR_CLOCK_FREQ_MODE(
+ mmio_read_32(
+ MVEBU_AP_SAR_REG_BASE(
+ FREQ_MODE_AP_SAR_REG_NUM)));
+
+ /* Decode all SVC work points */
+ svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK;
+ svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK;
+ svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK;
+ svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) & EFUSE_AP_LD0_WP_MASK;
+ INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n",
+ svc[0], svc[1], svc[2], svc[3]);
+
+ /* Validate parity of SVC workpoint values */
+ for (i = 0; i < 4; i++) {
+ uint8_t parity, bit;
+
+ perr[i] = 0;
+
+ for (bit = 1, parity = svc[i] & 1; bit < 7; bit++)
+ parity ^= (svc[i] >> bit) & 1;
+
+ /* Starting from SW version 2, the parity check is mandatory */
+ if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1)))
+ perr[i] = 1; /* register the error */
+ }
+
+ single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS);
+ single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1;
+
+ device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0));
+ if (device_id == MVEBU_80X0_DEV_ID ||
+ device_id == MVEBU_80X0_CP115_DEV_ID) {
+ /* A8040/A8020 */
+ NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n",
+ single_cluster == 0 ? "8040" : "8020", freq_pidi_mode);
+ switch (freq_pidi_mode) {
+ case CPU_1800_DDR_1200_RCLK_1200:
+ case CPU_1800_DDR_1050_RCLK_1050:
+ if (perr[1])
+ goto perror;
+ avs_workpoint = svc[1];
+ break;
+ case CPU_1600_DDR_1050_RCLK_1050:
+ case CPU_1600_DDR_900_RCLK_900_2:
+ if (perr[2])
+ goto perror;
+ avs_workpoint = svc[2];
+ break;
+ case CPU_1300_DDR_800_RCLK_800:
+ case CPU_1300_DDR_650_RCLK_650:
+ if (perr[3])
+ goto perror;
+ avs_workpoint = svc[3];
+ break;
+ case CPU_2000_DDR_1200_RCLK_1200:
+ case CPU_2000_DDR_1050_RCLK_1050:
+ default:
+ if (perr[0])
+ goto perror;
+ avs_workpoint = svc[0];
+ break;
+ }
+ } else if (device_id == MVEBU_70X0_DEV_ID ||
+ device_id == MVEBU_70X0_CP115_DEV_ID) {
+ /* A7040/A7020/A6040 */
+ NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n",
+ single_cluster == 0 ? "7040" : "7020", freq_pidi_mode);
+ switch (freq_pidi_mode) {
+ case CPU_1400_DDR_800_RCLK_800:
+ if (single_cluster) {/* 7020 */
+ if (perr[1])
+ goto perror;
+ avs_workpoint = svc[1];
+ } else {
+ if (perr[0])
+ goto perror;
+ avs_workpoint = svc[0];
+ }
+ break;
+ case CPU_1200_DDR_800_RCLK_800:
+ if (single_cluster) {/* 7020 */
+ if (perr[2])
+ goto perror;
+ avs_workpoint = svc[2];
+ } else {
+ if (perr[1])
+ goto perror;
+ avs_workpoint = svc[1];
+ }
+ break;
+ case CPU_800_DDR_800_RCLK_800:
+ case CPU_1000_DDR_800_RCLK_800:
+ if (single_cluster) {/* 7020 */
+ if (perr[3])
+ goto perror;
+ avs_workpoint = svc[3];
+ } else {
+ if (perr[2])
+ goto perror;
+ avs_workpoint = svc[2];
+ }
+ break;
+ case CPU_600_DDR_800_RCLK_800:
+ if (perr[3])
+ goto perror;
+ avs_workpoint = svc[3]; /* Same for 6040 and 7020 */
+ break;
+ case CPU_1600_DDR_800_RCLK_800: /* 7020 only */
+ default:
+ if (single_cluster) {/* 7020 */
+ if (perr[0])
+ goto perror;
+ avs_workpoint = svc[0];
+ } else
+ avs_workpoint = 0;
+ break;
+ }
+ } else {
+ ERROR("SVC: Unsupported Device ID 0x%x\n", device_id);
+ return;
+ }
+
+ /* Set AVS control if needed */
+ if (avs_workpoint == 0) {
+ ERROR("SVC: AVS work point not changed\n");
+ return;
+ }
+
+ /* Remove parity bit */
+ avs_workpoint &= 0x7F;
+
+ reg_val = mmio_read_32(AVS_EN_CTRL_REG);
+ NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n",
+ (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET,
+ avs_workpoint);
+ reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK);
+ reg_val |= 0x1 << AVS_ENABLE_OFFSET;
+ reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET;
+ reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET;
+ mmio_write_32(AVS_EN_CTRL_REG, reg_val);
+ return;
+
+perror:
+ ERROR("Failed SVC WP[%d] parity check!\n", i);
+ ERROR("Ignoring the WP values\n");
+}
+
+#if PLAT_RECOVERY_IMAGE_ENABLE
+static int ble_skip_image_i2c(struct skip_image *skip_im)
+{
+ ERROR("skipping image using i2c is not supported\n");
+ /* not supported */
+ return 0;
+}
+
+static int ble_skip_image_other(struct skip_image *skip_im)
+{
+ ERROR("implementation missing for skip image request\n");
+ /* not supported, make your own implementation */
+ return 0;
+}
+
+static int ble_skip_image_gpio(struct skip_image *skip_im)
+{
+ unsigned int val;
+ unsigned int mpp_address = 0;
+ unsigned int offset = 0;
+
+ switch (skip_im->info.test.cp_ap) {
+ case(CP):
+ mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index,
+ skip_im->info.gpio.num);
+ if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG)
+ offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG;
+ else
+ offset = skip_im->info.gpio.num;
+ break;
+ case(AP):
+ mpp_address = MVEBU_AP_GPIO_DATA_IN;
+ offset = skip_im->info.gpio.num;
+ break;
+ }
+
+ val = mmio_read_32(mpp_address);
+ val &= (1 << offset);
+ if ((!val && skip_im->info.gpio.button_state == HIGH) ||
+ (val && skip_im->info.gpio.button_state == LOW)) {
+ mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL);
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * This function checks if there's a skip image request:
+ * return values:
+ * 1: (true) images request been made.
+ * 0: (false) no image request been made.
+ */
+static int ble_skip_current_image(void)
+{
+ struct skip_image *skip_im;
+
+ /*fetching skip image info*/
+ skip_im = (struct skip_image *)plat_marvell_get_skip_image_data();
+
+ if (skip_im == NULL)
+ return 0;
+
+ /* check if skipping image request has already been made */
+ if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL)
+ return 0;
+
+ switch (skip_im->detection_method) {
+ case GPIO:
+ return ble_skip_image_gpio(skip_im);
+ case I2C:
+ return ble_skip_image_i2c(skip_im);
+ case USER_DEFINED:
+ return ble_skip_image_other(skip_im);
+ }
+
+ return 0;
+}
+#endif
+
+/* Switch to ARO from PLL in ap807 */
+static void aro_to_pll(void)
+{
+ unsigned int reg;
+
+ /* switch from ARO to PLL */
+ reg = mmio_read_32(AP807_CPU_ARO_0_CTRL_0);
+ reg |= AP807_CPU_ARO_SEL_PLL_MASK;
+ mmio_write_32(AP807_CPU_ARO_0_CTRL_0, reg);
+
+ reg = mmio_read_32(AP807_CPU_ARO_1_CTRL_0);
+ reg |= AP807_CPU_ARO_SEL_PLL_MASK;
+ mmio_write_32(AP807_CPU_ARO_1_CTRL_0, reg);
+
+ mdelay(1000);
+
+ /* disable ARO clk driver */
+ reg = mmio_read_32(AP807_CPU_ARO_0_CTRL_0);
+ reg |= (AP807_CPU_ARO_CLK_EN_MASK);
+ mmio_write_32(AP807_CPU_ARO_0_CTRL_0, reg);
+
+ reg = mmio_read_32(AP807_CPU_ARO_1_CTRL_0);
+ reg |= (AP807_CPU_ARO_CLK_EN_MASK);
+ mmio_write_32(AP807_CPU_ARO_1_CTRL_0, reg);
+}
+
+int ble_plat_setup(int *skip)
+{
+ int ret;
+
+ /* Power down unused CPUs */
+ plat_marvell_early_cpu_powerdown();
+
+ /*
+ * Save the current CCU configuration and make required changes:
+ * - Allow access to DRAM larger than 4GB
+ * - Open memory access to all CPn peripherals
+ */
+ ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG);
+
+#if PLAT_RECOVERY_IMAGE_ENABLE
+ /* Check if there's a skip request to bootRom recovery Image */
+ if (ble_skip_current_image()) {
+ /* close memory access to all CPn peripherals. */
+ ble_plat_mmap_config(MMAP_RESTORE_SAVED);
+ *skip = 1;
+ return 0;
+ }
+#endif
+ /* Do required CP-110 setups for BLE stage */
+ cp110_ble_init(MVEBU_CP_REGS_BASE(0));
+
+ /* Setup AVS */
+ ble_plat_svc_config();
+
+ /* work with PLL clock driver in AP807 */
+ if (ble_get_ap_type() == CHIP_ID_AP807)
+ aro_to_pll();
+
+ /* Do required AP setups for BLE stage */
+ ap_ble_init();
+
+ /* Update DRAM topology (scan DIMM SPDs) */
+ plat_marvell_dram_update_topology();
+
+ /* Kick it in */
+ ret = dram_init();
+
+ /* Restore the original CCU configuration before exit from BLE */
+ ble_plat_mmap_config(MMAP_RESTORE_SAVED);
+
+ return ret;
+}
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c
new file mode 100644
index 000000000..c716ee0f7
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_pm.c
@@ -0,0 +1,829 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <a8k_common.h>
+#include <assert.h>
+#include <bakery_lock.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <cache_llc.h>
+#include <console.h>
+#include <gicv2.h>
+#include <marvell_pm.h>
+#include <mmio.h>
+#include <mss_pm_ipc.h>
+#include <plat_marvell.h>
+#include <platform.h>
+#include <plat_pm_trace.h>
+#include <platform.h>
+
+#define MVEBU_PRIVATE_UID_REG 0x30
+#define MVEBU_RFU_GLOBL_SW_RST 0x84
+#define MVEBU_CCU_RVBAR(cpu) (MVEBU_REGS_BASE + 0x640 + (cpu * 4))
+#define MVEBU_CCU_CPU_UN_RESET(cpu) (MVEBU_REGS_BASE + 0x650 + (cpu * 4))
+
+#define MPIDR_CPU_GET(mpidr) ((mpidr) & MPIDR_CPU_MASK)
+#define MPIDR_CLUSTER_GET(mpidr) MPIDR_AFFLVL1_VAL((mpidr))
+
+#define MVEBU_GPIO_MASK(index) (1 << (index % 32))
+#define MVEBU_MPP_MASK(index) (0xF << (4 * (index % 8)))
+#define MVEBU_GPIO_VALUE(index, value) (value << (index % 32))
+
+#define MVEBU_USER_CMD_0_REG (MVEBU_DRAM_MAC_BASE + 0x20)
+#define MVEBU_USER_CMD_CH0_OFFSET 28
+#define MVEBU_USER_CMD_CH0_MASK (1 << MVEBU_USER_CMD_CH0_OFFSET)
+#define MVEBU_USER_CMD_CH0_EN (1 << MVEBU_USER_CMD_CH0_OFFSET)
+#define MVEBU_USER_CMD_CS_OFFSET 24
+#define MVEBU_USER_CMD_CS_MASK (0xF << MVEBU_USER_CMD_CS_OFFSET)
+#define MVEBU_USER_CMD_CS_ALL (0xF << MVEBU_USER_CMD_CS_OFFSET)
+#define MVEBU_USER_CMD_SR_OFFSET 6
+#define MVEBU_USER_CMD_SR_MASK (0x3 << MVEBU_USER_CMD_SR_OFFSET)
+#define MVEBU_USER_CMD_SR_ENTER (0x1 << MVEBU_USER_CMD_SR_OFFSET)
+#define MVEBU_MC_PWR_CTRL_REG (MVEBU_DRAM_MAC_BASE + 0x54)
+#define MVEBU_MC_AC_ON_DLY_OFFSET 8
+#define MVEBU_MC_AC_ON_DLY_MASK (0xF << MVEBU_MC_AC_ON_DLY_OFFSET)
+#define MVEBU_MC_AC_ON_DLY_DEF_VAR (8 << MVEBU_MC_AC_ON_DLY_OFFSET)
+#define MVEBU_MC_AC_OFF_DLY_OFFSET 4
+#define MVEBU_MC_AC_OFF_DLY_MASK (0xF << MVEBU_MC_AC_OFF_DLY_OFFSET)
+#define MVEBU_MC_AC_OFF_DLY_DEF_VAR (0xC << MVEBU_MC_AC_OFF_DLY_OFFSET)
+#define MVEBU_MC_PHY_AUTO_OFF_OFFSET 0
+#define MVEBU_MC_PHY_AUTO_OFF_MASK (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET)
+#define MVEBU_MC_PHY_AUTO_OFF_EN (1 << MVEBU_MC_PHY_AUTO_OFF_OFFSET)
+
+/* this lock synchronize AP multiple cores execution with MSS */
+DEFINE_BAKERY_LOCK(pm_sys_lock);
+
+/* Weak definitions may be overridden in specific board */
+#pragma weak plat_marvell_get_pm_cfg
+
+/* AP806 CPU power down /power up definitions */
+enum CPU_ID {
+ CPU0,
+ CPU1,
+ CPU2,
+ CPU3
+};
+
+#define REG_WR_VALIDATE_TIMEOUT (2000)
+
+#define FEATURE_DISABLE_STATUS_REG \
+ (MVEBU_REGS_BASE + 0x6F8230)
+#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET 4
+#define FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK \
+ (0x1 << FEATURE_DISABLE_STATUS_CPU_CLUSTER_OFFSET)
+
+#ifdef MVEBU_SOC_AP807
+ #define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 1
+ #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 0
+#else
+#define PWRC_CPUN_CR_PWR_DN_RQ_OFFSET 0
+ #define PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET 31
+#endif
+
+#define PWRC_CPUN_CR_REG(cpu_id) \
+ (MVEBU_REGS_BASE + 0x680000 + (cpu_id * 0x10))
+#define PWRC_CPUN_CR_PWR_DN_RQ_MASK \
+ (0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET)
+#define PWRC_CPUN_CR_ISO_ENABLE_OFFSET 16
+#define PWRC_CPUN_CR_ISO_ENABLE_MASK \
+ (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)
+#define PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK \
+ (0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)
+
+#define CCU_B_PRCRN_REG(cpu_id) \
+ (MVEBU_REGS_BASE + 0x1A50 + \
+ ((cpu_id / 2) * (0x400)) + ((cpu_id % 2) * 4))
+#define CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET 0
+#define CCU_B_PRCRN_CPUPORESET_STATIC_MASK \
+ (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)
+
+/* power switch fingers */
+#define AP807_PWRC_LDO_CR0_REG \
+ (MVEBU_REGS_BASE + 0x680000 + 0x100)
+#define AP807_PWRC_LDO_CR0_OFFSET 16
+#define AP807_PWRC_LDO_CR0_MASK \
+ (0xff << AP807_PWRC_LDO_CR0_OFFSET)
+#define AP807_PWRC_LDO_CR0_VAL 0xfd
+
+/*
+ * Power down CPU:
+ * Used to reduce power consumption, and avoid SoC unnecessary temperature rise.
+ */
+static int plat_marvell_cpu_powerdown(int cpu_id)
+{
+ uint32_t reg_val;
+ int exit_loop = REG_WR_VALIDATE_TIMEOUT;
+
+ INFO("Powering down CPU%d\n", cpu_id);
+
+ /* 1. Isolation enable */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val |= 0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 2. Read and check Isolation enabled - verify bit set to 1 */
+ do {
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ exit_loop--;
+ } while (!(reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) &&
+ exit_loop > 0);
+
+ /* 3. Switch off CPU power */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val &= ~PWRC_CPUN_CR_PWR_DN_RQ_MASK;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 4. Read and check Switch Off - verify bit set to 0 */
+ exit_loop = REG_WR_VALIDATE_TIMEOUT;
+ do {
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ exit_loop--;
+ } while (reg_val & PWRC_CPUN_CR_PWR_DN_RQ_MASK && exit_loop > 0);
+
+ if (exit_loop <= 0)
+ goto cpu_poweroff_error;
+
+ /* 5. De-Assert power ready */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val &= ~PWRC_CPUN_CR_LDO_BYPASS_RDY_MASK;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 6. Assert CPU POR reset */
+ reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
+ reg_val &= ~CCU_B_PRCRN_CPUPORESET_STATIC_MASK;
+ mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val);
+
+ /* 7. Read and poll on Validate the CPU is out of reset */
+ exit_loop = REG_WR_VALIDATE_TIMEOUT;
+ do {
+ reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
+ exit_loop--;
+ } while (reg_val & CCU_B_PRCRN_CPUPORESET_STATIC_MASK && exit_loop > 0);
+
+ if (exit_loop <= 0)
+ goto cpu_poweroff_error;
+
+ INFO("Successfully powered down CPU%d\n", cpu_id);
+
+ return 0;
+
+cpu_poweroff_error:
+ ERROR("ERROR: Can't power down CPU%d\n", cpu_id);
+ return -1;
+}
+
+/*
+ * Power down CPUs 1-3 at early boot stage,
+ * to reduce power consumption and SoC temperature.
+ * This is triggered by BLE prior to DDR initialization.
+ *
+ * Note:
+ * All CPUs will be powered up by plat_marvell_cpu_powerup on Linux boot stage,
+ * which is triggered by PSCI ops (pwr_domain_on).
+ */
+int plat_marvell_early_cpu_powerdown(void)
+{
+ uint32_t cpu_cluster_status =
+ mmio_read_32(FEATURE_DISABLE_STATUS_REG) &
+ FEATURE_DISABLE_STATUS_CPU_CLUSTER_MASK;
+ /* if cpu_cluster_status bit is set,
+ * that means we have only single cluster
+ */
+ int cluster_count = cpu_cluster_status ? 1 : 2;
+
+ INFO("Powering off unused CPUs\n");
+
+ /* CPU1 is in AP806 cluster-0, which always exists, so power it down */
+ if (plat_marvell_cpu_powerdown(CPU1) == -1)
+ return -1;
+
+ /*
+ * CPU2-3 are in AP806 2nd cluster (cluster-1),
+ * which doesn't exists in dual-core systems.
+ * so need to check if we have dual-core (single cluster)
+ * or quad-code (2 clusters)
+ */
+ if (cluster_count == 2) {
+ /* CPU2-3 are part of 2nd cluster */
+ if (plat_marvell_cpu_powerdown(CPU2) == -1)
+ return -1;
+ if (plat_marvell_cpu_powerdown(CPU3) == -1)
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Power up CPU - part of Linux boot stage
+ */
+static int plat_marvell_cpu_powerup(u_register_t mpidr)
+{
+ uint32_t reg_val;
+ int cpu_id = MPIDR_CPU_GET(mpidr),
+ cluster = MPIDR_CLUSTER_GET(mpidr);
+ int exit_loop = REG_WR_VALIDATE_TIMEOUT;
+
+ /* calculate absolute CPU ID */
+ cpu_id = cluster * PLAT_MARVELL_CLUSTER_CORE_COUNT + cpu_id;
+
+ INFO("Powering on CPU%d\n", cpu_id);
+
+#ifdef MVEBU_SOC_AP807
+ /* Activate 2 power switch fingers */
+ reg_val = mmio_read_32(AP807_PWRC_LDO_CR0_REG);
+ reg_val &= ~(AP807_PWRC_LDO_CR0_MASK);
+ reg_val |= (AP807_PWRC_LDO_CR0_VAL << AP807_PWRC_LDO_CR0_OFFSET);
+ mmio_write_32(AP807_PWRC_LDO_CR0_REG, reg_val);
+ udelay(100);
+#endif
+
+ /* 1. Switch CPU power ON */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val |= 0x1 << PWRC_CPUN_CR_PWR_DN_RQ_OFFSET;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 2. Wait for CPU on, up to 100 uSec: */
+ udelay(100);
+
+ /* 3. Assert power ready */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val |= 0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 4. Read & Validate power ready
+ * used in order to generate 16 Host CPU cycles
+ */
+ do {
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ exit_loop--;
+ } while (!(reg_val & (0x1 << PWRC_CPUN_CR_LDO_BYPASS_RDY_OFFSET)) &&
+ exit_loop > 0);
+
+ if (exit_loop <= 0)
+ goto cpu_poweron_error;
+
+ /* 5. Isolation disable */
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ reg_val &= ~PWRC_CPUN_CR_ISO_ENABLE_MASK;
+ mmio_write_32(PWRC_CPUN_CR_REG(cpu_id), reg_val);
+
+ /* 6. Read and check Isolation enabled - verify bit set to 1 */
+ exit_loop = REG_WR_VALIDATE_TIMEOUT;
+ do {
+ reg_val = mmio_read_32(PWRC_CPUN_CR_REG(cpu_id));
+ exit_loop--;
+ } while ((reg_val & (0x1 << PWRC_CPUN_CR_ISO_ENABLE_OFFSET)) &&
+ exit_loop > 0);
+
+ /* 7. De Assert CPU POR reset & Core reset */
+ reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
+ reg_val |= 0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET;
+ mmio_write_32(CCU_B_PRCRN_REG(cpu_id), reg_val);
+
+ /* 8. Read & Validate CPU POR reset */
+ exit_loop = REG_WR_VALIDATE_TIMEOUT;
+ do {
+ reg_val = mmio_read_32(CCU_B_PRCRN_REG(cpu_id));
+ exit_loop--;
+ } while (!(reg_val & (0x1 << CCU_B_PRCRN_CPUPORESET_STATIC_OFFSET)) &&
+ exit_loop > 0);
+
+ if (exit_loop <= 0)
+ goto cpu_poweron_error;
+
+ INFO("Successfully powered on CPU%d\n", cpu_id);
+
+ return 0;
+
+cpu_poweron_error:
+ ERROR("ERROR: Can't power up CPU%d\n", cpu_id);
+ return -1;
+}
+
+static int plat_marvell_cpu_on(u_register_t mpidr)
+{
+ int cpu_id;
+ int cluster;
+
+ /* Set barierr */
+ dsbsy();
+
+ /* Get cpu number - use CPU ID */
+ cpu_id = MPIDR_CPU_GET(mpidr);
+
+ /* Get cluster number - use affinity level 1 */
+ cluster = MPIDR_CLUSTER_GET(mpidr);
+
+ /* Set CPU private UID */
+ mmio_write_32(MVEBU_REGS_BASE + MVEBU_PRIVATE_UID_REG, cluster + 0x4);
+
+ /* Set the cpu start address to BL1 entry point (align to 0x10000) */
+ mmio_write_32(MVEBU_CCU_RVBAR(cpu_id),
+ PLAT_MARVELL_CPU_ENTRY_ADDR >> 16);
+
+ /* Get the cpu out of reset */
+ mmio_write_32(MVEBU_CCU_CPU_UN_RESET(cpu_id), 0x10001);
+
+ return 0;
+}
+
+/*****************************************************************************
+ * A8K handler called to check the validity of the power state
+ * parameter.
+ *****************************************************************************
+ */
+static int a8k_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ int pstate = psci_get_pstate_type(power_state);
+ int pwr_lvl = psci_get_pstate_pwrlvl(power_state);
+ int i;
+
+ if (pwr_lvl > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ /* Sanity check the requested state */
+ if (pstate == PSTATE_TYPE_STANDBY) {
+ /*
+ * It's possible to enter standby only on power level 0
+ * Ignore any other power level.
+ */
+ if (pwr_lvl != MARVELL_PWR_LVL0)
+ return PSCI_E_INVALID_PARAMS;
+
+ req_state->pwr_domain_state[MARVELL_PWR_LVL0] =
+ MARVELL_LOCAL_STATE_RET;
+ } else {
+ for (i = MARVELL_PWR_LVL0; i <= pwr_lvl; i++)
+ req_state->pwr_domain_state[i] =
+ MARVELL_LOCAL_STATE_OFF;
+ }
+
+ /*
+ * We expect the 'state id' to be zero.
+ */
+ if (psci_get_pstate_id(power_state))
+ return PSCI_E_INVALID_PARAMS;
+
+ return PSCI_E_SUCCESS;
+}
+
+/*****************************************************************************
+ * A8K handler called when a CPU is about to enter standby.
+ *****************************************************************************
+ */
+static void a8k_cpu_standby(plat_local_state_t cpu_state)
+{
+ ERROR("%s: needs to be implemented\n", __func__);
+ panic();
+}
+
+/*****************************************************************************
+ * A8K handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ *****************************************************************************
+ */
+static int a8k_pwr_domain_on(u_register_t mpidr)
+{
+ /* Power up CPU (CPUs 1-3 are powered off at start of BLE) */
+ plat_marvell_cpu_powerup(mpidr);
+
+ if (is_pm_fw_running()) {
+ unsigned int target =
+ ((mpidr & 0xFF) + (((mpidr >> 8) & 0xFF) * 2));
+
+ /*
+ * pm system synchronization - used to synchronize
+ * multiple core access to MSS
+ */
+ bakery_lock_get(&pm_sys_lock);
+
+ /* send CPU ON IPC Message to MSS */
+ mss_pm_ipc_msg_send(target, PM_IPC_MSG_CPU_ON, 0);
+
+ /* trigger IPC message to MSS */
+ mss_pm_ipc_msg_trigger();
+
+ /* pm system synchronization */
+ bakery_lock_release(&pm_sys_lock);
+
+ /* trace message */
+ PM_TRACE(TRACE_PWR_DOMAIN_ON | target);
+ } else {
+ /* proprietary CPU ON exection flow */
+ plat_marvell_cpu_on(mpidr);
+ }
+
+ return 0;
+}
+
+/*****************************************************************************
+ * A8K handler called to validate the entry point.
+ *****************************************************************************
+ */
+static int a8k_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+ return PSCI_E_SUCCESS;
+}
+
+/*****************************************************************************
+ * A8K handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ *****************************************************************************
+ */
+static void a8k_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ if (is_pm_fw_running()) {
+ unsigned int idx = plat_my_core_pos();
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ gicv2_cpuif_disable();
+
+ /* pm system synchronization - used to synchronize multiple
+ * core access to MSS
+ */
+ bakery_lock_get(&pm_sys_lock);
+
+ /* send CPU OFF IPC Message to MSS */
+ mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_OFF, target_state);
+
+ /* trigger IPC message to MSS */
+ mss_pm_ipc_msg_trigger();
+
+ /* pm system synchronization */
+ bakery_lock_release(&pm_sys_lock);
+
+ /* trace message */
+ PM_TRACE(TRACE_PWR_DOMAIN_OFF);
+ } else {
+ INFO("%s: is not supported without SCP\n", __func__);
+ }
+}
+
+/* Get PM config to power off the SoC */
+void *plat_marvell_get_pm_cfg(void)
+{
+ return NULL;
+}
+
+/*
+ * This function should be called on restore from
+ * "suspend to RAM" state when the execution flow
+ * has to bypass BootROM image to RAM copy and speed up
+ * the system recovery
+ *
+ */
+static void plat_marvell_exit_bootrom(void)
+{
+ marvell_exit_bootrom(PLAT_MARVELL_TRUSTED_ROM_BASE);
+}
+
+/*
+ * Prepare for the power off of the system via GPIO
+ */
+static void plat_marvell_power_off_gpio(struct power_off_method *pm_cfg,
+ register_t *gpio_addr,
+ register_t *gpio_data)
+{
+ unsigned int gpio;
+ unsigned int idx;
+ unsigned int shift;
+ unsigned int reg;
+ unsigned int addr;
+ gpio_info_t *info;
+ unsigned int tog_bits;
+
+ assert((pm_cfg->cfg.gpio.pin_count < PMIC_GPIO_MAX_NUMBER) &&
+ (pm_cfg->cfg.gpio.step_count < PMIC_GPIO_MAX_TOGGLE_STEP));
+
+ /* Prepare GPIOs for PMIC */
+ for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) {
+ info = &pm_cfg->cfg.gpio.info[gpio];
+ /* Set PMIC GPIO to output mode */
+ reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT_EN(
+ info->cp_index, info->gpio_index));
+ mmio_write_32(MVEBU_CP_GPIO_DATA_OUT_EN(
+ info->cp_index, info->gpio_index),
+ reg & ~MVEBU_GPIO_MASK(info->gpio_index));
+
+ /* Set the appropriate MPP to GPIO mode */
+ reg = mmio_read_32(MVEBU_PM_MPP_REGS(info->cp_index,
+ info->gpio_index));
+ mmio_write_32(MVEBU_PM_MPP_REGS(info->cp_index,
+ info->gpio_index),
+ reg & ~MVEBU_MPP_MASK(info->gpio_index));
+ }
+
+ /* Wait for MPP & GPIO pre-configurations done */
+ mdelay(pm_cfg->cfg.gpio.delay_ms);
+
+ /* Toggle the GPIO values, and leave final step to be triggered
+ * after DDR self-refresh is enabled
+ */
+ for (idx = 0; idx < pm_cfg->cfg.gpio.step_count; idx++) {
+ tog_bits = pm_cfg->cfg.gpio.seq[idx];
+
+ /* The GPIOs must be within same GPIO register,
+ * thus could get the original value by first GPIO
+ */
+ info = &pm_cfg->cfg.gpio.info[0];
+ reg = mmio_read_32(MVEBU_CP_GPIO_DATA_OUT(
+ info->cp_index, info->gpio_index));
+ addr = MVEBU_CP_GPIO_DATA_OUT(info->cp_index, info->gpio_index);
+
+ for (gpio = 0; gpio < pm_cfg->cfg.gpio.pin_count; gpio++) {
+ shift = pm_cfg->cfg.gpio.info[gpio].gpio_index % 32;
+ if (GPIO_LOW == (tog_bits & (1 << gpio)))
+ reg &= ~(1 << shift);
+ else
+ reg |= (1 << shift);
+ }
+
+ /* Set the GPIO register, for last step just store
+ * register address and values to system registers
+ */
+ if (idx < pm_cfg->cfg.gpio.step_count - 1) {
+ mmio_write_32(MVEBU_CP_GPIO_DATA_OUT(
+ info->cp_index, info->gpio_index), reg);
+ mdelay(pm_cfg->cfg.gpio.delay_ms);
+ } else {
+ /* Save GPIO register and address values for
+ * finishing the power down operation later
+ */
+ *gpio_addr = addr;
+ *gpio_data = reg;
+ }
+ }
+}
+
+/*
+ * Prepare for the power off of the system
+ */
+static void plat_marvell_power_off_prepare(struct power_off_method *pm_cfg,
+ register_t *addr, register_t *data)
+{
+ switch (pm_cfg->type) {
+ case PMIC_GPIO:
+ plat_marvell_power_off_gpio(pm_cfg, addr, data);
+ break;
+ default:
+ break;
+ }
+}
+
+/*****************************************************************************
+ * A8K handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
+ *****************************************************************************
+ */
+static void a8k_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+ if (is_pm_fw_running()) {
+ unsigned int idx;
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ gicv2_cpuif_disable();
+
+ idx = plat_my_core_pos();
+
+ /* pm system synchronization - used to synchronize multiple
+ * core access to MSS
+ */
+ bakery_lock_get(&pm_sys_lock);
+
+ /* send CPU Suspend IPC Message to MSS */
+ mss_pm_ipc_msg_send(idx, PM_IPC_MSG_CPU_SUSPEND, target_state);
+
+ /* trigger IPC message to MSS */
+ mss_pm_ipc_msg_trigger();
+
+ /* pm system synchronization */
+ bakery_lock_release(&pm_sys_lock);
+
+ /* trace message */
+ PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND);
+ } else {
+ uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
+
+ INFO("Suspending to RAM\n");
+
+ /* Prevent interrupts from spuriously waking up this cpu */
+ gicv2_cpuif_disable();
+
+ mailbox[MBOX_IDX_SUSPEND_MAGIC] = MVEBU_MAILBOX_SUSPEND_STATE;
+ mailbox[MBOX_IDX_ROM_EXIT_ADDR] = (uintptr_t)&plat_marvell_exit_bootrom;
+
+#if PLAT_MARVELL_SHARED_RAM_CACHED
+ flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE +
+ MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t),
+ 2 * sizeof(uintptr_t));
+#endif
+ /* Flush and disable LLC before going off-power */
+ llc_disable(0);
+
+ isb();
+ /*
+ * Do not halt here!
+ * The function must return for allowing the caller function
+ * psci_power_up_finish() to do the proper context saving and
+ * to release the CPU lock.
+ */
+ }
+}
+
+/*****************************************************************************
+ * A8K handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ *****************************************************************************
+ */
+static void a8k_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ /* arch specific configuration */
+ marvell_psci_arch_init(0);
+
+ /* Interrupt initialization */
+ gicv2_pcpu_distif_init();
+ gicv2_cpuif_enable();
+
+ if (is_pm_fw_running()) {
+ /* trace message */
+ PM_TRACE(TRACE_PWR_DOMAIN_ON_FINISH);
+ }
+}
+
+/*****************************************************************************
+ * A8K handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ * TODO: At the moment we reuse the on finisher and reinitialize the secure
+ * context. Need to implement a separate suspend finisher.
+ *****************************************************************************
+ */
+static void a8k_pwr_domain_suspend_finish(
+ const psci_power_state_t *target_state)
+{
+ if (is_pm_fw_running()) {
+ /* arch specific configuration */
+ marvell_psci_arch_init(0);
+
+ /* Interrupt initialization */
+ gicv2_cpuif_enable();
+
+ /* trace message */
+ PM_TRACE(TRACE_PWR_DOMAIN_SUSPEND_FINISH);
+ } else {
+ uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
+
+ /* Only primary CPU requres platform init */
+ if (!plat_my_core_pos()) {
+ /* Initialize the console to provide
+ * early debug support
+ */
+ console_init(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE);
+
+ bl31_plat_arch_setup();
+ marvell_bl31_platform_setup();
+ /*
+ * Remove suspend to RAM marker from the mailbox
+ * for treating a regular reset as a cold boot
+ */
+ mailbox[MBOX_IDX_SUSPEND_MAGIC] = 0;
+ mailbox[MBOX_IDX_ROM_EXIT_ADDR] = 0;
+#if PLAT_MARVELL_SHARED_RAM_CACHED
+ flush_dcache_range(PLAT_MARVELL_MAILBOX_BASE +
+ MBOX_IDX_SUSPEND_MAGIC * sizeof(uintptr_t),
+ 2 * sizeof(uintptr_t));
+#endif
+ }
+ }
+}
+
+/*****************************************************************************
+ * This handler is called by the PSCI implementation during the `SYSTEM_SUSPEND`
+ * call to get the `power_state` parameter. This allows the platform to encode
+ * the appropriate State-ID field within the `power_state` parameter which can
+ * be utilized in `pwr_domain_suspend()` to suspend to system affinity level.
+ *****************************************************************************
+ */
+static void a8k_get_sys_suspend_power_state(psci_power_state_t *req_state)
+{
+ /* lower affinities use PLAT_MAX_OFF_STATE */
+ for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++)
+ req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE;
+}
+
+static void
+__dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
+{
+ struct power_off_method *pm_cfg;
+ unsigned int srcmd;
+ unsigned int sdram_reg;
+ register_t gpio_data = 0, gpio_addr = 0;
+
+ if (is_pm_fw_running()) {
+ psci_power_down_wfi();
+ panic();
+ }
+
+ pm_cfg = (struct power_off_method *)plat_marvell_get_pm_cfg();
+
+ /* Prepare for power off */
+ plat_marvell_power_off_prepare(pm_cfg, &gpio_addr, &gpio_data);
+
+ /* First step to enable DDR self-refresh
+ * to keep the data during suspend
+ */
+ mmio_write_32(MVEBU_MC_PWR_CTRL_REG, 0x8C1);
+
+ /* Save DDR self-refresh second step register
+ * and value to be issued later
+ */
+ sdram_reg = MVEBU_USER_CMD_0_REG;
+ srcmd = mmio_read_32(sdram_reg);
+ srcmd &= ~(MVEBU_USER_CMD_CH0_MASK | MVEBU_USER_CMD_CS_MASK |
+ MVEBU_USER_CMD_SR_MASK);
+ srcmd |= (MVEBU_USER_CMD_CH0_EN | MVEBU_USER_CMD_CS_ALL |
+ MVEBU_USER_CMD_SR_ENTER);
+
+ /*
+ * Wait for DRAM is done using registers access only.
+ * At this stage any access to DRAM (procedure call) will
+ * release it from the self-refresh mode
+ */
+ __asm__ volatile (
+ /* Align to a cache line */
+ " .balign 64\n\t"
+
+ /* Enter self refresh */
+ " str %[srcmd], [%[sdram_reg]]\n\t"
+
+ /*
+ * Wait 100 cycles for DDR to enter self refresh, by
+ * doing 50 times two instructions.
+ */
+ " mov x1, #50\n\t"
+ "1: subs x1, x1, #1\n\t"
+ " bne 1b\n\t"
+
+ /* Issue the command to trigger the SoC power off */
+ " str %[gpio_data], [%[gpio_addr]]\n\t"
+
+ /* Trap the processor */
+ " b .\n\t"
+ : : [srcmd] "r" (srcmd), [sdram_reg] "r" (sdram_reg),
+ [gpio_addr] "r" (gpio_addr), [gpio_data] "r" (gpio_data)
+ : "x1");
+
+ panic();
+}
+
+/*****************************************************************************
+ * A8K handlers to shutdown/reboot the system
+ *****************************************************************************
+ */
+static void __dead2 a8k_system_off(void)
+{
+ ERROR("%s: needs to be implemented\n", __func__);
+ panic();
+}
+
+void plat_marvell_system_reset(void)
+{
+ mmio_write_32(MVEBU_RFU_BASE + MVEBU_RFU_GLOBL_SW_RST, 0x0);
+}
+
+static void __dead2 a8k_system_reset(void)
+{
+ plat_marvell_system_reset();
+
+ /* we shouldn't get to this point */
+ panic();
+}
+
+/*****************************************************************************
+ * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
+ * platform layer will take care of registering the handlers with PSCI.
+ *****************************************************************************
+ */
+const plat_psci_ops_t plat_arm_psci_pm_ops = {
+ .cpu_standby = a8k_cpu_standby,
+ .pwr_domain_on = a8k_pwr_domain_on,
+ .pwr_domain_off = a8k_pwr_domain_off,
+ .pwr_domain_suspend = a8k_pwr_domain_suspend,
+ .pwr_domain_on_finish = a8k_pwr_domain_on_finish,
+ .get_sys_suspend_power_state = a8k_get_sys_suspend_power_state,
+ .pwr_domain_suspend_finish = a8k_pwr_domain_suspend_finish,
+ .pwr_domain_pwr_down_wfi = a8k_pwr_domain_pwr_down_wfi,
+ .system_off = a8k_system_off,
+ .system_reset = a8k_system_reset,
+ .validate_power_state = a8k_validate_power_state,
+ .validate_ns_entrypoint = a8k_validate_ns_entrypoint
+};
diff --git a/plat/marvell/a8k/common/plat_pm_trace.c b/plat/marvell/a8k/common/plat_pm_trace.c
new file mode 100644
index 000000000..683e56f6a
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_pm_trace.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <mmio.h>
+#include <mss_mem.h>
+#include <platform.h>
+#include <plat_pm_trace.h>
+
+#ifdef PM_TRACE_ENABLE
+
+/* core trace APIs */
+core_trace_func funcTbl[PLATFORM_CORE_COUNT] = {
+ pm_core_0_trace,
+ pm_core_1_trace,
+ pm_core_2_trace,
+ pm_core_3_trace};
+
+/*****************************************************************************
+ * pm_core0_trace
+ * pm_core1_trace
+ * pm_core2_trace
+ * pm_core_3trace
+ *
+ * This functions set trace info into core cyclic trace queue in MSS SRAM
+ * memory space
+ *****************************************************************************
+ */
+void pm_core_0_trace(unsigned int trace)
+{
+ unsigned int current_position_core_0 =
+ mmio_read_32(AP_MSS_ATF_CORE_0_CTRL_BASE);
+ mmio_write_32((AP_MSS_ATF_CORE_0_INFO_BASE +
+ (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ mmio_read_32(AP_MSS_TIMER_BASE));
+ mmio_write_32((AP_MSS_ATF_CORE_0_INFO_TRACE +
+ (current_position_core_0 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ trace);
+ mmio_write_32(AP_MSS_ATF_CORE_0_CTRL_BASE,
+ ((current_position_core_0 + 1) &
+ AP_MSS_ATF_TRACE_SIZE_MASK));
+}
+
+void pm_core_1_trace(unsigned int trace)
+{
+ unsigned int current_position_core_1 =
+ mmio_read_32(AP_MSS_ATF_CORE_1_CTRL_BASE);
+ mmio_write_32((AP_MSS_ATF_CORE_1_INFO_BASE +
+ (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ mmio_read_32(AP_MSS_TIMER_BASE));
+ mmio_write_32((AP_MSS_ATF_CORE_1_INFO_TRACE +
+ (current_position_core_1 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ trace);
+ mmio_write_32(AP_MSS_ATF_CORE_1_CTRL_BASE,
+ ((current_position_core_1 + 1) &
+ AP_MSS_ATF_TRACE_SIZE_MASK));
+}
+
+void pm_core_2_trace(unsigned int trace)
+{
+ unsigned int current_position_core_2 =
+ mmio_read_32(AP_MSS_ATF_CORE_2_CTRL_BASE);
+ mmio_write_32((AP_MSS_ATF_CORE_2_INFO_BASE +
+ (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ mmio_read_32(AP_MSS_TIMER_BASE));
+ mmio_write_32((AP_MSS_ATF_CORE_2_INFO_TRACE +
+ (current_position_core_2 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ trace);
+ mmio_write_32(AP_MSS_ATF_CORE_2_CTRL_BASE,
+ ((current_position_core_2 + 1) &
+ AP_MSS_ATF_TRACE_SIZE_MASK));
+}
+
+void pm_core_3_trace(unsigned int trace)
+{
+ unsigned int current_position_core_3 =
+ mmio_read_32(AP_MSS_ATF_CORE_3_CTRL_BASE);
+ mmio_write_32((AP_MSS_ATF_CORE_3_INFO_BASE +
+ (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ mmio_read_32(AP_MSS_TIMER_BASE));
+ mmio_write_32((AP_MSS_ATF_CORE_3_INFO_TRACE +
+ (current_position_core_3 * AP_MSS_ATF_CORE_ENTRY_SIZE)),
+ trace);
+ mmio_write_32(AP_MSS_ATF_CORE_3_CTRL_BASE,
+ ((current_position_core_3 + 1) &
+ AP_MSS_ATF_TRACE_SIZE_MASK));
+}
+#endif /* PM_TRACE_ENABLE */
diff --git a/plat/marvell/a8k/common/plat_thermal.c b/plat/marvell/a8k/common/plat_thermal.c
new file mode 100644
index 000000000..02fe82097
--- /dev/null
+++ b/plat/marvell/a8k/common/plat_thermal.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <debug.h>
+#include <delay_timer.h>
+#include <mmio.h>
+#include <mvebu_def.h>
+#include <thermal.h>
+
+#define THERMAL_TIMEOUT 1200
+
+#define THERMAL_SEN_CTRL_LSB_STRT_OFFSET 0
+#define THERMAL_SEN_CTRL_LSB_STRT_MASK \
+ (0x1 << THERMAL_SEN_CTRL_LSB_STRT_OFFSET)
+#define THERMAL_SEN_CTRL_LSB_RST_OFFSET 1
+#define THERMAL_SEN_CTRL_LSB_RST_MASK \
+ (0x1 << THERMAL_SEN_CTRL_LSB_RST_OFFSET)
+#define THERMAL_SEN_CTRL_LSB_EN_OFFSET 2
+#define THERMAL_SEN_CTRL_LSB_EN_MASK \
+ (0x1 << THERMAL_SEN_CTRL_LSB_EN_OFFSET)
+
+#define THERMAL_SEN_CTRL_STATS_VALID_OFFSET 16
+#define THERMAL_SEN_CTRL_STATS_VALID_MASK \
+ (0x1 << THERMAL_SEN_CTRL_STATS_VALID_OFFSET)
+#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET 0
+#define THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK \
+ (0x3FF << THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET)
+
+#define THERMAL_SEN_OUTPUT_MSB 512
+#define THERMAL_SEN_OUTPUT_COMP 1024
+
+struct tsen_regs {
+ uint32_t ext_tsen_ctrl_lsb;
+ uint32_t ext_tsen_ctrl_msb;
+ uint32_t ext_tsen_status;
+};
+
+static int ext_tsen_probe(struct tsen_config *tsen_cfg)
+{
+ uint32_t reg, timeout = 0;
+ struct tsen_regs *base;
+
+ if (tsen_cfg == NULL && tsen_cfg->regs_base == NULL) {
+ ERROR("initial thermal sensor configuration is missing\n");
+ return -1;
+ }
+ base = (struct tsen_regs *)tsen_cfg->regs_base;
+
+ INFO("initializing thermal sensor\n");
+
+ /* initialize thermal sensor hardware reset once */
+ reg = mmio_read_32((uintptr_t)&base->ext_tsen_ctrl_lsb);
+ reg &= ~THERMAL_SEN_CTRL_LSB_RST_OFFSET; /* de-assert TSEN_RESET */
+ reg |= THERMAL_SEN_CTRL_LSB_EN_MASK; /* set TSEN_EN to 1 */
+ reg |= THERMAL_SEN_CTRL_LSB_STRT_MASK; /* set TSEN_START to 1 */
+ mmio_write_32((uintptr_t)&base->ext_tsen_ctrl_lsb, reg);
+
+ reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+ while ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0 &&
+ timeout < THERMAL_TIMEOUT) {
+ udelay(100);
+ reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+ timeout++;
+ }
+
+ if ((reg & THERMAL_SEN_CTRL_STATS_VALID_MASK) == 0) {
+ ERROR("thermal sensor is not ready\n");
+ return -1;
+ }
+
+ tsen_cfg->tsen_ready = 1;
+
+ VERBOSE("thermal sensor was initialized\n");
+
+ return 0;
+}
+
+static int ext_tsen_read(struct tsen_config *tsen_cfg, int *temp)
+{
+ uint32_t reg;
+ struct tsen_regs *base;
+
+ if (tsen_cfg == NULL && !tsen_cfg->tsen_ready) {
+ ERROR("thermal sensor was not initialized\n");
+ return -1;
+ }
+ base = (struct tsen_regs *)tsen_cfg->regs_base;
+
+ reg = mmio_read_32((uintptr_t)&base->ext_tsen_status);
+ reg = ((reg & THERMAL_SEN_CTRL_STATS_TEMP_OUT_MASK) >>
+ THERMAL_SEN_CTRL_STATS_TEMP_OUT_OFFSET);
+
+ /*
+ * TSEN output format is signed as a 2s complement number
+ * ranging from-512 to +511. when MSB is set, need to
+ * calculate the complement number
+ */
+ if (reg >= THERMAL_SEN_OUTPUT_MSB)
+ reg -= THERMAL_SEN_OUTPUT_COMP;
+
+ if (tsen_cfg->tsen_divisor == 0) {
+ ERROR("thermal sensor divisor cannot be zero\n");
+ return -1;
+ }
+
+ *temp = ((tsen_cfg->tsen_gain * ((int)reg)) +
+ tsen_cfg->tsen_offset) / tsen_cfg->tsen_divisor;
+
+ return 0;
+}
+
+static struct tsen_config tsen_cfg = {
+ .tsen_offset = 153400,
+ .tsen_gain = 425,
+ .tsen_divisor = 1000,
+ .tsen_ready = 0,
+ .regs_base = (void *)MVEBU_AP_EXT_TSEN_BASE,
+ .ptr_tsen_probe = ext_tsen_probe,
+ .ptr_tsen_read = ext_tsen_read
+};
+
+struct tsen_config *marvell_thermal_config_get(void)
+{
+ return &tsen_cfg;
+}
diff --git a/plat/marvell/common/aarch64/marvell_common.c b/plat/marvell/common/aarch64/marvell_common.c
new file mode 100644
index 000000000..abc501a90
--- /dev/null
+++ b/plat/marvell/common/aarch64/marvell_common.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <plat_marvell.h>
+#include <platform_def.h>
+#include <xlat_tables.h>
+
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak plat_get_ns_image_entrypoint
+#pragma weak plat_marvell_get_mmap
+
+/*
+ * Set up the page tables for the generic and platform-specific memory regions.
+ * The extents of the generic memory regions are specified by the function
+ * arguments and consist of:
+ * - Trusted SRAM seen by the BL image;
+ * - Code section;
+ * - Read-only data section;
+ * - Coherent memory region, if applicable.
+ */
+void marvell_setup_page_tables(uintptr_t total_base,
+ size_t total_size,
+ uintptr_t code_start,
+ uintptr_t code_limit,
+ uintptr_t rodata_start,
+ uintptr_t rodata_limit
+#if USE_COHERENT_MEM
+ ,
+ uintptr_t coh_start,
+ uintptr_t coh_limit
+#endif
+ )
+{
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+ (void *) total_base, (void *) (total_base + total_size));
+ mmap_add_region(total_base, total_base,
+ total_size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+
+ /* Re-map the code section */
+ VERBOSE("Code region: %p - %p\n",
+ (void *) code_start, (void *) code_limit);
+ mmap_add_region(code_start, code_start,
+ code_limit - code_start,
+ MT_CODE | MT_SECURE);
+
+ /* Re-map the read-only data section */
+ VERBOSE("Read-only data region: %p - %p\n",
+ (void *) rodata_start, (void *) rodata_limit);
+ mmap_add_region(rodata_start, rodata_start,
+ rodata_limit - rodata_start,
+ MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+ /* Re-map the coherent memory region */
+ VERBOSE("Coherent region: %p - %p\n",
+ (void *) coh_start, (void *) coh_limit);
+ mmap_add_region(coh_start, coh_start,
+ coh_limit - coh_start,
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+ /* Now (re-)map the platform-specific memory regions */
+ mmap_add(plat_marvell_get_mmap());
+
+ /* Create the page tables to reflect the above mappings */
+ init_xlat_tables();
+}
+
+unsigned long plat_get_ns_image_entrypoint(void)
+{
+ return PLAT_MARVELL_NS_IMAGE_OFFSET;
+}
+
+/*****************************************************************************
+ * Gets SPSR for BL32 entry
+ *****************************************************************************
+ */
+uint32_t marvell_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0;
+}
+
+/*****************************************************************************
+ * Gets SPSR for BL33 entry
+ *****************************************************************************
+ */
+uint32_t marvell_get_spsr_for_bl33_entry(void)
+{
+ unsigned long el_status;
+ unsigned int mode;
+ uint32_t spsr;
+
+ /* Figure out what mode we enter the non-secure world in */
+ el_status = read_id_aa64pfr0_el1() >> ID_AA64PFR0_EL2_SHIFT;
+ el_status &= ID_AA64PFR0_ELX_MASK;
+
+ mode = (el_status) ? MODE_EL2 : MODE_EL1;
+
+ /*
+ * TODO: Consider the possibility of specifying the SPSR in
+ * the FIP ToC and allowing the platform to have a say as
+ * well.
+ */
+ spsr = SPSR_64(mode, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+ return spsr;
+}
+
+/*****************************************************************************
+ * Returns ARM platform specific memory map regions.
+ *****************************************************************************
+ */
+const mmap_region_t *plat_marvell_get_mmap(void)
+{
+ return plat_marvell_mmap;
+}
+
diff --git a/plat/marvell/common/aarch64/marvell_helpers.S b/plat/marvell/common/aarch64/marvell_helpers.S
new file mode 100644
index 000000000..a3dc917c6
--- /dev/null
+++ b/plat/marvell/common/aarch64/marvell_helpers.S
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <asm_macros.S>
+#include <cortex_a72.h>
+#include <marvell_def.h>
+#include <platform_def.h>
+#ifndef PLAT_a3700
+#include <ccu.h>
+#include <cache_llc.h>
+#endif
+
+ .weak plat_marvell_calc_core_pos
+ .weak plat_my_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_putc
+ .globl platform_mem_init
+ .globl disable_mmu_dcache
+ .globl invalidate_tlb_all
+ .globl platform_unmap_sram
+ .globl disable_sram
+ .globl disable_icache
+ .globl invalidate_icache_all
+ .globl marvell_exit_bootrom
+ .globl ca72_l2_enable_unique_clean
+
+ /* -----------------------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * This function uses the plat_marvell_calc_core_pos()
+ * definition to get the index of the calling CPU.
+ * -----------------------------------------------------
+ */
+func plat_my_core_pos
+ mrs x0, mpidr_el1
+ b plat_marvell_calc_core_pos
+endfunc plat_my_core_pos
+
+ /* -----------------------------------------------------
+ * unsigned int plat_marvell_calc_core_pos(uint64_t mpidr)
+ * Helper function to calculate the core position.
+ * With this function: CorePos = (ClusterId * 2) +
+ * CoreId
+ * -----------------------------------------------------
+ */
+func plat_marvell_calc_core_pos
+ and x1, x0, #MPIDR_CPU_MASK
+ and x0, x0, #MPIDR_CLUSTER_MASK
+ add x0, x1, x0, LSR #7
+ ret
+endfunc plat_marvell_calc_core_pos
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ * Function to initialize the crash console
+ * without a C Runtime to print crash report.
+ * Clobber list : x0, x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_init
+ mov_imm x0, PLAT_MARVELL_CRASH_UART_BASE
+ mov_imm x1, PLAT_MARVELL_CRASH_UART_CLK_IN_HZ
+ mov_imm x2, MARVELL_CONSOLE_BAUDRATE
+ b console_core_init
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ * Function to print a character on the crash
+ * console without a C Runtime.
+ * Clobber list : x1, x2
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ mov_imm x1, PLAT_MARVELL_CRASH_UART_BASE
+ b console_core_putc
+endfunc plat_crash_console_putc
+
+ /* ---------------------------------------------------------------------
+ * We don't need to carry out any memory initialization on ARM
+ * platforms. The Secure RAM is accessible straight away.
+ * ---------------------------------------------------------------------
+ */
+func platform_mem_init
+ ret
+endfunc platform_mem_init
+
+ /* -----------------------------------------------------
+ * Disable icache, dcache, and MMU
+ * -----------------------------------------------------
+ */
+func disable_mmu_dcache
+ mrs x0, sctlr_el3
+ bic x0, x0, 0x1 /* M bit - MMU */
+ bic x0, x0, 0x4 /* C bit - Dcache L1 & L2 */
+ msr sctlr_el3, x0
+ isb
+ b mmu_off
+mmu_off:
+ ret
+endfunc disable_mmu_dcache
+
+ /* -----------------------------------------------------
+ * Disable all TLB entries
+ * -----------------------------------------------------
+ */
+func invalidate_tlb_all
+ tlbi alle3
+ dsb sy
+ isb
+ ret
+endfunc invalidate_tlb_all
+
+ /* -----------------------------------------------------
+ * Disable the i cache
+ * -----------------------------------------------------
+ */
+func disable_icache
+ mrs x0, sctlr_el3
+ bic x0, x0, 0x1000 /* I bit - Icache L1 & L2 */
+ msr sctlr_el3, x0
+ isb
+ ret
+endfunc disable_icache
+
+ /* -----------------------------------------------------
+ * Disable all of the i caches
+ * -----------------------------------------------------
+ */
+func invalidate_icache_all
+ ic ialluis
+ isb sy
+ ret
+endfunc invalidate_icache_all
+
+ /* -----------------------------------------------------
+ * Clear the SRAM enabling bit to unmap SRAM
+ * -----------------------------------------------------
+ */
+func platform_unmap_sram
+ ldr x0, =CCU_SRAM_WIN_CR
+ str wzr, [x0]
+ ret
+endfunc platform_unmap_sram
+
+ /* -----------------------------------------------------
+ * Disable the SRAM
+ * -----------------------------------------------------
+ */
+func disable_sram
+ /* Disable the line lockings. They must be disabled expictly
+ * or the OS will have problems using the cache */
+ ldr x1, =MASTER_LLC_TC0_LOCK
+ str wzr, [x1]
+
+ /* Invalidate all ways */
+ ldr w1, =LLC_WAY_MASK
+ ldr x0, =MASTER_L2X0_INV_WAY
+ str w1, [x0]
+
+ /* Finally disable LLC */
+ ldr x0, =MASTER_LLC_CTRL
+ str wzr, [x0]
+
+ ret
+endfunc disable_sram
+
+ /* -----------------------------------------------------
+ * Operation when exit bootROM:
+ * Disable the MMU
+ * Disable and invalidate the dcache
+ * Unmap and disable the SRAM
+ * Disable and invalidate the icache
+ * -----------------------------------------------------
+ */
+func marvell_exit_bootrom
+ /* Save the system restore address */
+ mov x28, x0
+
+ /* Close the caches and MMU */
+ bl disable_mmu_dcache
+
+ /*
+ * There is nothing important in the caches now,
+ * so invalidate them instead of cleaning.
+ */
+ adr x0, __RW_START__
+ adr x1, __RW_END__
+ sub x1, x1, x0
+ bl inv_dcache_range
+ bl invalidate_tlb_all
+
+ /*
+ * Clean the memory mapping of SRAM
+ * the DDR mapping will remain to enable boot image to execute
+ */
+ bl platform_unmap_sram
+
+ /* Disable the SRAM */
+ bl disable_sram
+
+ /* Disable and invalidate icache */
+ bl disable_icache
+ bl invalidate_icache_all
+
+ mov x0, x28
+ br x0
+endfunc marvell_exit_bootrom
+
+ /*
+ * Enable L2 UniqueClean evictions with data
+ */
+func ca72_l2_enable_unique_clean
+
+ mrs x0, CORTEX_A72_L2ACTLR_EL1
+ orr x0, x0, #CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN
+ msr CORTEX_A72_L2ACTLR_EL1, x0
+
+ ret
+endfunc ca72_l2_enable_unique_clean
diff --git a/plat/marvell/common/marvell_bl1_setup.c b/plat/marvell/common/marvell_bl1_setup.c
new file mode 100644
index 000000000..981cfbe88
--- /dev/null
+++ b/plat/marvell/common/marvell_bl1_setup.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <bl1.h>
+#include <bl1/bl1_private.h>
+#include <bl_common.h>
+#include <console.h>
+#include <debug.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <plat_marvell.h>
+#include <sp805.h>
+
+/* Weak definitions may be overridden in specific Marvell standard platform */
+#pragma weak bl1_early_platform_setup
+#pragma weak bl1_plat_arch_setup
+#pragma weak bl1_platform_setup
+#pragma weak bl1_plat_sec_mem_layout
+
+
+/* Data structure which holds the extents of the RAM for BL1*/
+static meminfo_t bl1_ram_layout;
+
+meminfo_t *bl1_plat_sec_mem_layout(void)
+{
+ return &bl1_ram_layout;
+}
+
+/*
+ * BL1 specific platform actions shared between Marvell standard platforms.
+ */
+void marvell_bl1_early_platform_setup(void)
+{
+ const size_t bl1_size = BL1_RAM_LIMIT - BL1_RAM_BASE;
+
+ /* Initialize the console to provide early debug support */
+ console_init(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE);
+
+ /* Allow BL1 to see the whole Trusted RAM */
+ bl1_ram_layout.total_base = MARVELL_BL_RAM_BASE;
+ bl1_ram_layout.total_size = MARVELL_BL_RAM_SIZE;
+
+ /* Calculate how much RAM BL1 is using and how much remains free */
+ bl1_ram_layout.free_base = MARVELL_BL_RAM_BASE;
+ bl1_ram_layout.free_size = MARVELL_BL_RAM_SIZE;
+ reserve_mem(&bl1_ram_layout.free_base,
+ &bl1_ram_layout.free_size,
+ BL1_RAM_BASE,
+ bl1_size);
+}
+
+void bl1_early_platform_setup(void)
+{
+ marvell_bl1_early_platform_setup();
+}
+
+/*
+ * Perform the very early platform specific architecture setup shared between
+ * MARVELL standard platforms. This only does basic initialization. Later
+ * architectural setup (bl1_arch_setup()) does not do anything platform
+ * specific.
+ */
+void marvell_bl1_plat_arch_setup(void)
+{
+ marvell_setup_page_tables(bl1_ram_layout.total_base,
+ bl1_ram_layout.total_size,
+ BL1_RO_BASE,
+ BL1_RO_LIMIT,
+ BL1_RO_DATA_BASE,
+ BL1_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ enable_mmu_el3(0);
+}
+
+void bl1_plat_arch_setup(void)
+{
+ marvell_bl1_plat_arch_setup();
+}
+
+/*
+ * Perform the platform specific architecture setup shared between
+ * MARVELL standard platforms.
+ */
+void marvell_bl1_platform_setup(void)
+{
+ /* Initialise the IO layer and register platform IO devices */
+ plat_marvell_io_setup();
+}
+
+void bl1_platform_setup(void)
+{
+ marvell_bl1_platform_setup();
+}
+
+void bl1_plat_prepare_exit(entry_point_info_t *ep_info)
+{
+#ifdef EL3_PAYLOAD_BASE
+ /*
+ * Program the EL3 payload's entry point address into the CPUs mailbox
+ * in order to release secondary CPUs from their holding pen and make
+ * them jump there.
+ */
+ marvell_program_trusted_mailbox(ep_info->pc);
+ dsbsy();
+ sev();
+#endif
+}
diff --git a/plat/marvell/common/marvell_bl2_setup.c b/plat/marvell/common/marvell_bl2_setup.c
new file mode 100644
index 000000000..7c87ce338
--- /dev/null
+++ b/plat/marvell/common/marvell_bl2_setup.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <bl_common.h>
+#include <console.h>
+#include <marvell_def.h>
+#include <platform_def.h>
+#include <plat_marvell.h>
+#include <string.h>
+
+/* Data structure which holds the extents of the trusted SRAM for BL2 */
+static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
+
+
+/*****************************************************************************
+ * This structure represents the superset of information that is passed to
+ * BL31, e.g. while passing control to it from BL2, bl31_params
+ * and other platform specific parameters
+ *****************************************************************************
+ */
+typedef struct bl2_to_bl31_params_mem {
+ bl31_params_t bl31_params;
+ image_info_t bl31_image_info;
+ image_info_t bl32_image_info;
+ image_info_t bl33_image_info;
+ entry_point_info_t bl33_ep_info;
+ entry_point_info_t bl32_ep_info;
+ entry_point_info_t bl31_ep_info;
+} bl2_to_bl31_params_mem_t;
+
+
+static bl2_to_bl31_params_mem_t bl31_params_mem;
+
+
+/* Weak definitions may be overridden in specific MARVELL standard platform */
+#pragma weak bl2_early_platform_setup
+#pragma weak bl2_platform_setup
+#pragma weak bl2_plat_arch_setup
+#pragma weak bl2_plat_sec_mem_layout
+#pragma weak bl2_plat_get_bl31_params
+#pragma weak bl2_plat_get_bl31_ep_info
+#pragma weak bl2_plat_flush_bl31_params
+#pragma weak bl2_plat_set_bl31_ep_info
+#pragma weak bl2_plat_get_scp_bl2_meminfo
+#pragma weak bl2_plat_get_bl32_meminfo
+#pragma weak bl2_plat_set_bl32_ep_info
+#pragma weak bl2_plat_get_bl33_meminfo
+#pragma weak bl2_plat_set_bl33_ep_info
+
+
+meminfo_t *bl2_plat_sec_mem_layout(void)
+{
+ return &bl2_tzram_layout;
+}
+
+/*****************************************************************************
+ * This function assigns a pointer to the memory that the platform has kept
+ * aside to pass platform specific and trusted firmware related information
+ * to BL31. This memory is allocated by allocating memory to
+ * bl2_to_bl31_params_mem_t structure which is a superset of all the
+ * structure whose information is passed to BL31
+ * NOTE: This function should be called only once and should be done
+ * before generating params to BL31
+ *****************************************************************************
+ */
+bl31_params_t *bl2_plat_get_bl31_params(void)
+{
+ bl31_params_t *bl2_to_bl31_params;
+
+ /*
+ * Initialise the memory for all the arguments that needs to
+ * be passed to BL31
+ */
+ memset(&bl31_params_mem, 0, sizeof(bl2_to_bl31_params_mem_t));
+
+ /* Assign memory for TF related information */
+ bl2_to_bl31_params = &bl31_params_mem.bl31_params;
+ SET_PARAM_HEAD(bl2_to_bl31_params, PARAM_BL31, VERSION_1, 0);
+
+ /* Fill BL31 related information */
+ bl2_to_bl31_params->bl31_image_info = &bl31_params_mem.bl31_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl31_image_info, PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+
+ /* Fill BL32 related information if it exists */
+#if BL32_BASE
+ bl2_to_bl31_params->bl32_ep_info = &bl31_params_mem.bl32_ep_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_ep_info, PARAM_EP,
+ VERSION_1, 0);
+ bl2_to_bl31_params->bl32_image_info = &bl31_params_mem.bl32_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl32_image_info, PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+#endif
+
+ /* Fill BL33 related information */
+ bl2_to_bl31_params->bl33_ep_info = &bl31_params_mem.bl33_ep_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_ep_info,
+ PARAM_EP, VERSION_1, 0);
+
+ /* BL33 expects to receive the primary CPU MPID (through x0) */
+ bl2_to_bl31_params->bl33_ep_info->args.arg0 = 0xffff & read_mpidr();
+
+ bl2_to_bl31_params->bl33_image_info = &bl31_params_mem.bl33_image_info;
+ SET_PARAM_HEAD(bl2_to_bl31_params->bl33_image_info, PARAM_IMAGE_BINARY,
+ VERSION_1, 0);
+
+ return bl2_to_bl31_params;
+}
+
+/* Flush the TF params and the TF plat params */
+void bl2_plat_flush_bl31_params(void)
+{
+ flush_dcache_range((unsigned long)&bl31_params_mem,
+ sizeof(bl2_to_bl31_params_mem_t));
+}
+
+/*****************************************************************************
+ * This function returns a pointer to the shared memory that the platform
+ * has kept to point to entry point information of BL31 to BL2
+ *****************************************************************************
+ */
+struct entry_point_info *bl2_plat_get_bl31_ep_info(void)
+{
+#if DEBUG
+ bl31_params_mem.bl31_ep_info.args.arg1 = MARVELL_BL31_PLAT_PARAM_VAL;
+#endif
+
+ return &bl31_params_mem.bl31_ep_info;
+}
+
+/*****************************************************************************
+ * BL1 has passed the extents of the trusted SRAM that should be visible to BL2
+ * in x0. This memory layout is sitting at the base of the free trusted SRAM.
+ * Copy it to a safe location before its reclaimed by later BL2 functionality.
+ *****************************************************************************
+ */
+void marvell_bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+ /* Initialize the console to provide early debug support */
+ console_init(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE);
+
+ /* Setup the BL2 memory layout */
+ bl2_tzram_layout = *mem_layout;
+
+ /* Initialise the IO layer and register platform IO devices */
+ plat_marvell_io_setup();
+}
+
+void bl2_early_platform_setup(meminfo_t *mem_layout)
+{
+ marvell_bl2_early_platform_setup(mem_layout);
+}
+
+void bl2_platform_setup(void)
+{
+ /* Nothing to do */
+}
+
+/*****************************************************************************
+ * Perform the very early platform specific architectural setup here. At the
+ * moment this is only initializes the mmu in a quick and dirty way.
+ *****************************************************************************
+ */
+void marvell_bl2_plat_arch_setup(void)
+{
+ marvell_setup_page_tables(bl2_tzram_layout.total_base,
+ bl2_tzram_layout.total_size,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+ enable_mmu_el1(0);
+}
+
+void bl2_plat_arch_setup(void)
+{
+ marvell_bl2_plat_arch_setup();
+}
+
+/*****************************************************************************
+ * Populate the extents of memory available for loading SCP_BL2 (if used),
+ * i.e. anywhere in trusted RAM as long as it doesn't overwrite BL2.
+ *****************************************************************************
+ */
+void bl2_plat_get_scp_bl2_meminfo(meminfo_t *scp_bl2_meminfo)
+{
+ *scp_bl2_meminfo = bl2_tzram_layout;
+}
+
+/*****************************************************************************
+ * Before calling this function BL31 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL31 and set SPSR and security state.
+ * On MARVELL std. platforms we only set the security state of the entrypoint
+ *****************************************************************************
+ */
+void bl2_plat_set_bl31_ep_info(image_info_t *bl31_image_info,
+ entry_point_info_t *bl31_ep_info)
+{
+ SET_SECURITY_STATE(bl31_ep_info->h.attr, SECURE);
+ bl31_ep_info->spsr = SPSR_64(MODE_EL3, MODE_SP_ELX,
+ DISABLE_ALL_EXCEPTIONS);
+}
+
+/*****************************************************************************
+ * Populate the extents of memory available for loading BL32
+ *****************************************************************************
+ */
+#ifdef BL32_BASE
+void bl2_plat_get_bl32_meminfo(meminfo_t *bl32_meminfo)
+{
+ /*
+ * Populate the extents of memory available for loading BL32.
+ */
+ bl32_meminfo->total_base = BL32_BASE;
+ bl32_meminfo->free_base = BL32_BASE;
+ bl32_meminfo->total_size =
+ (TRUSTED_DRAM_BASE + TRUSTED_DRAM_SIZE) - BL32_BASE;
+ bl32_meminfo->free_size =
+ (TRUSTED_DRAM_BASE + TRUSTED_DRAM_SIZE) - BL32_BASE;
+}
+#endif
+
+/*****************************************************************************
+ * Before calling this function BL32 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL32 and set SPSR and security state.
+ * On MARVELL std. platforms we only set the security state of the entrypoint
+ *****************************************************************************
+ */
+void bl2_plat_set_bl32_ep_info(image_info_t *bl32_image_info,
+ entry_point_info_t *bl32_ep_info)
+{
+ SET_SECURITY_STATE(bl32_ep_info->h.attr, SECURE);
+ bl32_ep_info->spsr = marvell_get_spsr_for_bl32_entry();
+}
+
+/*****************************************************************************
+ * Before calling this function BL33 is loaded in memory and its entrypoint
+ * is set by load_image. This is a placeholder for the platform to change
+ * the entrypoint of BL33 and set SPSR and security state.
+ * On MARVELL std. platforms we only set the security state of the entrypoint
+ *****************************************************************************
+ */
+void bl2_plat_set_bl33_ep_info(image_info_t *image,
+ entry_point_info_t *bl33_ep_info)
+{
+
+ SET_SECURITY_STATE(bl33_ep_info->h.attr, NON_SECURE);
+ bl33_ep_info->spsr = marvell_get_spsr_for_bl33_entry();
+}
+
+/*****************************************************************************
+ * Populate the extents of memory available for loading BL33
+ *****************************************************************************
+ */
+void bl2_plat_get_bl33_meminfo(meminfo_t *bl33_meminfo)
+{
+ bl33_meminfo->total_base = MARVELL_DRAM_BASE;
+ bl33_meminfo->total_size = MARVELL_DRAM_SIZE;
+ bl33_meminfo->free_base = MARVELL_DRAM_BASE;
+ bl33_meminfo->free_size = MARVELL_DRAM_SIZE;
+}
diff --git a/plat/marvell/common/marvell_bl31_setup.c b/plat/marvell/common/marvell_bl31_setup.c
new file mode 100644
index 000000000..f3818767d
--- /dev/null
+++ b/plat/marvell/common/marvell_bl31_setup.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch.h>
+#include <assert.h>
+#include <console.h>
+#include <debug.h>
+#include <marvell_def.h>
+#include <marvell_plat_priv.h>
+#include <plat_marvell.h>
+#include <platform.h>
+
+#ifdef USE_CCI
+#include <cci.h>
+#endif
+
+/*
+ * The next 3 constants identify the extents of the code, RO data region and the
+ * limit of the BL31 image. These addresses are used by the MMU setup code and
+ * therefore they must be page-aligned. It is the responsibility of the linker
+ * script to ensure that __RO_START__, __RO_END__ & __BL31_END__ linker symbols
+ * refer to page-aligned addresses.
+ */
+#define BL31_END (unsigned long)(&__BL31_END__)
+
+/*
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL31 from BL2.
+ */
+static entry_point_info_t bl32_image_ep_info;
+static entry_point_info_t bl33_image_ep_info;
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak bl31_early_platform_setup2
+#pragma weak bl31_platform_setup
+#pragma weak bl31_plat_arch_setup
+#pragma weak bl31_plat_get_next_image_ep_info
+#pragma weak plat_get_syscnt_freq2
+
+/*****************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ *****************************************************************************
+ */
+entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
+{
+ entry_point_info_t *next_image_info;
+
+ assert(sec_state_is_valid(type));
+ next_image_info = (type == NON_SECURE)
+ ? &bl33_image_ep_info : &bl32_image_ep_info;
+
+ return next_image_info;
+}
+
+/*****************************************************************************
+ * Perform any BL31 early platform setup common to ARM standard platforms.
+ * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
+ * in BL2 & S-EL3 in BL1) before they are lost (potentially). This needs to be
+ * done before the MMU is initialized so that the memory layout can be used
+ * while creating page tables. BL2 has flushed this information to memory, so
+ * we are guaranteed to pick up good data.
+ *****************************************************************************
+ */
+void marvell_bl31_early_platform_setup(bl31_params_t *from_bl2,
+ uintptr_t soc_fw_config,
+ uintptr_t hw_config,
+ void *plat_params_from_bl2)
+{
+ /* Initialize the console to provide early debug support */
+ console_init(PLAT_MARVELL_BOOT_UART_BASE,
+ PLAT_MARVELL_BOOT_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE);
+
+#if RESET_TO_BL31
+ /* There are no parameters from BL2 if BL31 is a reset vector */
+ assert(from_bl2 == NULL);
+ assert(plat_params_from_bl2 == NULL);
+
+#ifdef BL32_BASE
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = marvell_get_spsr_for_bl32_entry();
+#endif /* BL32_BASE */
+
+ /* Populate entry point information for BL33 */
+ SET_PARAM_HEAD(&bl33_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ /*
+ * Tell BL31 where the non-trusted software image
+ * is located and the entry state information
+ */
+ bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
+ bl33_image_ep_info.spsr = marvell_get_spsr_for_bl33_entry();
+ SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
+
+#else
+ /*
+ * Check params passed from BL2 should not be NULL,
+ */
+ assert(from_bl2 != NULL);
+ assert(from_bl2->h.type == PARAM_BL31);
+ assert(from_bl2->h.version >= VERSION_1);
+ /*
+ * In debug builds, we pass a special value in 'plat_params_from_bl2'
+ * to verify platform parameters from BL2 to BL31.
+ * In release builds, it's not used.
+ */
+ assert(((unsigned long long)plat_params_from_bl2) ==
+ MARVELL_BL31_PLAT_PARAM_VAL);
+
+ /*
+ * Copy BL32 (if populated by BL2) and BL33 entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ if (from_bl2->bl32_ep_info)
+ bl32_image_ep_info = *from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *from_bl2->bl33_ep_info;
+#endif
+}
+
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+
+{
+ marvell_bl31_early_platform_setup((void *)arg0, arg1, arg2,
+ (void *)arg3);
+
+#ifdef USE_CCI
+ /*
+ * Initialize CCI for this cluster during cold boot.
+ * No need for locks as no other CPU is active.
+ */
+ plat_marvell_interconnect_init();
+
+ /*
+ * Enable CCI coherency for the primary CPU's cluster.
+ * Platform specific PSCI code will enable coherency for other
+ * clusters.
+ */
+ plat_marvell_interconnect_enter_coherency();
+#endif
+}
+
+/*****************************************************************************
+ * Perform any BL31 platform setup common to ARM standard platforms
+ *****************************************************************************
+ */
+void marvell_bl31_platform_setup(void)
+{
+ /* Initialize the GIC driver, cpu and distributor interfaces */
+ plat_marvell_gic_driver_init();
+ plat_marvell_gic_init();
+
+ /* For Armada-8k-plus family, the SoC includes more than
+ * a single AP die, but the default die that boots is AP #0.
+ * For other families there is only one die (#0).
+ * Initialize psci arch from die 0
+ */
+ marvell_psci_arch_init(0);
+}
+
+/*****************************************************************************
+ * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
+ * standard platforms
+ *****************************************************************************
+ */
+void marvell_bl31_plat_runtime_setup(void)
+{
+ /* Initialize the runtime console */
+ console_init(PLAT_MARVELL_BL31_RUN_UART_BASE,
+ PLAT_MARVELL_BL31_RUN_UART_CLK_IN_HZ,
+ MARVELL_CONSOLE_BAUDRATE);
+}
+
+void bl31_platform_setup(void)
+{
+ marvell_bl31_platform_setup();
+}
+
+void bl31_plat_runtime_setup(void)
+{
+ marvell_bl31_plat_runtime_setup();
+}
+
+/*****************************************************************************
+ * Perform the very early platform specific architectural setup shared between
+ * ARM standard platforms. This only does basic initialization. Later
+ * architectural setup (bl31_arch_setup()) does not do anything platform
+ * specific.
+ *****************************************************************************
+ */
+void marvell_bl31_plat_arch_setup(void)
+{
+ marvell_setup_page_tables(BL31_BASE,
+ BL31_END - BL31_BASE,
+ BL_CODE_BASE,
+ BL_CODE_END,
+ BL_RO_DATA_BASE,
+ BL_RO_DATA_END
+#if USE_COHERENT_MEM
+ , BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END
+#endif
+ );
+
+#if BL31_CACHE_DISABLE
+ enable_mmu_el3(DISABLE_DCACHE);
+ INFO("Cache is disabled in BL3\n");
+#else
+ enable_mmu_el3(0);
+#endif
+}
+
+void bl31_plat_arch_setup(void)
+{
+ marvell_bl31_plat_arch_setup();
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return PLAT_REF_CLK_IN_HZ;
+}
diff --git a/plat/marvell/common/marvell_cci.c b/plat/marvell/common/marvell_cci.c
new file mode 100644
index 000000000..2df480243
--- /dev/null
+++ b/plat/marvell/common/marvell_cci.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <cci.h>
+#include <plat_marvell.h>
+
+static const int cci_map[] = {
+ PLAT_MARVELL_CCI_CLUSTER0_SL_IFACE_IX,
+ PLAT_MARVELL_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_marvell_interconnect_init
+#pragma weak plat_marvell_interconnect_enter_coherency
+#pragma weak plat_marvell_interconnect_exit_coherency
+
+
+/****************************************************************************
+ * Helper function to initialize ARM CCI driver.
+ ****************************************************************************
+ */
+void plat_marvell_interconnect_init(void)
+{
+ cci_init(PLAT_MARVELL_CCI_BASE, cci_map, ARRAY_SIZE(cci_map));
+}
+
+/****************************************************************************
+ * Helper function to place current master into coherency
+ ****************************************************************************
+ */
+void plat_marvell_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_marvell_interconnect_exit_coherency(void)
+{
+ cci_disable_snoop_dvm_reqs(MPIDR_AFFLVL1_VAL(read_mpidr_el1()));
+}
diff --git a/plat/marvell/common/marvell_common.mk b/plat/marvell/common/marvell_common.mk
new file mode 100644
index 000000000..3ee2f3dba
--- /dev/null
+++ b/plat/marvell/common/marvell_common.mk
@@ -0,0 +1,67 @@
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+
+MARVELL_PLAT_BASE := plat/marvell
+MARVELL_PLAT_INCLUDE_BASE := include/plat/marvell
+
+include $(MARVELL_PLAT_BASE)/version.mk
+include $(MARVELL_PLAT_BASE)/marvell.mk
+
+VERSION_STRING +=(Marvell-${SUBVERSION})
+
+SEPARATE_CODE_AND_RODATA := 1
+
+# flag to switch from PLL to ARO
+ARO_ENABLE := 0
+$(eval $(call add_define,ARO_ENABLE))
+# Enable/Disable LLC
+LLC_ENABLE := 1
+$(eval $(call add_define,LLC_ENABLE))
+
+PLAT_INCLUDES += -I. -Iinclude/common/tbbr \
+ -I$(MARVELL_PLAT_INCLUDE_BASE)/common \
+ -I$(MARVELL_PLAT_INCLUDE_BASE)/common/aarch64
+
+
+PLAT_BL_COMMON_SOURCES += lib/xlat_tables/xlat_tables_common.c \
+ lib/xlat_tables/aarch64/xlat_tables.c \
+ $(MARVELL_PLAT_BASE)/common/aarch64/marvell_common.c \
+ $(MARVELL_PLAT_BASE)/common/aarch64/marvell_helpers.S
+
+BL1_SOURCES += drivers/delay_timer/delay_timer.c \
+ drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_bl1_setup.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c \
+ $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c
+
+ifdef EL3_PAYLOAD_BASE
+# Need the arm_program_trusted_mailbox() function to release secondary CPUs from
+# their holding pen
+endif
+
+BL2_SOURCES += drivers/io/io_fip.c \
+ drivers/io/io_memmap.c \
+ drivers/io/io_storage.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_bl2_setup.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_io_storage.c
+
+BL31_SOURCES += $(MARVELL_PLAT_BASE)/common/marvell_bl31_setup.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_pm.c \
+ $(MARVELL_PLAT_BASE)/common/marvell_topology.c \
+ plat/common/plat_psci_common.c \
+ $(MARVELL_PLAT_BASE)/common/plat_delay_timer.c \
+ drivers/delay_timer/delay_timer.c
+
+# PSCI functionality
+$(eval $(call add_define,CONFIG_ARM64))
+
+# MSS (SCP) build
+ifeq (${MSS_SUPPORT}, 1)
+include $(MARVELL_PLAT_BASE)/common/mss/mss_common.mk
+endif
+
+fip: mrvl_flash
diff --git a/plat/marvell/common/marvell_ddr_info.c b/plat/marvell/common/marvell_ddr_info.c
new file mode 100644
index 000000000..68bff998b
--- /dev/null
+++ b/plat/marvell/common/marvell_ddr_info.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <debug.h>
+#include <platform_def.h>
+#include <ddr_info.h>
+#include <mmio.h>
+
+#define DRAM_CH0_MMAP_LOW_REG(iface, cs, base) \
+ (base + DRAM_CH0_MMAP_LOW_OFFSET + (iface) * 0x10000 + (cs) * 0x8)
+#define DRAM_CH0_MMAP_HIGH_REG(iface, cs, base) \
+ (DRAM_CH0_MMAP_LOW_REG(iface, cs, base) + 4)
+#define DRAM_CS_VALID_ENABLED_MASK 0x1
+#define DRAM_AREA_LENGTH_OFFS 16
+#define DRAM_AREA_LENGTH_MASK (0x1f << DRAM_AREA_LENGTH_OFFS)
+#define DRAM_START_ADDRESS_L_OFFS 23
+#define DRAM_START_ADDRESS_L_MASK \
+ (0x1ff << DRAM_START_ADDRESS_L_OFFS)
+#define DRAM_START_ADDR_HTOL_OFFS 32
+
+#define DRAM_MAX_CS_NUM 2
+
+#define DRAM_CS_ENABLED(iface, cs, base) \
+ (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \
+ DRAM_CS_VALID_ENABLED_MASK)
+#define GET_DRAM_REGION_SIZE_CODE(iface, cs, base) \
+ (mmio_read_32(DRAM_CH0_MMAP_LOW_REG(iface, cs, base)) & \
+ DRAM_AREA_LENGTH_MASK) >> DRAM_AREA_LENGTH_OFFS
+
+/* Mapping between DDR area length and real DDR size is specific and looks like
+ * bellow:
+ * 0 => 384 MB
+ * 1 => 768 MB
+ * 2 => 1536 MB
+ * 3 => 3 GB
+ * 4 => 6 GB
+ *
+ * 7 => 8 MB
+ * 8 => 16 MB
+ * 9 => 32 MB
+ * 10 => 64 MB
+ * 11 => 128 MB
+ * 12 => 256 MB
+ * 13 => 512 MB
+ * 14 => 1 GB
+ * 15 => 2 GB
+ * 16 => 4 GB
+ * 17 => 8 GB
+ * 18 => 16 GB
+ * 19 => 32 GB
+ * 20 => 64 GB
+ * 21 => 128 GB
+ * 22 => 256 GB
+ * 23 => 512 GB
+ * 24 => 1 TB
+ * 25 => 2 TB
+ * 26 => 4 TB
+ *
+ * to calculate real size we need to use two different formulas:
+ * -- GET_DRAM_REGION_SIZE_ODD for values 0-4 (DRAM_REGION_SIZE_ODD)
+ * -- GET_DRAM_REGION_SIZE_EVEN for values 7-26 (DRAM_REGION_SIZE_EVEN)
+ * using mentioned formulas we cover whole mapping between "Area length" value
+ * and real size (see above mapping).
+ */
+#define DRAM_REGION_SIZE_EVEN(C) (((C) >= 7) && ((C) <= 26))
+#define GET_DRAM_REGION_SIZE_EVEN(C) ((uint64_t)1 << ((C) + 16))
+#define DRAM_REGION_SIZE_ODD(C) ((C) <= 4)
+#define GET_DRAM_REGION_SIZE_ODD(C) ((uint64_t)0x18000000 << (C))
+
+
+uint64_t mvebu_get_dram_size(uint64_t ap_base_addr)
+{
+ uint64_t mem_size = 0;
+ uint8_t region_code;
+ uint8_t cs, iface;
+
+ for (iface = 0; iface < DRAM_MAX_IFACE; iface++) {
+ for (cs = 0; cs < DRAM_MAX_CS_NUM; cs++) {
+
+ /* Exit loop on first disabled DRAM CS */
+ if (!DRAM_CS_ENABLED(iface, cs, ap_base_addr))
+ break;
+
+ /* Decode area length for current CS
+ * from register value
+ */
+ region_code =
+ GET_DRAM_REGION_SIZE_CODE(iface, cs,
+ ap_base_addr);
+
+ if (DRAM_REGION_SIZE_EVEN(region_code)) {
+ mem_size +=
+ GET_DRAM_REGION_SIZE_EVEN(region_code);
+ } else if (DRAM_REGION_SIZE_ODD(region_code)) {
+ mem_size +=
+ GET_DRAM_REGION_SIZE_ODD(region_code);
+ } else {
+ WARN("%s: Invalid mem region (0x%x) CS#%d\n",
+ __func__, region_code, cs);
+ return 0;
+ }
+ }
+ }
+
+ return mem_size;
+}
diff --git a/plat/marvell/common/marvell_gicv2.c b/plat/marvell/common/marvell_gicv2.c
new file mode 100644
index 000000000..ba8e40961
--- /dev/null
+++ b/plat/marvell/common/marvell_gicv2.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <gicv2.h>
+#include <plat_marvell.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*
+ * The following functions are defined as weak to allow a platform to override
+ * the way the GICv2 driver is initialised and used.
+ */
+#pragma weak plat_marvell_gic_driver_init
+#pragma weak plat_marvell_gic_init
+
+/*
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ */
+static const interrupt_prop_t marvell_interrupt_props[] = {
+ PLAT_MARVELL_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ PLAT_MARVELL_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+};
+
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+
+/*
+ * Ideally `marvell_gic_data` structure definition should be a `const` but it is
+ * kept as modifiable for overwriting with different GICD and GICC base when
+ * running on FVP with VE memory map.
+ */
+static gicv2_driver_data_t marvell_gic_data = {
+ .gicd_base = PLAT_MARVELL_GICD_BASE,
+ .gicc_base = PLAT_MARVELL_GICC_BASE,
+ .interrupt_props = marvell_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(marvell_interrupt_props),
+ .target_masks = target_mask_array,
+ .target_masks_num = ARRAY_SIZE(target_mask_array),
+};
+
+/*
+ * ARM common helper to initialize the GICv2 only driver.
+ */
+void plat_marvell_gic_driver_init(void)
+{
+ gicv2_driver_init(&marvell_gic_data);
+}
+
+void plat_marvell_gic_init(void)
+{
+ gicv2_distif_init();
+ gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
+ gicv2_cpuif_enable();
+}
diff --git a/plat/marvell/common/marvell_io_storage.c b/plat/marvell/common/marvell_io_storage.c
new file mode 100644
index 000000000..cb9ece247
--- /dev/null
+++ b/plat/marvell/common/marvell_io_storage.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <assert.h>
+#include <bl_common.h> /* For ARRAY_SIZE */
+#include <debug.h>
+#include <firmware_image_package.h>
+#include <io_driver.h>
+#include <io_fip.h>
+#include <io_memmap.h>
+#include <io_storage.h>
+#include <platform_def.h>
+#include <string.h>
+
+/* IO devices */
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static const io_dev_connector_t *memmap_dev_con;
+static uintptr_t memmap_dev_handle;
+
+static const io_block_spec_t fip_block_spec = {
+ .offset = PLAT_MARVELL_FIP_BASE,
+ .length = PLAT_MARVELL_FIP_MAX_SIZE
+};
+
+static const io_uuid_spec_t bl2_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
+};
+
+static const io_uuid_spec_t scp_bl2_uuid_spec = {
+ .uuid = UUID_SCP_FIRMWARE_SCP_BL2,
+};
+
+static const io_uuid_spec_t bl31_uuid_spec = {
+ .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
+};
+static const io_uuid_spec_t bl32_uuid_spec = {
+ .uuid = UUID_SECURE_PAYLOAD_BL32,
+};
+static const io_uuid_spec_t bl33_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
+};
+
+static int open_fip(const uintptr_t spec);
+static int open_memmap(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+/* By default, Marvell platforms load images from the FIP */
+static const struct plat_io_policy policies[] = {
+ [FIP_IMAGE_ID] = {
+ &memmap_dev_handle,
+ (uintptr_t)&fip_block_spec,
+ open_memmap
+ },
+ [BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl2_uuid_spec,
+ open_fip
+ },
+ [SCP_BL2_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&scp_bl2_uuid_spec,
+ open_fip
+ },
+ [BL31_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl31_uuid_spec,
+ open_fip
+ },
+ [BL32_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl32_uuid_spec,
+ open_fip
+ },
+ [BL33_IMAGE_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&bl33_uuid_spec,
+ open_fip
+ },
+};
+
+
+/* Weak definitions may be overridden in specific ARM standard platform */
+#pragma weak plat_marvell_io_setup
+#pragma weak plat_marvell_get_alt_image_source
+
+
+static int open_fip(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ /* See if a Firmware Image Package is available */
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+ if (result == 0) {
+ result = io_open(fip_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using FIP\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+static int open_memmap(const uintptr_t spec)
+{
+ int result;
+ uintptr_t local_image_handle;
+
+ result = io_dev_init(memmap_dev_handle, (uintptr_t)NULL);
+ if (result == 0) {
+ result = io_open(memmap_dev_handle, spec, &local_image_handle);
+ if (result == 0) {
+ VERBOSE("Using Memmap\n");
+ io_close(local_image_handle);
+ }
+ }
+ return result;
+}
+
+
+void marvell_io_setup(void)
+{
+ int io_result;
+
+ io_result = register_io_dev_fip(&fip_dev_con);
+ assert(io_result == 0);
+
+ io_result = register_io_dev_memmap(&memmap_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to devices and cache the handles */
+ io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+ &fip_dev_handle);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL,
+ &memmap_dev_handle);
+ assert(io_result == 0);
+
+ /* Ignore improbable errors in release builds */
+ (void)io_result;
+}
+
+void plat_marvell_io_setup(void)
+{
+ marvell_io_setup();
+}
+
+int plat_marvell_get_alt_image_source(
+ unsigned int image_id __attribute__((unused)),
+ uintptr_t *dev_handle __attribute__((unused)),
+ uintptr_t *image_spec __attribute__((unused)))
+{
+ /* By default do not try an alternative */
+ return -ENOENT;
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int result;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ policy = &policies[image_id];
+ result = policy->check(policy->image_spec);
+ if (result == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ } else {
+ VERBOSE("Trying alternative IO\n");
+ result = plat_marvell_get_alt_image_source(image_id, dev_handle,
+ image_spec);
+ }
+
+ return result;
+}
+
+/*
+ * See if a Firmware Image Package is available,
+ * by checking if TOC is valid or not.
+ */
+int marvell_io_is_toc_valid(void)
+{
+ int result;
+
+ result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
+
+ return result == 0;
+}
diff --git a/plat/marvell/common/marvell_pm.c b/plat/marvell/common/marvell_pm.c
new file mode 100644
index 000000000..2a7579009
--- /dev/null
+++ b/plat/marvell/common/marvell_pm.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <psci.h>
+#include <marvell_pm.h>
+
+/* Standard ARM platforms are expected to export plat_arm_psci_pm_ops */
+extern const plat_psci_ops_t plat_arm_psci_pm_ops;
+
+/*****************************************************************************
+ * Private function to program the mailbox for a cpu before it is released
+ * from reset. This function assumes that the mail box base is within
+ * the MARVELL_SHARED_RAM region
+ *****************************************************************************
+ */
+void marvell_program_mailbox(uintptr_t address)
+{
+ uintptr_t *mailbox = (void *)PLAT_MARVELL_MAILBOX_BASE;
+
+ /*
+ * Ensure that the PLAT_MARVELL_MAILBOX_BASE is within
+ * MARVELL_SHARED_RAM region.
+ */
+ assert((PLAT_MARVELL_MAILBOX_BASE >= MARVELL_SHARED_RAM_BASE) &&
+ ((PLAT_MARVELL_MAILBOX_BASE + sizeof(*mailbox)) <=
+ (MARVELL_SHARED_RAM_BASE + MARVELL_SHARED_RAM_SIZE)));
+
+ mailbox[MBOX_IDX_MAGIC] = MVEBU_MAILBOX_MAGIC_NUM;
+ mailbox[MBOX_IDX_SEC_ADDR] = address;
+
+ /* Flush data cache if the mail box shared RAM is cached */
+#if PLAT_MARVELL_SHARED_RAM_CACHED
+ flush_dcache_range((uintptr_t)PLAT_MARVELL_MAILBOX_BASE +
+ 8 * MBOX_IDX_MAGIC,
+ 2 * sizeof(uint64_t));
+#endif
+}
+
+/*****************************************************************************
+ * The ARM Standard platform definition of platform porting API
+ * `plat_setup_psci_ops`.
+ *****************************************************************************
+ */
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ *psci_ops = &plat_arm_psci_pm_ops;
+
+ /* Setup mailbox with entry point. */
+ marvell_program_mailbox(sec_entrypoint);
+ return 0;
+}
diff --git a/plat/marvell/common/marvell_topology.c b/plat/marvell/common/marvell_topology.c
new file mode 100644
index 000000000..a40ff6f50
--- /dev/null
+++ b/plat/marvell/common/marvell_topology.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <plat_marvell.h>
+
+/* The power domain tree descriptor */
+unsigned char marvell_power_domain_tree_desc[PLAT_MARVELL_CLUSTER_COUNT + 1];
+
+/*****************************************************************************
+ * This function dynamically constructs the topology according to
+ * PLAT_MARVELL_CLUSTER_COUNT and returns it.
+ *****************************************************************************
+ */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ int i;
+
+ /*
+ * The 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 Marvell Platform this is the number of cluster power domains.
+ */
+ marvell_power_domain_tree_desc[0] = PLAT_MARVELL_CLUSTER_COUNT;
+
+ for (i = 0; i < PLAT_MARVELL_CLUSTER_COUNT; i++)
+ marvell_power_domain_tree_desc[i + 1] =
+ PLAT_MARVELL_CLUSTER_CORE_COUNT;
+
+ return marvell_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
+ * is passed.
+ *****************************************************************************
+ */
+int marvell_check_mpidr(u_register_t mpidr)
+{
+ unsigned int nb_id, cluster_id, cpu_id;
+
+ mpidr &= MPIDR_AFFINITY_MASK;
+
+ if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK |
+ MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT))
+ return -1;
+
+ /* Get north bridge ID */
+ nb_id = MPIDR_AFFLVL3_VAL(mpidr);
+ cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+ cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
+
+ if (nb_id >= PLAT_MARVELL_CLUSTER_COUNT)
+ return -1;
+
+ if (cluster_id >= PLAT_MARVELL_CLUSTER_COUNT)
+ return -1;
+
+ if (cpu_id >= PLAT_MARVELL_CLUSTER_CORE_COUNT)
+ return -1;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * This function implements a part of the critical interface between the PSCI
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ *****************************************************************************
+ */
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ if (marvell_check_mpidr(mpidr) == -1)
+ return -1;
+
+ return plat_marvell_calc_core_pos(mpidr);
+}
diff --git a/plat/marvell/common/mrvl_sip_svc.c b/plat/marvell/common/mrvl_sip_svc.c
new file mode 100644
index 000000000..ec293afa3
--- /dev/null
+++ b/plat/marvell/common/mrvl_sip_svc.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <ap_setup.h>
+#include <cache_llc.h>
+#include <debug.h>
+#include <marvell_plat_priv.h>
+#include <runtime_svc.h>
+#include <smcc.h>
+#include "comphy/phy-comphy-cp110.h"
+
+/* #define DEBUG_COMPHY */
+#ifdef DEBUG_COMPHY
+#define debug(format...) NOTICE(format)
+#else
+#define debug(format, arg...)
+#endif
+
+/* Comphy related FID's */
+#define MV_SIP_COMPHY_POWER_ON 0x82000001
+#define MV_SIP_COMPHY_POWER_OFF 0x82000002
+#define MV_SIP_COMPHY_PLL_LOCK 0x82000003
+#define MV_SIP_COMPHY_XFI_TRAIN 0x82000004
+#define MV_SIP_COMPHY_DIG_RESET 0x82000005
+
+/* Miscellaneous FID's' */
+#define MV_SIP_DRAM_SIZE 0x82000010
+#define MV_SIP_LLC_ENABLE 0x82000011
+
+#define MAX_LANE_NR 6
+#define MVEBU_COMPHY_OFFSET 0x441000
+#define MVEBU_SD_OFFSET 0x120000
+
+/* This macro is used to identify COMPHY related calls from SMC function ID */
+#define is_comphy_fid(fid) \
+ ((fid) >= MV_SIP_COMPHY_POWER_ON && (fid) <= MV_SIP_COMPHY_DIG_RESET)
+
+
+uintptr_t mrvl_sip_smc_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ u_register_t ret;
+ int i;
+
+ debug("%s: got SMC (0x%x) x1 0x%lx, x2 0x%lx, x3 0x%lx\n",
+ __func__, smc_fid, x1, x2, x3);
+ if (is_comphy_fid(smc_fid)) {
+
+ /* some systems passes SD phys address instead of COMPHY phys
+ * address - convert it
+ */
+ if (x1 & MVEBU_SD_OFFSET)
+ x1 = (x1 & ~0xffffff) + MVEBU_COMPHY_OFFSET;
+
+ if ((x1 & 0xffffff) != MVEBU_COMPHY_OFFSET) {
+ ERROR("%s: Wrong smc (0x%x) address: %lx\n",
+ __func__, smc_fid, x1);
+ SMC_RET1(handle, SMC_UNK);
+ }
+
+ if (x2 >= MAX_LANE_NR) {
+ ERROR("%s: Wrong smc (0x%x) lane nr: %lx\n",
+ __func__, smc_fid, x2);
+ SMC_RET1(handle, SMC_UNK);
+ }
+ }
+
+ switch (smc_fid) {
+
+ /* Comphy related FID's */
+ case MV_SIP_COMPHY_POWER_ON:
+ /* x1: comphy_base, x2: comphy_index, x3: comphy_mode */
+ ret = mvebu_cp110_comphy_power_on(x1, x2, x3);
+ SMC_RET1(handle, ret);
+ case MV_SIP_COMPHY_POWER_OFF:
+ /* x1: comphy_base, x2: comphy_index */
+ ret = mvebu_cp110_comphy_power_off(x1, x2);
+ SMC_RET1(handle, ret);
+ case MV_SIP_COMPHY_PLL_LOCK:
+ /* x1: comphy_base, x2: comphy_index */
+ ret = mvebu_cp110_comphy_is_pll_locked(x1, x2);
+ SMC_RET1(handle, ret);
+ case MV_SIP_COMPHY_XFI_TRAIN:
+ /* x1: comphy_base, x2: comphy_index */
+ ret = mvebu_cp110_comphy_xfi_rx_training(x1, x2);
+ SMC_RET1(handle, ret);
+ case MV_SIP_COMPHY_DIG_RESET:
+ /* x1: comphy_base, x2: comphy_index, x3: mode, x4: command */
+ ret = mvebu_cp110_comphy_digital_reset(x1, x2, x3, x4);
+ SMC_RET1(handle, ret);
+
+ /* Miscellaneous FID's' */
+ case MV_SIP_DRAM_SIZE:
+ /* x1: ap_base_addr */
+ ret = mvebu_get_dram_size(x1);
+ SMC_RET1(handle, ret);
+ case MV_SIP_LLC_ENABLE:
+ for (i = 0; i < ap_get_count(); i++)
+ llc_runtime_enable(i);
+
+ SMC_RET1(handle, 0);
+
+ default:
+ ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
+
+/* Define a runtime service descriptor for fast SMC calls */
+DECLARE_RT_SVC(
+ marvell_sip_svc,
+ OEN_SIP_START,
+ OEN_SIP_END,
+ SMC_TYPE_FAST,
+ NULL,
+ mrvl_sip_smc_handler
+);
diff --git a/plat/marvell/common/mss/mss_common.mk b/plat/marvell/common/mss/mss_common.mk
new file mode 100644
index 000000000..898b6dccc
--- /dev/null
+++ b/plat/marvell/common/mss/mss_common.mk
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+#
+
+
+PLAT_MARVELL := plat/marvell
+MSS_SOURCE := $(PLAT_MARVELL)/common/mss
+
+BL2_SOURCES += $(MSS_SOURCE)/mss_scp_bootloader.c \
+ $(PLAT_MARVELL)/common/plat_delay_timer.c \
+ drivers/delay_timer/delay_timer.c \
+ $(MARVELL_DRV) \
+ $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+
+BL31_SOURCES += $(MSS_SOURCE)/mss_ipc_drv.c
+
+PLAT_INCLUDES += -I$(MSS_SOURCE)
diff --git a/plat/marvell/common/mss/mss_ipc_drv.c b/plat/marvell/common/mss/mss_ipc_drv.c
new file mode 100644
index 000000000..731c315bf
--- /dev/null
+++ b/plat/marvell/common/mss/mss_ipc_drv.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <plat_marvell.h>
+#include <debug.h>
+#include <string.h>
+#include <mss_ipc_drv.h>
+#include <mmio.h>
+
+#define IPC_MSG_BASE_MASK MVEBU_REGS_BASE_MASK
+
+#define IPC_CH_NUM_OF_MSG (16)
+#define IPC_CH_MSG_IDX (-1)
+
+unsigned long mv_pm_ipc_msg_base;
+unsigned int mv_pm_ipc_queue_size;
+
+unsigned int msg_sync;
+int msg_index = IPC_CH_MSG_IDX;
+
+/******************************************************************************
+ * mss_pm_ipc_init
+ *
+ * DESCRIPTION: Initialize PM IPC infrastructure
+ ******************************************************************************
+ */
+int mv_pm_ipc_init(unsigned long ipc_control_addr)
+{
+ struct mss_pm_ipc_ctrl *ipc_control =
+ (struct mss_pm_ipc_ctrl *)ipc_control_addr;
+
+ /* Initialize PM IPC control block */
+ mv_pm_ipc_msg_base = ipc_control->msg_base_address |
+ IPC_MSG_BASE_MASK;
+ mv_pm_ipc_queue_size = ipc_control->queue_size;
+
+ return 0;
+}
+
+/******************************************************************************
+ * mv_pm_ipc_queue_addr_get
+ *
+ * DESCRIPTION: Returns the IPC queue address
+ ******************************************************************************
+ */
+unsigned int mv_pm_ipc_queue_addr_get(void)
+{
+ unsigned int addr;
+
+ inv_dcache_range((uint64_t)&msg_index, sizeof(msg_index));
+ msg_index = msg_index + 1;
+ if (msg_index >= IPC_CH_NUM_OF_MSG)
+ msg_index = 0;
+
+ addr = (unsigned int)(mv_pm_ipc_msg_base +
+ (msg_index * mv_pm_ipc_queue_size));
+
+ flush_dcache_range((uint64_t)&msg_index, sizeof(msg_index));
+
+ return addr;
+}
+
+/******************************************************************************
+ * mv_pm_ipc_msg_rx
+ *
+ * DESCRIPTION: Retrieve message from IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get();
+
+ msg->msg_reply = mmio_read_32(addr + IPC_MSG_REPLY_LOC);
+
+ return 0;
+}
+
+/******************************************************************************
+ * mv_pm_ipc_msg_tx
+ *
+ * DESCRIPTION: Send message via IPC channel
+ ******************************************************************************
+ */
+int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id,
+ unsigned int cluster_power_state)
+{
+ unsigned int addr = mv_pm_ipc_queue_addr_get();
+
+ /* Validate the entry for message placed by the host is free */
+ if (mmio_read_32(addr + IPC_MSG_STATE_LOC) == IPC_MSG_FREE) {
+ inv_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync));
+ msg_sync = msg_sync + 1;
+ flush_dcache_range((uint64_t)&msg_sync, sizeof(msg_sync));
+
+ mmio_write_32(addr + IPC_MSG_SYNC_ID_LOC, msg_sync);
+ mmio_write_32(addr + IPC_MSG_ID_LOC, msg_id);
+ mmio_write_32(addr + IPC_MSG_CPU_ID_LOC, channel_id);
+ mmio_write_32(addr + IPC_MSG_POWER_STATE_LOC,
+ cluster_power_state);
+ mmio_write_32(addr + IPC_MSG_STATE_LOC, IPC_MSG_OCCUPY);
+
+ } else {
+ ERROR("%s: FAILED\n", __func__);
+ }
+
+ return 0;
+}
diff --git a/plat/marvell/common/mss/mss_ipc_drv.h b/plat/marvell/common/mss/mss_ipc_drv.h
new file mode 100644
index 000000000..28eb907ea
--- /dev/null
+++ b/plat/marvell/common/mss/mss_ipc_drv.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __PM_IPC_DRV_H
+#define __PM_IPC_DRV_H
+
+#include <psci.h>
+
+#define MV_PM_FW_IPC_VERSION_MAGIC (0xCA530000) /* Do NOT change */
+/* Increament for each version */
+#define MV_PM_FW_IPC_VERSION_SEQ (0x00000001)
+#define MV_PM_FW_IPC_VERSION (MV_PM_FW_IPC_VERSION_MAGIC | \
+ MV_PM_FW_IPC_VERSION_SEQ)
+
+#define IPC_MSG_STATE_LOC (0x0)
+#define IPC_MSG_SYNC_ID_LOC (0x4)
+#define IPC_MSG_ID_LOC (0x8)
+#define IPC_MSG_RET_CH_ID_LOC (0xC)
+#define IPC_MSG_CPU_ID_LOC (0x10)
+#define IPC_MSG_CLUSTER_ID_LOC (0x14)
+#define IPC_MSG_SYSTEM_ID_LOC (0x18)
+#define IPC_MSG_POWER_STATE_LOC (0x1C)
+#define IPC_MSG_REPLY_LOC (0x20)
+#define IPC_MSG_RESERVED_LOC (0x24)
+
+/* IPC initialization state */
+enum mss_pm_ipc_init_state {
+ IPC_UN_INITIALIZED = 1,
+ IPC_INITIALIZED = 2
+};
+
+/* IPC queue direction */
+enum mss_pm_ipc_init_msg_dir {
+ IPC_MSG_TX = 0,
+ IPC_MSG_RX = 1
+};
+
+/* IPC message state */
+enum mss_pm_ipc_msg_state {
+ IPC_MSG_FREE = 1,
+ IPC_MSG_OCCUPY = 2
+
+};
+
+/* IPC control block */
+struct mss_pm_ipc_ctrl {
+ unsigned int ctrl_base_address;
+ unsigned int msg_base_address;
+ unsigned int num_of_channels;
+ unsigned int channel_size;
+ unsigned int queue_size;
+};
+
+/* IPC message types */
+enum mss_pm_msg_id {
+ PM_IPC_MSG_CPU_SUSPEND = 1,
+ PM_IPC_MSG_CPU_OFF = 2,
+ PM_IPC_MSG_CPU_ON = 3,
+ PM_IPC_MSG_SYSTEM_RESET = 4,
+ PM_IPC_MSG_SYSTEM_SUSPEND = 5,
+ PM_IPC_MAX_MSG
+};
+
+struct mss_pm_ipc_msg {
+ unsigned int msg_sync_id; /*
+ * Sync number, validate message
+ * reply corresponding to message
+ * received
+ */
+ unsigned int msg_id; /* Message Id */
+ unsigned int ret_channel_id; /* IPC channel reply */
+ unsigned int cpu_id; /* CPU Id */
+ unsigned int cluster_id; /* Cluster Id */
+ unsigned int system_id; /* System Id */
+ unsigned int power_state;
+ unsigned int msg_reply; /* Message reply */
+};
+
+/* IPC queue */
+struct mss_pm_ipc_queue {
+ unsigned int state;
+ struct mss_pm_ipc_msg msg;
+};
+
+/* IPC channel */
+struct mss_pm_ipc_ch {
+ struct mss_pm_ipc_queue *tx_queue;
+ struct mss_pm_ipc_queue *rx_queue;
+};
+
+/*****************************************************************************
+ * mv_pm_ipc_init
+ *
+ * DESCRIPTION: Initialize PM IPC infrastructure
+ *****************************************************************************
+ */
+int mv_pm_ipc_init(unsigned long ipc_control_addr);
+
+/*****************************************************************************
+ * mv_pm_ipc_msg_rx
+ *
+ * DESCRIPTION: Retrieve message from IPC channel
+ *****************************************************************************
+ */
+int mv_pm_ipc_msg_rx(unsigned int channel_id, struct mss_pm_ipc_msg *msg);
+
+/*****************************************************************************
+ * mv_pm_ipc_msg_tx
+ *
+ * DESCRIPTION: Send message via IPC channel
+ *****************************************************************************
+ */
+int mv_pm_ipc_msg_tx(unsigned int channel_id, unsigned int msg_id,
+ unsigned int cluster_power_state);
+
+#endif /* __PM_IPC_DRV_H */
diff --git a/plat/marvell/common/mss/mss_mem.h b/plat/marvell/common/mss/mss_mem.h
new file mode 100644
index 000000000..efff59e62
--- /dev/null
+++ b/plat/marvell/common/mss/mss_mem.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MSS_PM_MEM_H
+#define __MSS_PM_MEM_H
+
+/* MSS SRAM Memory base */
+#define MSS_SRAM_PM_CONTROL_BASE (MVEBU_REGS_BASE + 0x520000)
+
+enum mss_pm_ctrl_handshake {
+ MSS_UN_INITIALIZED = 0,
+ MSS_COMPATIBILITY_ERROR = 1,
+ MSS_ACKNOWLEDGMENT = 2,
+ HOST_ACKNOWLEDGMENT = 3
+};
+
+enum mss_pm_ctrl_rtos_env {
+ MSS_MULTI_PROCESS_ENV = 0,
+ MSS_SINGLE_PROCESS_ENV = 1,
+ MSS_MAX_PROCESS_ENV
+};
+
+struct mss_pm_ctrl_block {
+ /* This field is used to synchronize the Host
+ * and MSS initialization sequence
+ * Valid Values
+ * 0 - Un-Initialized
+ * 1 - Compatibility Error
+ * 2 - MSS Acknowledgment
+ * 3 - Host Acknowledgment
+ */
+ unsigned int handshake;
+
+ /*
+ * This field include Host IPC version. Once received by the MSS
+ * It will be compared to MSS IPC version and set MSS Acknowledge to
+ * "compatibility error" in case there is no match
+ */
+ unsigned int ipc_version;
+ unsigned int ipc_base_address;
+ unsigned int ipc_state;
+
+ /* Following fields defines firmware core architecture */
+ unsigned int num_of_cores;
+ unsigned int num_of_clusters;
+ unsigned int num_of_cores_per_cluster;
+
+ /* Following fields define pm trace debug base address */
+ unsigned int pm_trace_ctrl_base_address;
+ unsigned int pm_trace_info_base_address;
+ unsigned int pm_trace_info_core_size;
+
+ unsigned int ctrl_blk_size;
+};
+
+#endif /* __MSS_PM_MEM_H */
diff --git a/plat/marvell/common/mss/mss_scp_bl2_format.h b/plat/marvell/common/mss/mss_scp_bl2_format.h
new file mode 100644
index 000000000..c04df727a
--- /dev/null
+++ b/plat/marvell/common/mss/mss_scp_bl2_format.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MSS_SCP_BL2_FORMAT_H
+#define __MSS_SCP_BL2_FORMAT_H
+
+#define MAX_NR_OF_FILES 5
+#define FILE_MAGIC 0xddd01ff
+#define HEADER_VERSION 0x1
+
+#define MSS_IDRAM_SIZE 0x10000 /* 64KB */
+#define MG_SRAM_SIZE 0x20000 /* 128KB */
+
+/* Types definitions */
+typedef struct file_header {
+ /* Magic specific for concatenated file (used for validation) */
+ uint32_t magic;
+ uint32_t nr_of_imgs; /* Number of images concatenated */
+} file_header_t;
+
+/* Types definitions */
+enum cm3_t {
+ MSS_AP,
+ MSS_CP0,
+ MSS_CP1,
+ MSS_CP2,
+ MSS_CP3,
+ MG_CP0,
+ MG_CP1,
+};
+
+typedef struct img_header {
+ uint32_t type; /* CM3 type, can be one of cm3_t */
+ uint32_t length; /* Image length */
+ uint32_t version; /* For sanity checks and future
+ * extended functionality
+ */
+} img_header_t;
+
+#endif /* __MSS_SCP_BL2_FORMAT_H */
diff --git a/plat/marvell/common/mss/mss_scp_bootloader.c b/plat/marvell/common/mss/mss_scp_bootloader.c
new file mode 100644
index 000000000..334fcfc61
--- /dev/null
+++ b/plat/marvell/common/mss/mss_scp_bootloader.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <mmio.h>
+#include <arch_helpers.h> /* for cache maintanance operations */
+#include <platform_def.h>
+#include <delay_timer.h>
+
+#include <plat_pm_trace.h>
+#include <mss_scp_bootloader.h>
+#include <mss_ipc_drv.h>
+#include <mss_mem.h>
+#include <mss_scp_bl2_format.h>
+
+#define MSS_DMA_SRCBR(base) (base + 0xC0)
+#define MSS_DMA_DSTBR(base) (base + 0xC4)
+#define MSS_DMA_CTRLR(base) (base + 0xC8)
+#define MSS_M3_RSTCR(base) (base + 0xFC)
+
+#define MSS_DMA_CTRLR_SIZE_OFFSET (0)
+#define MSS_DMA_CTRLR_REQ_OFFSET (15)
+#define MSS_DMA_CTRLR_REQ_SET (1)
+#define MSS_DMA_CTRLR_ACK_OFFSET (12)
+#define MSS_DMA_CTRLR_ACK_MASK (0x1)
+#define MSS_DMA_CTRLR_ACK_READY (1)
+#define MSS_M3_RSTCR_RST_OFFSET (0)
+#define MSS_M3_RSTCR_RST_OFF (1)
+
+#define MSS_DMA_TIMEOUT 1000
+#define MSS_EXTERNAL_SPACE 0x50000000
+#define MSS_EXTERNAL_ADDR_MASK 0xfffffff
+
+#define DMA_SIZE 128
+
+#define MSS_HANDSHAKE_TIMEOUT 50
+
+static int mss_check_image_ready(volatile struct mss_pm_ctrl_block *mss_pm_crtl)
+{
+ int timeout = MSS_HANDSHAKE_TIMEOUT;
+
+ /* Wait for SCP to signal it's ready */
+ while ((mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT) &&
+ (timeout-- > 0))
+ mdelay(1);
+
+ if (mss_pm_crtl->handshake != MSS_ACKNOWLEDGMENT)
+ return -1;
+
+ mss_pm_crtl->handshake = HOST_ACKNOWLEDGMENT;
+
+ return 0;
+}
+
+static int mss_image_load(uint32_t src_addr, uint32_t size, uintptr_t mss_regs)
+{
+ uint32_t i, loop_num, timeout;
+
+ /* Check if the img size is not bigger than ID-RAM size of MSS CM3 */
+ if (size > MSS_IDRAM_SIZE) {
+ ERROR("image is too big to fit into MSS CM3 memory\n");
+ return 1;
+ }
+
+ NOTICE("Loading MSS image from addr. 0x%x Size 0x%x to MSS at 0x%lx\n",
+ src_addr, size, mss_regs);
+ /* load image to MSS RAM using DMA */
+ loop_num = (size / DMA_SIZE) + (((size & (DMA_SIZE - 1)) == 0) ? 0 : 1);
+
+ for (i = 0; i < loop_num; i++) {
+ /* write destination and source addresses */
+ mmio_write_32(MSS_DMA_SRCBR(mss_regs),
+ MSS_EXTERNAL_SPACE |
+ ((src_addr & MSS_EXTERNAL_ADDR_MASK) +
+ (i * DMA_SIZE)));
+ mmio_write_32(MSS_DMA_DSTBR(mss_regs), (i * DMA_SIZE));
+
+ dsb(); /* make sure DMA data is ready before triggering it */
+
+ /* set the DMA control register */
+ mmio_write_32(MSS_DMA_CTRLR(mss_regs), ((MSS_DMA_CTRLR_REQ_SET
+ << MSS_DMA_CTRLR_REQ_OFFSET) |
+ (DMA_SIZE << MSS_DMA_CTRLR_SIZE_OFFSET)));
+
+ /* Poll DMA_ACK at MSS_DMACTLR until it is ready */
+ timeout = MSS_DMA_TIMEOUT;
+ while (timeout) {
+ if ((mmio_read_32(MSS_DMA_CTRLR(mss_regs)) >>
+ MSS_DMA_CTRLR_ACK_OFFSET & MSS_DMA_CTRLR_ACK_MASK)
+ == MSS_DMA_CTRLR_ACK_READY) {
+ break;
+ }
+
+ udelay(50);
+ timeout--;
+ }
+
+ if (timeout == 0) {
+ ERROR("\nDMA failed to load MSS image\n");
+ return 1;
+ }
+ }
+
+ bl2_plat_configure_mss_windows(mss_regs);
+
+ /* Release M3 from reset */
+ mmio_write_32(MSS_M3_RSTCR(mss_regs), (MSS_M3_RSTCR_RST_OFF <<
+ MSS_M3_RSTCR_RST_OFFSET));
+
+ NOTICE("Done\n");
+
+ return 0;
+}
+
+/* Load image to MSS AP and do PM related initialization
+ * Note that this routine is different than other CM3 loading routines, because
+ * firmware for AP is dedicated for PM and therefore some additional PM
+ * initialization is required
+ */
+static int mss_ap_load_image(uintptr_t single_img,
+ uint32_t image_size, uint32_t ap_idx)
+{
+ volatile struct mss_pm_ctrl_block *mss_pm_crtl;
+ int ret;
+
+ /* TODO: add PM Control Info from platform */
+ mss_pm_crtl = (struct mss_pm_ctrl_block *)MSS_SRAM_PM_CONTROL_BASE;
+ mss_pm_crtl->ipc_version = MV_PM_FW_IPC_VERSION;
+ mss_pm_crtl->num_of_clusters = PLAT_MARVELL_CLUSTER_COUNT;
+ mss_pm_crtl->num_of_cores_per_cluster =
+ PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ mss_pm_crtl->num_of_cores = PLAT_MARVELL_CLUSTER_COUNT *
+ PLAT_MARVELL_CLUSTER_CORE_COUNT;
+ mss_pm_crtl->pm_trace_ctrl_base_address = AP_MSS_ATF_CORE_CTRL_BASE;
+ mss_pm_crtl->pm_trace_info_base_address = AP_MSS_ATF_CORE_INFO_BASE;
+ mss_pm_crtl->pm_trace_info_core_size = AP_MSS_ATF_CORE_INFO_SIZE;
+ VERBOSE("MSS Control Block = 0x%x\n", MSS_SRAM_PM_CONTROL_BASE);
+ VERBOSE("mss_pm_crtl->ipc_version = 0x%x\n",
+ mss_pm_crtl->ipc_version);
+ VERBOSE("mss_pm_crtl->num_of_cores = 0x%x\n",
+ mss_pm_crtl->num_of_cores);
+ VERBOSE("mss_pm_crtl->num_of_clusters = 0x%x\n",
+ mss_pm_crtl->num_of_clusters);
+ VERBOSE("mss_pm_crtl->num_of_cores_per_cluster = 0x%x\n",
+ mss_pm_crtl->num_of_cores_per_cluster);
+ VERBOSE("mss_pm_crtl->pm_trace_ctrl_base_address = 0x%x\n",
+ mss_pm_crtl->pm_trace_ctrl_base_address);
+ VERBOSE("mss_pm_crtl->pm_trace_info_base_address = 0x%x\n",
+ mss_pm_crtl->pm_trace_info_base_address);
+ VERBOSE("mss_pm_crtl->pm_trace_info_core_size = 0x%x\n",
+ mss_pm_crtl->pm_trace_info_core_size);
+
+ /* TODO: add checksum to image */
+ VERBOSE("Send info about the SCP_BL2 image to be transferred to SCP\n");
+
+ ret = mss_image_load(single_img, image_size,
+ bl2_plat_get_ap_mss_regs(ap_idx));
+ if (ret != 0) {
+ ERROR("SCP Image load failed\n");
+ return -1;
+ }
+
+ /* check that the image was loaded successfully */
+ ret = mss_check_image_ready(mss_pm_crtl);
+ if (ret != 0)
+ NOTICE("SCP Image doesn't contain PM firmware\n");
+
+ return 0;
+}
+
+/* Load CM3 image (single_img) to CM3 pointed by cm3_type */
+static int load_img_to_cm3(enum cm3_t cm3_type,
+ uintptr_t single_img, uint32_t image_size)
+{
+ int ret, ap_idx, cp_index;
+ uint32_t ap_count = bl2_plat_get_ap_count();
+
+ switch (cm3_type) {
+ case MSS_AP:
+ for (ap_idx = 0; ap_idx < ap_count; ap_idx++) {
+ NOTICE("Load image to AP%d MSS\n", ap_idx);
+ ret = mss_ap_load_image(single_img, image_size, ap_idx);
+ if (ret != 0)
+ return ret;
+ }
+ break;
+ case MSS_CP0:
+ case MSS_CP1:
+ case MSS_CP2:
+ case MSS_CP3:
+ /* MSS_AP = 0
+ * MSS_CP1 = 1
+ * .
+ * .
+ * MSS_CP3 = 4
+ * Actual CP index is MSS_CPX - 1
+ */
+ cp_index = cm3_type - 1;
+ for (ap_idx = 0; ap_idx < ap_count; ap_idx++) {
+ /* Check if we should load this image
+ * according to number of CPs
+ */
+ if (bl2_plat_get_cp_count(ap_idx) <= cp_index) {
+ NOTICE("Skipping MSS CP%d related image\n",
+ cp_index);
+ break;
+ }
+
+ NOTICE("Load image to CP%d MSS AP%d\n",
+ cp_index, ap_idx);
+ ret = mss_image_load(single_img, image_size,
+ bl2_plat_get_cp_mss_regs(
+ ap_idx, cp_index));
+ if (ret != 0) {
+ ERROR("SCP Image load failed\n");
+ return -1;
+ }
+ }
+ break;
+ case MG_CP0:
+ /* TODO: */
+ NOTICE("Load image to CP0 MG not supported\n");
+ break;
+ case MG_CP1:
+ /* TODO: */
+ NOTICE("Load image to CP1 MG not supported\n");
+ break;
+ default:
+ ERROR("SCP_BL2 wrong img format (cm3_type=%d)\n", cm3_type);
+ break;
+ }
+
+ return 0;
+}
+
+/* The Armada 8K has 5 service CPUs and Armada 7K has 3. Therefore it was
+ * required to provide a method for loading firmware to all of the service CPUs.
+ * To achieve that, the scp_bl2 image in fact is file containing up to 5
+ * concatenated firmwares and this routine splits concatenated image into single
+ * images dedicated for appropriate service CPU and then load them.
+ */
+static int split_and_load_bl2_image(void *image)
+{
+ file_header_t *file_hdr;
+ img_header_t *img_hdr;
+ uintptr_t single_img;
+ int i;
+
+ file_hdr = (file_header_t *)image;
+
+ if (file_hdr->magic != FILE_MAGIC) {
+ ERROR("SCP_BL2 wrong img format\n");
+ return -1;
+ }
+
+ if (file_hdr->nr_of_imgs > MAX_NR_OF_FILES) {
+ ERROR("SCP_BL2 concatenated image contains to many images\n");
+ return -1;
+ }
+
+ img_hdr = (img_header_t *)((uintptr_t)image + sizeof(file_header_t));
+ single_img = (uintptr_t)image + sizeof(file_header_t) +
+ sizeof(img_header_t) * file_hdr->nr_of_imgs;
+
+ NOTICE("SCP_BL2 contains %d concatenated images\n",
+ file_hdr->nr_of_imgs);
+ for (i = 0; i < file_hdr->nr_of_imgs; i++) {
+
+ /* Before loading make sanity check on header */
+ if (img_hdr->version != HEADER_VERSION) {
+ ERROR("Wrong header, img corrupted exiting\n");
+ return -1;
+ }
+
+ load_img_to_cm3(img_hdr->type, single_img, img_hdr->length);
+
+ /* Prepare offsets for next run */
+ single_img += img_hdr->length;
+ img_hdr++;
+ }
+
+ return 0;
+}
+
+int scp_bootloader_transfer(void *image, unsigned int image_size)
+{
+#ifdef SCP_BL2_BASE
+ assert((uintptr_t) image == SCP_BL2_BASE);
+#endif
+
+ VERBOSE("Concatenated img size %d\n", image_size);
+
+ if (image_size == 0) {
+ ERROR("SCP_BL2 image size can't be 0 (current size = 0x%x)\n",
+ image_size);
+ return -1;
+ }
+
+ if (split_and_load_bl2_image(image))
+ return -1;
+
+ return 0;
+}
diff --git a/plat/marvell/common/mss/mss_scp_bootloader.h b/plat/marvell/common/mss/mss_scp_bootloader.h
new file mode 100644
index 000000000..67c387a03
--- /dev/null
+++ b/plat/marvell/common/mss/mss_scp_bootloader.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __MSS_SCP_BOOTLOADER_H__
+#define __MSS_SCP_BOOTLOADER_H__
+
+int scp_bootloader_transfer(void *image, unsigned int image_size);
+uintptr_t bl2_plat_get_cp_mss_regs(int ap_idx, int cp_idx);
+uintptr_t bl2_plat_get_ap_mss_regs(int ap_idx);
+uint32_t bl2_plat_get_cp_count(int ap_idx);
+uint32_t bl2_plat_get_ap_count(void);
+void bl2_plat_configure_mss_windows(uintptr_t mss_regs);
+int bl2_plat_mss_check_image_ready(void);
+
+#endif /* __MSS_SCP_BOOTLOADER_H__ */
diff --git a/plat/marvell/common/plat_delay_timer.c b/plat/marvell/common/plat_delay_timer.c
new file mode 100644
index 000000000..dfc77c7fe
--- /dev/null
+++ b/plat/marvell/common/plat_delay_timer.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <arch_helpers.h>
+#include <delay_timer.h>
+#include <mvebu_def.h>
+
+#define SYS_COUNTER_FREQ_IN_MHZ (COUNTER_FREQUENCY/1000000)
+
+static uint32_t plat_get_timer_value(void)
+{
+ /*
+ * Generic delay timer implementation expects the timer to be a down
+ * counter. We apply bitwise NOT operator to the tick values returned
+ * by read_cntpct_el0() to simulate the down counter.
+ */
+ return (uint32_t)(~read_cntpct_el0());
+}
+
+static const timer_ops_t plat_timer_ops = {
+ .get_timer_value = plat_get_timer_value,
+ .clk_mult = 1,
+ .clk_div = SYS_COUNTER_FREQ_IN_MHZ
+};
+
+void plat_delay_timer_init(void)
+{
+ timer_init(&plat_timer_ops);
+}
diff --git a/plat/marvell/marvell.mk b/plat/marvell/marvell.mk
new file mode 100644
index 000000000..217ad46f0
--- /dev/null
+++ b/plat/marvell/marvell.mk
@@ -0,0 +1,53 @@
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+
+# Marvell images
+BOOT_IMAGE := boot-image.bin
+BOOT_ENC_IMAGE := boot-image-enc.bin
+FLASH_IMAGE := flash-image.bin
+
+# Make non-trusted image by default
+MARVELL_SECURE_BOOT := 0
+$(eval $(call add_define,MARVELL_SECURE_BOOT))
+
+# Enable compilation for Palladium emulation platform
+PALLADIUM := 0
+$(eval $(call add_define,PALLADIUM))
+
+ifeq (${MARVELL_SECURE_BOOT},1)
+DOIMAGE_SEC_FLAGS := -c $(DOIMAGE_SEC)
+DOIMAGE_LIBS_CHECK = \
+ if ! [ -d "/usr/include/mbedtls" ]; then \
+ echo "****************************************" >&2; \
+ echo "Missing mbedTLS installation! " >&2; \
+ echo "Please download it from \"tls.mbed.org\"" >&2; \
+ echo "Alternatively on Debian/Ubuntu system install" >&2; \
+ echo "\"libmbedtls-dev\" package" >&2; \
+ echo "Make sure to use version 2.1.0 or later" >&2; \
+ echo "****************************************" >&2; \
+ exit 1; \
+ else if ! [ -f "/usr/include/libconfig.h" ]; then \
+ echo "********************************************************" >&2; \
+ echo "Missing Libconfig installation!" >&2; \
+ echo "Please download it from \"www.hyperrealm.com/libconfig/\"" >&2; \
+ echo "Alternatively on Debian/Ubuntu system install packages" >&2; \
+ echo "\"libconfig8\" and \"libconfig8-dev\"" >&2; \
+ echo "********************************************************" >&2; \
+ exit 1; \
+ fi \
+ fi
+else #MARVELL_SECURE_BOOT
+DOIMAGE_LIBS_CHECK =
+DOIMAGE_SEC_FLAGS =
+endif #MARVELL_SECURE_BOOT
+
+mrvl_clean:
+ @echo " Doimage CLEAN"
+ ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${DOIMAGEPATH} clean
+
+${DOIMAGETOOL}: mrvl_clean
+ ${Q}${MAKE} --no-print-directory -C ${DOIMAGEPATH} WTMI_IMG=$(WTMI_IMG)
+
+
diff --git a/plat/marvell/version.mk b/plat/marvell/version.mk
new file mode 100644
index 000000000..017e11988
--- /dev/null
+++ b/plat/marvell/version.mk
@@ -0,0 +1 @@
+SUBVERSION = devel-18.08.0
diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h
index 6c64ba5de..0fa63a1a6 100644
--- a/plat/mediatek/mt6795/include/platform_def.h
+++ b/plat/mediatek/mt6795/include/platform_def.h
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <utils_def.h>
#define PLAT_PRIMARY_CPU 0x0
@@ -146,7 +148,7 @@
#if ENABLE_PLAT_COMPAT
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
#else
-#define PLAT_MAX_PWR_LVL 2 /* MPIDR_AFFLVL2 */
+#define PLAT_MAX_PWR_LVL U(2) /* MPIDR_AFFLVL2 */
#endif
#define PLATFORM_CACHE_LINE_SIZE 64
@@ -239,4 +241,4 @@
#define PAGE_SIZE_2MB (1 << PAGE_SIZE_2MB_SHIFT)
#define PAGE_SIZE_2MB_SHIFT TWO_MB_SHIFT
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt6795/power_tracer.c b/plat/mediatek/mt6795/power_tracer.c
index f5208d09a..56e22402f 100644
--- a/plat/mediatek/mt6795/power_tracer.c
+++ b/plat/mediatek/mt6795/power_tracer.c
@@ -14,30 +14,30 @@ void trace_power_flow(unsigned long mpidr, unsigned char mode)
{
switch (mode) {
case CPU_UP:
- trace_log("core %ld:%ld ON\n",
+ trace_log("core %lld:%lld ON\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CPU_DOWN:
- trace_log("core %ld:%ld OFF\n",
+ trace_log("core %lld:%lld OFF\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CPU_SUSPEND:
- trace_log("core %ld:%ld SUSPEND\n",
+ trace_log("core %lld:%lld SUSPEND\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CLUSTER_UP:
- trace_log("cluster %ld ON\n",
+ trace_log("cluster %lld ON\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
case CLUSTER_DOWN:
- trace_log("cluster %ld OFF\n",
+ trace_log("cluster %lld OFF\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
case CLUSTER_SUSPEND:
- trace_log("cluster %ld SUSPEND\n",
+ trace_log("cluster %lld SUSPEND\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
default:
diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h
index 5e79df2d7..6e3f4a3b4 100644
--- a/plat/mediatek/mt8173/include/platform_def.h
+++ b/plat/mediatek/mt8173/include/platform_def.h
@@ -1,17 +1,17 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <gic_common.h>
#include <interrupt_props.h>
+#include <utils_def.h>
#include "mt8173_def.h"
-
/*******************************************************************************
* Platform binary types for linking
******************************************************************************/
@@ -37,9 +37,9 @@
#define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2
#if !ENABLE_PLAT_COMPAT
-#define PLAT_MAX_PWR_LVL 2
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_PWR_LVL U(2)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
#endif
#define PLATFORM_SYSTEM_COUNT 1
#define PLATFORM_CLUSTER_COUNT 2
@@ -137,4 +137,4 @@
#define PLAT_ARM_G0_IRQ_PROPS(grp)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8173/power_tracer.c b/plat/mediatek/mt8173/power_tracer.c
index 5c0a468d7..787dad13f 100644
--- a/plat/mediatek/mt8173/power_tracer.c
+++ b/plat/mediatek/mt8173/power_tracer.c
@@ -14,30 +14,30 @@ void trace_power_flow(unsigned long mpidr, unsigned char mode)
{
switch (mode) {
case CPU_UP:
- trace_log("core %ld:%ld ON\n",
+ trace_log("core %lld:%lld ON\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CPU_DOWN:
- trace_log("core %ld:%ld OFF\n",
+ trace_log("core %lld:%lld OFF\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CPU_SUSPEND:
- trace_log("core %ld:%ld SUSPEND\n",
+ trace_log("core %lld:%lld SUSPEND\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS,
(mpidr & MPIDR_CPU_MASK));
break;
case CLUSTER_UP:
- trace_log("cluster %ld ON\n",
+ trace_log("cluster %lld ON\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
case CLUSTER_DOWN:
- trace_log("cluster %ld OFF\n",
+ trace_log("cluster %lld OFF\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
case CLUSTER_SUSPEND:
- trace_log("cluster %ld SUSPEND\n",
+ trace_log("cluster %lld SUSPEND\n",
(mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS);
break;
default:
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index fa3f0002a..4b9edb622 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,6 +12,8 @@
#include <string.h>
#include <tegra_private.h>
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
/* SMMU IDs currently supported by the driver */
enum {
TEGRA_SMMU0,
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 2fe4e7dbc..65997687f 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -28,6 +28,7 @@
/* length of Trusty's input parameters (in bytes) */
#define TRUSTY_PARAMS_LEN_BYTES (4096*2)
+extern void memcpy16(void *dest, const void *src, unsigned int length);
extern void zeromem16(void *mem, unsigned int length);
/*******************************************************************************
@@ -116,9 +117,6 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
{
plat_params_from_bl2_t *plat_params =
(plat_params_from_bl2_t *)plat_params_from_bl2;
-#if LOG_LEVEL >= LOG_LEVEL_INFO
- int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
-#endif
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
@@ -227,8 +225,9 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
/* Early platform setup for Tegra SoCs */
plat_early_platform_setup();
- INFO("BL3-1: Boot CPU: %s Processor [%lx]\n", (impl == DENVER_IMPL) ?
- "Denver" : "ARM", read_mpidr());
+ INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
+ (((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
+ == DENVER_IMPL) ? "Denver" : "ARM", read_mpidr());
}
#ifdef SPD_trusty
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 60c8a0405..b72653e49 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,7 +11,7 @@
#ifndef __ASSEMBLY__
-#include <sys/types.h>
+#include <stdint.h>
/*******************************************************************************
* StreamID to indicate no SMMU translations (requests to be steered on the
diff --git a/plat/nvidia/tegra/include/tegra_platform.h b/plat/nvidia/tegra/include/tegra_platform.h
index fbaad6e75..db79fbe21 100644
--- a/plat/nvidia/tegra/include/tegra_platform.h
+++ b/plat/nvidia/tegra/include/tegra_platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,7 +7,7 @@
#ifndef __TEGRA_PLATFORM_H__
#define __TEGRA_PLATFORM_H__
-#include <sys/cdefs.h>
+#include <cdefs.h>
/*
* Tegra chip major/minor version
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 7eb6c6c81..7126c3ba7 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,10 +10,10 @@
#include <debug.h>
#include <delay_timer.h>
#include <denver.h>
+#include <errno.h>
#include <mce_private.h>
#include <mmio.h>
#include <platform.h>
-#include <sys/errno.h>
#include <t18x_ari.h>
/*******************************************************************************
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
index 1353b6ab5..712519f9f 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,11 +12,11 @@
#include <context_mgmt.h>
#include <debug.h>
#include <denver.h>
+#include <errno.h>
#include <mce.h>
#include <mce_private.h>
#include <mmio.h>
#include <string.h>
-#include <sys/errno.h>
#include <t18x_ari.h>
#include <tegra_def.h>
#include <tegra_platform.h>
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
index 243c8f3a3..857cfbb53 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/nvg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,9 +8,9 @@
#include <arch_helpers.h>
#include <debug.h>
#include <denver.h>
+#include <errno.h>
#include <mce_private.h>
#include <mmio.h>
-#include <sys/errno.h>
#include <t18x_ari.h>
int32_t nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time)
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 095614e42..6eb18fa6c 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,6 +20,8 @@
#include <t18x_ari.h>
#include <tegra_private.h>
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
extern void prepare_cpu_pwr_dwn(void);
extern void tegra186_cpu_reset_handler(void);
extern uint32_t __tegra186_cpu_reset_handler_end,
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 52daab21d..ebc2b46a2 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,8 @@
#define CPU_RESET_MODE_AA64 1
+extern void memcpy16(void *dest, const void *src, unsigned int length);
+
extern uint64_t tegra_bl31_phys_base;
extern uint64_t __tegra186_cpu_reset_handler_end;
diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/include/platform_def.h
index 2f2ca6f1e..55252c380 100644
--- a/plat/qemu/include/platform_def.h
+++ b/plat/qemu/include/platform_def.h
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <common_def.h>
#include <tbbr_img_def.h>
+#include <utils_def.h>
/* Special value used to verify platform parameters from BL2 to BL3-1 */
#define QEMU_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL
@@ -36,13 +37,13 @@
PLATFORM_CORE_COUNT)
#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
/* Local power state for power domains in Run state. */
-#define PLAT_LOCAL_STATE_RUN 0
+#define PLAT_LOCAL_STATE_RUN U(0)
/* Local power state for retention. Valid only for CPU power domains */
-#define PLAT_LOCAL_STATE_RET 1
+#define PLAT_LOCAL_STATE_RET U(1)
/*
* Local power state for OFF/power-down. Valid for CPU and cluster power
* domains.
@@ -229,4 +230,4 @@
*/
#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/platform.mk b/plat/qemu/platform.mk
index 379ab3dca..1d46eeccd 100644
--- a/plat/qemu/platform.mk
+++ b/plat/qemu/platform.mk
@@ -132,8 +132,7 @@ BL2_SOURCES += drivers/io/io_semihosting.c \
plat/qemu/qemu_io_storage.c \
plat/qemu/${ARCH}/plat_helpers.S \
plat/qemu/qemu_bl2_setup.c \
- plat/qemu/dt.c \
- $(LIBFDT_SRCS)
+ plat/qemu/dt.c
ifeq (${LOAD_IMAGE_V2},1)
BL2_SOURCES += plat/qemu/qemu_bl2_mem_params_desc.c \
plat/qemu/qemu_image_load.c \
diff --git a/plat/qemu/qemu_private.h b/plat/qemu/qemu_private.h
index 800fa037f..0fb7cd5fd 100644
--- a/plat/qemu/qemu_private.h
+++ b/plat/qemu/qemu_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,9 +7,8 @@
#ifndef __QEMU_PRIVATE_H
#define __QEMU_PRIVATE_H
-#include <sys/types.h>
+#include <stdint.h>
-#include <xlat_tables_defs.h>
#include "../../bl1/bl1_private.h"
void qemu_configure_mmu_secure(unsigned long total_base,
diff --git a/plat/qemu/topology.c b/plat/qemu/topology.c
index d7ba9b7e0..569d15f8c 100644
--- a/plat/qemu/topology.c
+++ b/plat/qemu/topology.c
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include "qemu_private.h"
/* The power domain tree descriptor */
diff --git a/plat/rockchip/common/aarch64/plat_helpers.S b/plat/rockchip/common/aarch64/plat_helpers.S
index f415f8772..f0136b0d9 100644
--- a/plat/rockchip/common/aarch64/plat_helpers.S
+++ b/plat/rockchip/common/aarch64/plat_helpers.S
@@ -18,7 +18,7 @@
.globl platform_cpu_warmboot
.globl plat_secondary_cold_boot_setup
.globl plat_report_exception
- .globl platform_is_primary_cpu
+ .globl plat_is_my_cpu_primary
.globl plat_my_core_pos
.globl plat_reset_handler
.globl plat_panic_handler
@@ -73,12 +73,13 @@ cb_panic:
b cb_panic
endfunc plat_secondary_cold_boot_setup
-func platform_is_primary_cpu
+func plat_is_my_cpu_primary
+ mrs x0, mpidr_el1
and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
cmp x0, #PLAT_RK_PRIMARY_CPU
cset x0, eq
ret
-endfunc platform_is_primary_cpu
+endfunc plat_is_my_cpu_primary
/* --------------------------------------------------------------------
* void plat_panic_handler(void)
diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h
index 019f4e148..56d51ee30 100644
--- a/plat/rockchip/rk3328/include/platform_def.h
+++ b/plat/rockchip/rk3328/include/platform_def.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <common_def.h>
@@ -58,13 +58,13 @@
* This macro defines the deepest retention state possible. A higher state
* id will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE U(1)
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE U(2)
/*******************************************************************************
* Platform memory map related constants
@@ -123,4 +123,4 @@
#define PSRAM_DO_DDR_RESUME 0
#define PSRAM_CHECK_WAKEUP_CPU 0
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index a61663c4d..d9a80a7af 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <common_def.h>
#include <rk3368_def.h>
+#include <utils_def.h>
#define DEBUG_XLAT_TABLE 0
@@ -58,13 +59,13 @@
* This macro defines the deepest retention state possible. A higher state
* id will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE U(1)
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE U(2)
/*******************************************************************************
* Platform memory map related constants
@@ -125,4 +126,4 @@
#define PSRAM_DO_DDR_RESUME 0
#define PSRAM_CHECK_WAKEUP_CPU 0
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
index f1a5e2b7a..2adab8fbf 100644
--- a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
+++ b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <cdefs.h>
#include <cdn_dp.h>
#include <smccc.h>
#include <stdlib.h>
diff --git a/plat/rockchip/rk3399/include/platform_def.h b/plat/rockchip/rk3399/include/platform_def.h
index 7139b41e9..26204a116 100644
--- a/plat/rockchip/rk3399/include/platform_def.h
+++ b/plat/rockchip/rk3399/include/platform_def.h
@@ -1,16 +1,17 @@
/*
- * Copyright (c) 2014-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <bl31_param.h>
#include <common_def.h>
#include <rk3399_def.h>
+#include <utils_def.h>
#define DEBUG_XLAT_TABLE 0
@@ -57,13 +58,13 @@
* This macro defines the deepest retention state possible. A higher state
* id will represent an invalid or a power down state.
*/
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_RET_STATE U(1)
/*
* This macro defines the deepest power down states possible. Any state ID
* higher than this is invalid.
*/
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_OFF_STATE U(2)
/*******************************************************************************
* Platform specific page table and MMU setup constants
@@ -110,4 +111,4 @@
#define PSRAM_DO_DDR_RESUME 1
#define PSRAM_CHECK_WAKEUP_CPU 0
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/rpi3/aarch64/plat_helpers.S b/plat/rpi3/aarch64/plat_helpers.S
index 65c1bf2d4..7974b602d 100644
--- a/plat/rpi3/aarch64/plat_helpers.S
+++ b/plat/rpi3/aarch64/plat_helpers.S
@@ -175,9 +175,5 @@ func plat_reset_handler
mov w1, #0x80000000
str wzr, [x0, #RPI3_INTC_CONTROL_OFFSET]
str w1, [x0, #RPI3_INTC_PRESCALER_OFFSET]
-
- /* wire mailbox 3 to the FIQ line */
- mov w1, RPI3_INTC_MBOX_CONTROL_SLOT3_FIQ
- str w1, [x0, #RPI3_INTC_MBOX_CONTROL_OFFSET]
ret
endfunc plat_reset_handler
diff --git a/plat/rpi3/include/plat_macros.S b/plat/rpi3/include/plat_macros.S
index f5e057ede..c0c396791 100644
--- a/plat/rpi3/include/plat_macros.S
+++ b/plat/rpi3/include/plat_macros.S
@@ -1,13 +1,10 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLAT_MACROS_S__
-#define __PLAT_MACROS_S__
-
-#include <arm_macros.S>
-#include <platform_def.h>
+#ifndef PLAT_MACROS_S
+#define PLAT_MACROS_S
/* ---------------------------------------------
* The below required platform porting macro
@@ -20,4 +17,4 @@
.macro plat_crash_print_regs
.endm
-#endif /* __PLAT_MACROS_S__ */
+#endif /* PLAT_MACROS_S */
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 5b84aa617..76a5ff440 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -70,17 +70,17 @@
#define PLAT_RPI3_FIP_BASE ULL(0x00020000)
#define PLAT_RPI3_FIP_MAX_SIZE ULL(0x001E0000)
-/* We have 16M of memory reserved at at 256M */
+/* We have 16M of memory reserved starting at 256M */
#define SEC_SRAM_BASE ULL(0x10000000)
#define SEC_SRAM_SIZE ULL(0x00100000)
#define SEC_DRAM0_BASE ULL(0x10100000)
-#define SEC_DRAM0_SIZE ULL(0x00B00000)
-
-#define NS_DRAM0_BASE ULL(0x10C00000)
-#define NS_DRAM0_SIZE ULL(0x00400000)
+#define SEC_DRAM0_SIZE ULL(0x00F00000)
/* End of reserved memory */
+#define NS_DRAM0_BASE ULL(0x11000000)
+#define NS_DRAM0_SIZE ULL(0x01000000)
+
/*
* BL33 entrypoint.
*/
@@ -117,9 +117,11 @@
*/
#define PLAT_RPI3_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE
+/* The secure entry point to be used on warm reset by all CPUs. */
#define PLAT_RPI3_TM_ENTRYPOINT PLAT_RPI3_TRUSTED_MAILBOX_BASE
#define PLAT_RPI3_TM_ENTRYPOINT_SIZE ULL(8)
+/* Hold entries for each CPU. */
#define PLAT_RPI3_TM_HOLD_BASE (PLAT_RPI3_TM_ENTRYPOINT + \
PLAT_RPI3_TM_ENTRYPOINT_SIZE)
#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE ULL(8)
@@ -213,10 +215,11 @@
/*
* Other memory-related defines.
*/
-#define ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32)
-#define MAX_MMAP_REGIONS U(8)
-#define MAX_XLAT_TABLES U(4)
+#define MAX_MMAP_REGIONS 8
+#define MAX_XLAT_TABLES 4
#define MAX_IO_DEVICES U(3)
#define MAX_IO_HANDLES U(4)
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index df19705e6..d6d0d56ce 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -5,8 +5,6 @@
#
PLAT_INCLUDES := -Iinclude/common/tbbr \
- -Iinclude/plat/arm/common/ \
- -Iinclude/plat/arm/common/aarch64/ \
-Iplat/rpi3/include
PLAT_BL_COMMON_SOURCES := drivers/console/aarch64/console.S \
@@ -20,7 +18,8 @@ BL1_SOURCES += drivers/io/io_fip.c \
plat/common/aarch64/platform_mp_stack.S \
plat/rpi3/aarch64/plat_helpers.S \
plat/rpi3/rpi3_bl1_setup.c \
- plat/rpi3/rpi3_io_storage.c
+ plat/rpi3/rpi3_io_storage.c \
+ plat/rpi3/rpi3_mbox.c
BL2_SOURCES += common/desc_image_load.c \
drivers/io/io_fip.c \
@@ -34,7 +33,7 @@ BL2_SOURCES += common/desc_image_load.c \
plat/rpi3/rpi3_io_storage.c
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
- plat/common/aarch64/plat_psci_common.c \
+ plat/common/plat_psci_common.c \
plat/rpi3/aarch64/plat_helpers.S \
plat/rpi3/rpi3_bl31_setup.c \
plat/rpi3/rpi3_pm.c \
@@ -54,6 +53,26 @@ else
TF_CFLAGS_aarch64 += -mtune=cortex-a53
endif
+# Platform Makefile target
+# ------------------------
+
+RPI3_BL1_PAD_BIN := ${BUILD_PLAT}/bl1_pad.bin
+RPI3_ARMSTUB8_BIN := ${BUILD_PLAT}/armstub8.bin
+
+# Add new default target when compiling this platform
+all: armstub
+
+# This target concatenates BL1 and the FIP so that the base addresses match the
+# ones defined in the memory map
+armstub: bl1 fip
+ @echo " CAT $@"
+ ${Q}cp ${BUILD_PLAT}/bl1.bin ${RPI3_BL1_PAD_BIN}
+ ${Q}truncate --size=131072 ${RPI3_BL1_PAD_BIN}
+ ${Q}cat ${RPI3_BL1_PAD_BIN} ${BUILD_PLAT}/fip.bin > ${RPI3_ARMSTUB8_BIN}
+ @${ECHO_BLANK_LINE}
+ @echo "Built $@ successfully"
+ @${ECHO_BLANK_LINE}
+
# Build config flags
# ------------------
@@ -69,8 +88,11 @@ WORKAROUND_CVE_2017_5715 := 0
# Disable the PSCI platform compatibility layer by default
ENABLE_PLAT_COMPAT := 0
-# Enable reset to BL31 by default
-RESET_TO_BL31 := 1
+# Disable stack protector by default
+ENABLE_STACK_PROTECTOR := 0
+
+# Reset to BL31 isn't supported
+RESET_TO_BL31 := 0
# Have different sections for code and rodata
SEPARATE_CODE_AND_RODATA := 1
@@ -90,6 +112,9 @@ MULTI_CONSOLE_API := 1
# BL33 images are in AArch64 by default
RPI3_BL33_IN_AARCH32 := 0
+# Assume that BL33 isn't the Linux kernel by default
+RPI3_DIRECT_LINUX_BOOT := 0
+
# BL32 location
RPI3_BL32_RAM_LOCATION := tdram
ifeq (${RPI3_BL32_RAM_LOCATION}, tsram)
@@ -105,9 +130,17 @@ endif
$(eval $(call add_define,RPI3_BL32_RAM_LOCATION_ID))
$(eval $(call add_define,RPI3_BL33_IN_AARCH32))
+$(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
+$(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
# Verify build config
# -------------------
+#
+ifneq (${RPI3_DIRECT_LINUX_BOOT}, 0)
+ ifndef RPI3_PRELOADED_DTB_BASE
+ $(error Error: RPI3_PRELOADED_DTB_BASE needed if RPI3_DIRECT_LINUX_BOOT=1)
+ endif
+endif
ifneq (${LOAD_IMAGE_V2}, 1)
$(error Error: rpi3 needs LOAD_IMAGE_V2=1)
@@ -117,10 +150,19 @@ ifneq (${MULTI_CONSOLE_API}, 1)
$(error Error: rpi3 needs MULTI_CONSOLE_API=1)
endif
+ifneq (${RESET_TO_BL31}, 0)
+ $(error Error: rpi3 needs RESET_TO_BL31=0)
+endif
+
ifeq (${ARCH},aarch32)
$(error Error: AArch32 not supported on rpi3)
endif
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+PLAT_BL_COMMON_SOURCES += plat/rpi3/rpi3_rng.c \
+ plat/rpi3/rpi3_stack_protector.c
+endif
+
ifeq (${SPD},opteed)
BL2_SOURCES += \
lib/optee/optee_utils.c
diff --git a/plat/rpi3/rpi3_bl1_setup.c b/plat/rpi3/rpi3_bl1_setup.c
index c98715b9a..39bb33256 100644
--- a/plat/rpi3/rpi3_bl1_setup.c
+++ b/plat/rpi3/rpi3_bl1_setup.c
@@ -7,6 +7,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <bl_common.h>
+#include <debug.h>
#include <platform_def.h>
#include <xlat_mmu_helpers.h>
#include <xlat_tables_defs.h>
@@ -56,6 +57,39 @@ void bl1_plat_arch_setup(void)
void bl1_platform_setup(void)
{
+ uint32_t __unused rev;
+ int __unused rc;
+
+ rc = rpi3_vc_hardware_get_board_revision(&rev);
+
+ if (rc == 0) {
+ const char __unused *model, __unused *info;
+
+ switch (rev) {
+ case 0xA02082:
+ model = "Raspberry Pi 3 Model B";
+ info = "(1GB, Sony, UK)";
+ break;
+ case 0xA22082:
+ model = "Raspberry Pi 3 Model B";
+ info = "(1GB, Embest, China)";
+ break;
+ case 0xA020D3:
+ model = "Raspberry Pi 3 Model B+";
+ info = "(1GB, Sony, UK)";
+ break;
+ default:
+ model = "Unknown";
+ info = "(Unknown)";
+ ERROR("rpi3: Unknown board revision 0x%08x\n", rev);
+ break;
+ }
+
+ NOTICE("rpi3: Detected: %s %s [0x%08x]\n", model, info, rev);
+ } else {
+ ERROR("rpi3: Unable to detect board revision\n");
+ }
+
/* Initialise the IO layer and register platform IO devices */
plat_rpi3_io_setup();
}
diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi3/rpi3_bl2_setup.c
index 13e8c0155..c78024eaa 100644
--- a/plat/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi3/rpi3_bl2_setup.c
@@ -24,8 +24,12 @@ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE);
* in x0. This memory layout is sitting at the base of the free trusted SRAM.
* Copy it to a safe location before its reclaimed by later BL2 functionality.
******************************************************************************/
-void bl2_early_platform_setup(meminfo_t *mem_layout)
+
+void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
{
+ meminfo_t *mem_layout = (meminfo_t *) arg1;
+
/* Initialize the console to provide early debug support */
rpi3_console_init();
diff --git a/plat/rpi3/rpi3_bl31_setup.c b/plat/rpi3/rpi3_bl31_setup.c
index 58344ae99..306f26b3f 100644
--- a/plat/rpi3/rpi3_bl31_setup.c
+++ b/plat/rpi3/rpi3_bl31_setup.c
@@ -53,56 +53,21 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type)
* tables. BL2 has flushed this information to memory, so we are guaranteed
* to pick up good data.
******************************************************************************/
-void bl31_early_platform_setup(void *from_bl2,
- void *plat_params_from_bl2)
+void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+
{
/* Initialize the console to provide early debug support */
rpi3_console_init();
-#if RESET_TO_BL31
-
- /* There are no parameters from BL2 if BL31 is a reset vector */
- assert(from_bl2 == NULL);
- assert(plat_params_from_bl2 == NULL);
-
-#ifdef BL32_BASE
- /* Populate entry point information for BL32 */
- SET_PARAM_HEAD(&bl32_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
- bl32_image_ep_info.pc = BL32_BASE;
- bl32_image_ep_info.spsr = rpi3_get_spsr_for_bl32_entry();
-#endif /* BL32_BASE */
-
- /* Populate entry point information for BL33 */
- SET_PARAM_HEAD(&bl33_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- /*
- * Tell BL31 where the non-trusted software image
- * is located and the entry state information
- */
- bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
-
- bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
- SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
-
-#else /* RESET_TO_BL31 */
-
/*
- * In debug builds, we pass a special value in 'plat_params_from_bl2'
- * to verify platform parameters from BL2 to BL31.
- * In release builds, it's not used.
+ * In debug builds, a special value is passed in 'arg1' to verify
+ * platform parameters from BL2 to BL31. Not used in release builds.
*/
- assert(((uintptr_t)plat_params_from_bl2) == RPI3_BL31_PLAT_PARAM_VAL);
+ assert(arg1 == RPI3_BL31_PLAT_PARAM_VAL);
- /*
- * Check params passed from BL2 should not be NULL,
- */
- bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
+ /* Check that params passed from BL2 are not NULL. */
+ bl_params_t *params_from_bl2 = (bl_params_t *) arg0;
assert(params_from_bl2 != NULL);
assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
@@ -130,7 +95,33 @@ void bl31_early_platform_setup(void *from_bl2,
panic();
}
-#endif /* RESET_TO_BL31 */
+#if RPI3_DIRECT_LINUX_BOOT
+# if RPI3_BL33_IN_AARCH32
+ /*
+ * According to the file ``Documentation/arm/Booting`` of the Linux
+ * kernel tree, Linux expects:
+ * r0 = 0
+ * r1 = machine type number, optional in DT-only platforms (~0 if so)
+ * r2 = Physical address of the device tree blob
+ */
+ VERBOSE("rpi3: Preparing to boot 32-bit Linux kernel\n");
+ bl33_image_ep_info.args.arg0 = 0U;
+ bl33_image_ep_info.args.arg1 = ~0U;
+ bl33_image_ep_info.args.arg2 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
+# else
+ /*
+ * According to the file ``Documentation/arm64/booting.txt`` of the
+ * Linux kernel tree, Linux expects the physical address of the device
+ * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
+ * must be 0.
+ */
+ VERBOSE("rpi3: Preparing to boot 64-bit Linux kernel\n");
+ bl33_image_ep_info.args.arg0 = (u_register_t) RPI3_PRELOADED_DTB_BASE;
+ bl33_image_ep_info.args.arg1 = 0ULL;
+ bl33_image_ep_info.args.arg2 = 0ULL;
+ bl33_image_ep_info.args.arg3 = 0ULL;
+# endif /* RPI3_BL33_IN_AARCH32 */
+#endif /* RPI3_DIRECT_LINUX_BOOT */
}
void bl31_plat_arch_setup(void)
@@ -148,12 +139,10 @@ void bl31_plat_arch_setup(void)
void bl31_platform_setup(void)
{
-#if RESET_TO_BL31
/*
* Do initial security configuration to allow DRAM/device access
* (if earlier BL has not already done so).
*/
-#endif /* RESET_TO_BL31 */
return;
}
diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi3/rpi3_hw.h
index 70272e003..1a26053b9 100644
--- a/plat/rpi3/rpi3_hw.h
+++ b/plat/rpi3/rpi3_hw.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,11 +17,25 @@
#define RPI3_IO_SIZE ULL(0x01000000)
/*
- * Serial port (called 'Mini UART' in the BCM docucmentation).
+ * ARM <-> VideoCore mailboxes
*/
-#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040)
-#define RPI3_MINI_UART_BASE (RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000)
+#define RPI3_MBOX_OFFSET ULL(0x0000B880)
+#define RPI3_MBOX_BASE (RPI3_IO_BASE + RPI3_MBOX_OFFSET)
+/* VideoCore -> ARM */
+#define RPI3_MBOX0_READ_OFFSET ULL(0x00000000)
+#define RPI3_MBOX0_PEEK_OFFSET ULL(0x00000010)
+#define RPI3_MBOX0_SENDER_OFFSET ULL(0x00000014)
+#define RPI3_MBOX0_STATUS_OFFSET ULL(0x00000018)
+#define RPI3_MBOX0_CONFIG_OFFSET ULL(0x0000001C)
+/* ARM -> VideoCore */
+#define RPI3_MBOX1_WRITE_OFFSET ULL(0x00000020)
+#define RPI3_MBOX1_PEEK_OFFSET ULL(0x00000030)
+#define RPI3_MBOX1_SENDER_OFFSET ULL(0x00000034)
+#define RPI3_MBOX1_STATUS_OFFSET ULL(0x00000038)
+#define RPI3_MBOX1_CONFIG_OFFSET ULL(0x0000003C)
+/* Mailbox status constants */
+#define RPI3_MBOX_STATUS_FULL_MASK U(0x80000000) /* Set if full */
+#define RPI3_MBOX_STATUS_EMPTY_MASK U(0x40000000) /* Set if empty */
/*
* Power management, reset controller, watchdog.
@@ -30,11 +44,44 @@
#define RPI3_PM_BASE (RPI3_IO_BASE + RPI3_IO_PM_OFFSET)
/* Registers on top of RPI3_PM_BASE. */
#define RPI3_PM_RSTC_OFFSET ULL(0x0000001C)
+#define RPI3_PM_RSTS_OFFSET ULL(0x00000020)
#define RPI3_PM_WDOG_OFFSET ULL(0x00000024)
/* Watchdog constants */
-#define RPI3_PM_PASSWORD ULL(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK ULL(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET ULL(0x00000020)
+#define RPI3_PM_PASSWORD U(0x5A000000)
+#define RPI3_PM_RSTC_WRCFG_MASK U(0x00000030)
+#define RPI3_PM_RSTC_WRCFG_FULL_RESET U(0x00000020)
+/*
+ * The RSTS register is used by the VideoCore firmware when booting the
+ * Raspberry Pi to know which partition to boot from. The partition value is
+ * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
+ * to indicate halt.
+ */
+#define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555)
+
+/*
+ * Hardware random number generator.
+ */
+#define RPI3_IO_RNG_OFFSET ULL(0x00104000)
+#define RPI3_RNG_BASE (RPI3_IO_BASE + RPI3_IO_RNG_OFFSET)
+#define RPI3_RNG_CTRL_OFFSET ULL(0x00000000)
+#define RPI3_RNG_STATUS_OFFSET ULL(0x00000004)
+#define RPI3_RNG_DATA_OFFSET ULL(0x00000008)
+#define RPI3_RNG_INT_MASK_OFFSET ULL(0x00000010)
+/* Enable/disable RNG */
+#define RPI3_RNG_CTRL_ENABLE U(0x1)
+#define RPI3_RNG_CTRL_DISABLE U(0x0)
+/* Number of currently available words */
+#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT U(24)
+#define RPI3_RNG_STATUS_NUM_WORDS_MASK U(0xFF)
+/* Value to mask interrupts caused by the RNG */
+#define RPI3_RNG_INT_MASK_DISABLE U(0x1)
+
+/*
+ * Serial port (called 'Mini UART' in the BCM docucmentation).
+ */
+#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040)
+#define RPI3_MINI_UART_BASE (RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
+#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000)
/*
* Local interrupt controller
diff --git a/plat/rpi3/rpi3_mbox.c b/plat/rpi3/rpi3_mbox.c
new file mode 100644
index 000000000..77e17af6b
--- /dev/null
+++ b/plat/rpi3/rpi3_mbox.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <arch_helpers.h>
+#include <debug.h>
+#include <mmio.h>
+#include <platform_def.h>
+
+#include "rpi3_hw.h"
+
+/* This struct must be aligned to 16 bytes */
+typedef struct __packed __aligned(16) rpi3_mbox_request {
+ uint32_t size; /* Buffer size in bytes */
+ uint32_t code; /* Request/response code */
+ uint32_t tags[0];
+} rpi3_mbox_request_t;
+
+#define RPI3_MBOX_BUFFER_SIZE U(256)
+static uint8_t __aligned(16) rpi3_mbox_buffer[RPI3_MBOX_BUFFER_SIZE];
+
+/* Constants to perform a request/check the status of a request. */
+#define RPI3_MBOX_PROCESS_REQUEST U(0x00000000)
+#define RPI3_MBOX_REQUEST_SUCCESSFUL U(0x80000000)
+#define RPI3_MBOX_REQUEST_ERROR U(0x80000001)
+
+/* Command constants */
+#define RPI3_TAG_HARDWARE_GET_BOARD_REVISION U(0x00010002)
+#define RPI3_TAG_END U(0x00000000)
+
+#define RPI3_TAG_REQUEST U(0x00000000)
+#define RPI3_TAG_IS_RESPONSE U(0x80000000) /* Set if response */
+#define RPI3_TAG_RESPONSE_LENGTH_MASK U(0x7FFFFFFF)
+
+#define RPI3_CHANNEL_ARM_TO_VC U(0x8)
+#define RPI3_CHANNEL_MASK U(0xF)
+
+#define RPI3_MAILBOX_MAX_RETRIES U(1000000)
+
+/*******************************************************************************
+ * Helpers to send requests to the VideoCore using the mailboxes.
+ ******************************************************************************/
+static void rpi3_vc_mailbox_request_send(void)
+{
+ uint32_t st, data;
+ uintptr_t resp_addr, addr;
+ unsigned int retries;
+
+ /* This is the location of the request buffer */
+ addr = (uintptr_t) &rpi3_mbox_buffer;
+
+ /* Make sure that the changes are seen by the VideoCore */
+ flush_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE);
+
+ /* Wait until the outbound mailbox is empty */
+ retries = 0U;
+
+ do {
+ st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX1_STATUS_OFFSET);
+
+ retries++;
+ if (retries == RPI3_MAILBOX_MAX_RETRIES) {
+ ERROR("rpi3: mbox: Send request timeout\n");
+ return;
+ }
+
+ } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) == 0U);
+
+ /* Send base address of this message to start request */
+ mmio_write_32(RPI3_MBOX_BASE + RPI3_MBOX1_WRITE_OFFSET,
+ RPI3_CHANNEL_ARM_TO_VC | (uint32_t) addr);
+
+ /* Wait until the inbound mailbox isn't empty */
+ retries = 0U;
+
+ do {
+ st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_STATUS_OFFSET);
+
+ retries++;
+ if (retries == RPI3_MAILBOX_MAX_RETRIES) {
+ ERROR("rpi3: mbox: Receive response timeout\n");
+ return;
+ }
+
+ } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) != 0U);
+
+ /* Get location and channel */
+ data = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_READ_OFFSET);
+
+ if ((data & RPI3_CHANNEL_MASK) != RPI3_CHANNEL_ARM_TO_VC) {
+ ERROR("rpi3: mbox: Wrong channel: 0x%08x\n", data);
+ panic();
+ }
+
+ resp_addr = (uintptr_t)(data & ~RPI3_CHANNEL_MASK);
+ if (addr != resp_addr) {
+ ERROR("rpi3: mbox: Unexpected address: 0x%08x\n", data);
+ panic();
+ }
+
+ /* Make sure that the data seen by the CPU is up to date */
+ inv_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE);
+}
+
+/*******************************************************************************
+ * Request board revision. Returns the revision and 0 on success, -1 on error.
+ ******************************************************************************/
+int rpi3_vc_hardware_get_board_revision(uint32_t *revision)
+{
+ uint32_t tag_request_size = sizeof(uint32_t);
+ rpi3_mbox_request_t *req = (rpi3_mbox_request_t *) rpi3_mbox_buffer;
+
+ assert(revision != NULL);
+
+ VERBOSE("rpi3: mbox: Sending request at %p\n", (void *)req);
+
+ req->size = sizeof(rpi3_mbox_buffer);
+ req->code = RPI3_MBOX_PROCESS_REQUEST;
+
+ req->tags[0] = RPI3_TAG_HARDWARE_GET_BOARD_REVISION;
+ req->tags[1] = tag_request_size; /* Space available for the response */
+ req->tags[2] = RPI3_TAG_REQUEST;
+ req->tags[3] = 0; /* Placeholder for the response */
+
+ req->tags[4] = RPI3_TAG_END;
+
+ rpi3_vc_mailbox_request_send();
+
+ if (req->code != RPI3_MBOX_REQUEST_SUCCESSFUL) {
+ ERROR("rpi3: mbox: Code = 0x%08x\n", req->code);
+ return -1;
+ }
+
+ if (req->tags[2] != (RPI3_TAG_IS_RESPONSE | tag_request_size)) {
+ ERROR("rpi3: mbox: get board revision failed (0x%08x)\n",
+ req->tags[2]);
+ return -1;
+ }
+
+ *revision = req->tags[3];
+
+ return 0;
+}
diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi3/rpi3_pm.c
index 1d067fb13..b6adc8a53 100644
--- a/plat/rpi3/rpi3_pm.c
+++ b/plat/rpi3/rpi3_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,11 +15,6 @@
#include "rpi3_hw.h"
-/*
- * The secure entry point to be used on warm reset.
- */
-static uintptr_t secure_entrypoint;
-
/* Make composite power state parameter till power level 0 */
#if PSCI_EXTENDED_STATE_ID
@@ -150,41 +145,61 @@ void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state)
}
/*******************************************************************************
- * Platform handler to reboot the system
+ * Platform handlers for system reset and system off.
******************************************************************************/
-#define RESET_TIMEOUT 10
-static void __dead2 rpi3_system_reset(void)
-{
- /* Setup watchdog for reset */
+/* 10 ticks (Watchdog timer = Timer clock / 16) */
+#define RESET_TIMEOUT U(10)
- static const uintptr_t base = RPI3_PM_BASE;
+static void __dead2 rpi3_watchdog_reset(void)
+{
uint32_t rstc;
- INFO("rpi3: PSCI System Reset: invoking watchdog reset\n");
-
console_flush();
- rstc = mmio_read_32(base + RPI3_PM_RSTC_OFFSET);
- rstc &= ~RPI3_PM_RSTC_WRCFG_MASK;
- rstc |= RPI3_PM_RSTC_WRCFG_FULL_RESET;
-
- dmbst();
+ dsbsy();
+ isb();
- /*
- * Watchdog timer = Timer clock / 16
- * Password (31:16) | Value (11:0)
- */
- mmio_write_32(base + RPI3_PM_WDOG_OFFSET,
+ mmio_write_32(RPI3_PM_BASE + RPI3_PM_WDOG_OFFSET,
RPI3_PM_PASSWORD | RESET_TIMEOUT);
- mmio_write_32(base + RPI3_PM_RSTC_OFFSET,
- RPI3_PM_PASSWORD | rstc);
+
+ rstc = mmio_read_32(RPI3_PM_BASE + RPI3_PM_RSTC_OFFSET);
+ rstc &= ~RPI3_PM_RSTC_WRCFG_MASK;
+ rstc |= RPI3_PM_PASSWORD | RPI3_PM_RSTC_WRCFG_FULL_RESET;
+ mmio_write_32(RPI3_PM_BASE + RPI3_PM_RSTC_OFFSET, rstc);
for (;;) {
wfi();
}
}
+static void __dead2 rpi3_system_reset(void)
+{
+ INFO("rpi3: PSCI_SYSTEM_RESET: Invoking watchdog reset\n");
+
+ rpi3_watchdog_reset();
+}
+
+static void __dead2 rpi3_system_off(void)
+{
+ uint32_t rsts;
+
+ INFO("rpi3: PSCI_SYSTEM_OFF: Invoking watchdog reset\n");
+
+ /*
+ * This function doesn't actually make the Raspberry Pi turn itself off,
+ * the hardware doesn't allow it. It simply reboots it and the RSTS
+ * value tells the bootcode.bin firmware not to continue the regular
+ * bootflow and to stay in a low power mode.
+ */
+
+ rsts = mmio_read_32(RPI3_PM_BASE + RPI3_PM_RSTS_OFFSET);
+ rsts |= RPI3_PM_PASSWORD | RPI3_PM_RSTS_WRCFG_HALT;
+ mmio_write_32(RPI3_PM_BASE + RPI3_PM_RSTS_OFFSET, rsts);
+
+ rpi3_watchdog_reset();
+}
+
/*******************************************************************************
* Platform handlers and setup function.
******************************************************************************/
@@ -192,6 +207,7 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
.cpu_standby = rpi3_cpu_standby,
.pwr_domain_on = rpi3_pwr_domain_on,
.pwr_domain_on_finish = rpi3_pwr_domain_on_finish,
+ .system_off = rpi3_system_off,
.system_reset = rpi3_system_reset,
.validate_power_state = rpi3_validate_power_state,
};
@@ -199,10 +215,9 @@ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = {
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const plat_psci_ops_t **psci_ops)
{
- uintptr_t *mailbox = (void *)PLAT_RPI3_TRUSTED_MAILBOX_BASE;
+ uintptr_t *entrypoint = (void *) PLAT_RPI3_TM_ENTRYPOINT;
- *mailbox = sec_entrypoint;
- secure_entrypoint = (uintptr_t)sec_entrypoint;
+ *entrypoint = sec_entrypoint;
*psci_ops = &plat_rpi3_psci_pm_ops;
return 0;
diff --git a/plat/rpi3/rpi3_private.h b/plat/rpi3/rpi3_private.h
index a9fbfe479..368d09b2b 100644
--- a/plat/rpi3/rpi3_private.h
+++ b/plat/rpi3/rpi3_private.h
@@ -7,7 +7,7 @@
#ifndef __RPI3_PRIVATE_H__
#define __RPI3_PRIVATE_H__
-#include <sys/types.h>
+#include <stdint.h>
/*******************************************************************************
* Function and variable prototypes
@@ -33,4 +33,10 @@ uint32_t rpi3_get_spsr_for_bl33_entry(void);
/* IO storage utility functions */
void plat_rpi3_io_setup(void);
+/* Hardware RNG functions */
+void rpi3_rng_read(void *buf, size_t len);
+
+/* VideoCore firmware commands */
+int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
+
#endif /*__RPI3_PRIVATE_H__ */
diff --git a/plat/rpi3/rpi3_rng.c b/plat/rpi3/rpi3_rng.c
new file mode 100644
index 000000000..111b3b6c6
--- /dev/null
+++ b/plat/rpi3/rpi3_rng.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <mmio.h>
+#include <string.h>
+
+#include "rpi3_hw.h"
+
+/* Initial amount of values to discard */
+#define RNG_WARMUP_COUNT U(0x40000)
+
+static void rpi3_rng_initialize(void)
+{
+ uint32_t int_mask, ctrl;
+
+ /* Return if it is already enabled */
+ ctrl = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET);
+ if ((ctrl & RPI3_RNG_CTRL_ENABLE) != 0U) {
+ return;
+ }
+
+ /* Mask interrupts */
+ int_mask = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET);
+ int_mask |= RPI3_RNG_INT_MASK_DISABLE;
+ mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET, int_mask);
+
+ /* Discard several values when initializing to give it time to warmup */
+ mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET, RNG_WARMUP_COUNT);
+
+ mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET,
+ RPI3_RNG_CTRL_ENABLE);
+}
+
+static uint32_t rpi3_rng_get_word(void)
+{
+ size_t nwords;
+
+ do {
+ /* Get number of available words to read */
+ nwords = (mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET)
+ >> RPI3_RNG_STATUS_NUM_WORDS_SHIFT)
+ & RPI3_RNG_STATUS_NUM_WORDS_MASK;
+ } while (nwords == 0U);
+
+ return mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_DATA_OFFSET);
+}
+
+void rpi3_rng_read(void *buf, size_t len)
+{
+ uint32_t data;
+ size_t left = len;
+ uint32_t *dst = buf;
+
+ assert(buf != NULL);
+ assert(len != 0U);
+ assert(check_uptr_overflow((uintptr_t) buf, (uintptr_t) len) == 0);
+
+ rpi3_rng_initialize();
+
+ while (left >= sizeof(uint32_t)) {
+ data = rpi3_rng_get_word();
+ *dst++ = data;
+ left -= sizeof(uint32_t);
+ }
+
+ if (left > 0U) {
+ data = rpi3_rng_get_word();
+ memcpy(dst, &data, left);
+ }
+}
diff --git a/plat/rpi3/rpi3_stack_protector.c b/plat/rpi3/rpi3_stack_protector.c
new file mode 100644
index 000000000..812f6edfa
--- /dev/null
+++ b/plat/rpi3/rpi3_stack_protector.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <utils.h>
+
+#include "rpi3_private.h"
+
+/* Get 128 bits of entropy and fuse the values together to form the canary. */
+#define TRNG_NBYTES 16U
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ size_t i;
+ u_register_t buf[TRNG_NBYTES / sizeof(u_register_t)];
+ u_register_t ret = 0U;
+
+ rpi3_rng_read(buf, sizeof(buf));
+
+ for (i = 0U; i < ARRAY_SIZE(buf); i++)
+ ret ^= buf[i];
+
+ return ret;
+}
diff --git a/plat/rpi3/rpi3_topology.c b/plat/rpi3/rpi3_topology.c
index 0e03ec329..31a22a469 100644
--- a/plat/rpi3/rpi3_topology.c
+++ b/plat/rpi3/rpi3_topology.c
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include "rpi3_private.h"
diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h
index 3e1664223..bde73485b 100644
--- a/plat/socionext/synquacer/include/platform_def.h
+++ b/plat/socionext/synquacer/include/platform_def.h
@@ -4,10 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <common_def.h>
+#include <utils_def.h>
/* CPU topology */
#define PLAT_MAX_CORES_PER_CLUSTER 2
@@ -15,9 +16,9 @@
#define PLATFORM_CORE_COUNT (PLAT_CLUSTER_COUNT * \
PLAT_MAX_CORES_PER_CLUSTER)
-#define PLAT_MAX_PWR_LVL 1
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_PWR_LVL U(1)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
#define SQ_LOCAL_STATE_RUN 0
#define SQ_LOCAL_STATE_RET 1
@@ -78,4 +79,4 @@
#define PLAT_SQ_GPIO_BASE 0x51000000
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/socionext/synquacer/include/sq_common.h b/plat/socionext/synquacer/include/sq_common.h
index 58b1e24ec..7f0633a5c 100644
--- a/plat/socionext/synquacer/include/sq_common.h
+++ b/plat/socionext/synquacer/include/sq_common.h
@@ -7,7 +7,7 @@
#ifndef __SQ_COMMON_H__
#define __SQ_COMMON_H__
-#include <sys/types.h>
+#include <stdint.h>
#include <xlat_tables_v2.h>
struct draminfo {
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index 546f84aa1..96427a161 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -18,6 +18,10 @@ ERRATA_A53_855873 := 1
# Libraries
include lib/xlat_tables_v2/xlat_tables.mk
+ifeq (${SPD},opteed)
+TF_CFLAGS_aarch64 += -DBL32_BASE=0xfc000000
+endif
+
PLAT_PATH := plat/socionext/synquacer
PLAT_INCLUDES := -I$(PLAT_PATH)/include \
-I$(PLAT_PATH)/drivers/scpi \
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index 461c8dece..26b8ff1bb 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -70,15 +70,31 @@ void bl31_early_platform_setup(bl31_params_t *from_bl2,
assert(from_bl2 == NULL);
assert(plat_params_from_bl2 == NULL);
+ /* Initialize power controller before setting up topology */
+ plat_sq_pwrc_setup();
+
#ifdef BL32_BASE
- /* Populate entry point information for BL32 */
- SET_PARAM_HEAD(&bl32_image_ep_info,
- PARAM_EP,
- VERSION_1,
- 0);
- SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
- bl32_image_ep_info.pc = BL32_BASE;
- bl32_image_ep_info.spsr = sq_get_spsr_for_bl32_entry();
+ struct draminfo di = {0};
+
+ scpi_get_draminfo(&di);
+
+ /*
+ * Check if OP-TEE has been loaded in Secure RAM allocated
+ * from DRAM1 region
+ */
+ if ((di.base1 + di.size1) <= BL32_BASE) {
+ NOTICE("OP-TEE has been loaded by SCP firmware\n");
+ /* Populate entry point information for BL32 */
+ SET_PARAM_HEAD(&bl32_image_ep_info,
+ PARAM_EP,
+ VERSION_1,
+ 0);
+ SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+ bl32_image_ep_info.pc = BL32_BASE;
+ bl32_image_ep_info.spsr = sq_get_spsr_for_bl32_entry();
+ } else {
+ NOTICE("OP-TEE has not been loaded by SCP firmware\n");
+ }
#endif /* BL32_BASE */
/* Populate entry point information for BL33 */
@@ -121,13 +137,10 @@ void bl31_platform_setup(void)
/* Enable and initialize the System level generic timer */
mmio_write_32(SQ_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0) | CNTCR_EN);
+ CNTCR_FCREQ(0U) | CNTCR_EN);
/* Allow access to the System counter timer module */
sq_configure_sys_timer();
-
- /* Initialize power controller before setting up topology */
- plat_sq_pwrc_setup();
}
void bl31_plat_runtime_setup(void)
diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h
index 301aa147f..3d71db205 100644
--- a/plat/socionext/uniphier/include/platform_def.h
+++ b/plat/socionext/uniphier/include/platform_def.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <common_def.h>
#include <tbbr/tbbr_img_def.h>
@@ -23,10 +23,10 @@
#define PLATFORM_CORE_COUNT \
((UNIPHIER_MAX_CPUS_PER_CLUSTER) * (UNIPHIER_CLUSTER_COUNT))
-#define PLAT_MAX_PWR_LVL 1
+#define PLAT_MAX_PWR_LVL U(1)
-#define PLAT_MAX_OFF_STATE 2
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
#define BL2_BASE ULL(0x80000000)
#define BL2_LIMIT ULL(0x80080000)
@@ -59,4 +59,4 @@
#define TSP_SEC_MEM_SIZE ((BL32_LIMIT) - (BL32_BASE))
#define TSP_IRQ_SEC_PHY_TIMER 29
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h
index 1768e3bee..7ff146415 100644
--- a/plat/socionext/uniphier/uniphier.h
+++ b/plat/socionext/uniphier/uniphier.h
@@ -8,7 +8,7 @@
#define __UNIPHIER_H__
#include <stdint.h>
-#include <types.h>
+#include <string.h>
unsigned int uniphier_get_soc_type(void);
unsigned int uniphier_get_soc_model(void);
diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c
index d9c87bd93..9e28eecd7 100644
--- a/plat/socionext/uniphier/uniphier_bl31_setup.c
+++ b/plat/socionext/uniphier/uniphier_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,7 +17,6 @@
#include "uniphier.h"
-#define BL31_END (unsigned long)(&__BL31_END__)
#define BL31_SIZE ((BL31_END) - (BL31_BASE))
static entry_point_info_t bl32_image_ep_info;
@@ -70,7 +69,7 @@ void bl31_platform_setup(void)
/* Enable and initialize the System level generic timer */
mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF,
- CNTCR_FCREQ(0) | CNTCR_EN);
+ CNTCR_FCREQ(0U) | CNTCR_EN);
}
void bl31_plat_arch_setup(void)
diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c
index fcd4cb401..db87637b7 100644
--- a/plat/socionext/uniphier/uniphier_emmc.c
+++ b/plat/socionext/uniphier/uniphier_emmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include <utils_def.h>
#include "uniphier.h"
diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c
index ed1f6faed..1fd835b54 100644
--- a/plat/socionext/uniphier/uniphier_io_storage.c
+++ b/plat/socionext/uniphier/uniphier_io_storage.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,7 @@
#include <io/io_fip.h>
#include <io/io_memmap.h>
#include <platform_def.h>
-#include <types.h>
+#include <stdint.h>
#include <utils_def.h>
#include <xlat_tables_v2.h>
diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c
index a118b8512..c8e825d6a 100644
--- a/plat/socionext/uniphier/uniphier_nand.c
+++ b/plat/socionext/uniphier/uniphier_nand.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include <utils_def.h>
#include "uniphier.h"
diff --git a/plat/socionext/uniphier/uniphier_usb.c b/plat/socionext/uniphier/uniphier_usb.c
index 4be0e908c..b51b60120 100644
--- a/plat/socionext/uniphier/uniphier_usb.c
+++ b/plat/socionext/uniphier/uniphier_usb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,7 +9,7 @@
#include <io/io_block.h>
#include <mmio.h>
#include <platform_def.h>
-#include <sys/types.h>
+#include <stdint.h>
#include <utils_def.h>
#include "uniphier.h"
diff --git a/plat/st/stm32mp1/bl2_io_storage.c b/plat/st/stm32mp1/bl2_io_storage.c
new file mode 100644
index 000000000..7346c0cf3
--- /dev/null
+++ b/plat/st/stm32mp1/bl2_io_storage.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <io_driver.h>
+#include <io_dummy.h>
+#include <io_storage.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <string.h>
+#include <utils.h>
+
+/* IO devices */
+static const io_dev_connector_t *dummy_dev_con;
+static uintptr_t dummy_dev_handle;
+static uintptr_t dummy_dev_spec;
+
+static const io_block_spec_t bl32_block_spec = {
+ .offset = BL32_BASE,
+ .length = STM32MP1_BL32_SIZE
+};
+
+static const io_block_spec_t bl2_block_spec = {
+ .offset = BL2_BASE,
+ .length = STM32MP1_BL2_SIZE,
+};
+
+static int open_dummy(const uintptr_t spec);
+
+struct plat_io_policy {
+ uintptr_t *dev_handle;
+ uintptr_t image_spec;
+ int (*check)(const uintptr_t spec);
+};
+
+static const struct plat_io_policy policies[] = {
+ [BL2_IMAGE_ID] = {
+ .dev_handle = &dummy_dev_handle,
+ .image_spec = (uintptr_t)&bl2_block_spec,
+ .check = open_dummy
+ },
+ [BL32_IMAGE_ID] = {
+ .dev_handle = &dummy_dev_handle,
+ .image_spec = (uintptr_t)&bl32_block_spec,
+ .check = open_dummy
+ },
+};
+
+static int open_dummy(const uintptr_t spec)
+{
+ return io_dev_init(dummy_dev_handle, 0);
+}
+
+static void print_boot_device(boot_api_context_t *boot_context)
+{
+ switch (boot_context->boot_interface_selected) {
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
+ INFO("Using SDMMC\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
+ INFO("Using EMMC\n");
+ break;
+ default:
+ ERROR("Boot interface not found\n");
+ panic();
+ break;
+ }
+
+ if (boot_context->boot_interface_instance != 0U) {
+ INFO(" Instance %d\n", boot_context->boot_interface_instance);
+ }
+}
+
+static void print_reset_reason(void)
+{
+ uint32_t rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+ if (rstsr == 0U) {
+ WARN("Reset reason unknown\n");
+ return;
+ }
+
+ INFO("Reset reason (0x%x):\n", rstsr);
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) == 0U) {
+ if ((rstsr & RCC_MP_RSTSCLRR_STDBYRSTF) != 0U) {
+ INFO("System exits from STANDBY\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_CSTDBYRSTF) != 0U) {
+ INFO("MPU exits from CSTANDBY\n");
+ return;
+ }
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PORRSTF) != 0U) {
+ INFO(" Power-on Reset (rst_por)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_BORRSTF) != 0U) {
+ INFO(" Brownout Reset (rst_bor)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_MPSYSRSTF) != 0U) {
+ INFO(" System reset generated by MPU (MPSYSRST)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_HCSSRSTF) != 0U) {
+ INFO(" Reset due to a clock failure on HSE\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_IWDG1RSTF) != 0U) {
+ INFO(" IWDG1 Reset (rst_iwdg1)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_IWDG2RSTF) != 0U) {
+ INFO(" IWDG2 Reset (rst_iwdg2)\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_PADRSTF) != 0U) {
+ INFO(" Pad Reset from NRST\n");
+ return;
+ }
+
+ if ((rstsr & RCC_MP_RSTSCLRR_VCORERSTF) != 0U) {
+ INFO(" Reset due to a failure of VDD_CORE\n");
+ return;
+ }
+
+ ERROR(" Unidentified reset reason\n");
+}
+
+void stm32mp1_io_setup(void)
+{
+ int io_result __unused;
+ boot_api_context_t *boot_context =
+ (boot_api_context_t *)stm32mp1_get_boot_ctx_address();
+
+ print_reset_reason();
+
+ print_boot_device(boot_context);
+
+ if ((boot_context->boot_partition_used_toboot == 1U) ||
+ (boot_context->boot_partition_used_toboot == 2U)) {
+ INFO("Boot used partition fsbl%d\n",
+ boot_context->boot_partition_used_toboot);
+ }
+
+ io_result = register_io_dev_dummy(&dummy_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
+ &dummy_dev_handle);
+ assert(io_result == 0);
+}
+
+/*
+ * Return an IO device handle and specification which can be used to access
+ * an image. Use this to enforce platform load policy.
+ */
+int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
+ uintptr_t *image_spec)
+{
+ int rc;
+ const struct plat_io_policy *policy;
+
+ assert(image_id < ARRAY_SIZE(policies));
+
+ policy = &policies[image_id];
+ rc = policy->check(policy->image_spec);
+ if (rc == 0) {
+ *image_spec = policy->image_spec;
+ *dev_handle = *(policy->dev_handle);
+ }
+
+ return rc;
+}
diff --git a/plat/st/stm32mp1/bl2_plat_setup.c b/plat/st/stm32mp1/bl2_plat_setup.c
new file mode 100644
index 000000000..9f2d8bd0f
--- /dev/null
+++ b/plat/st/stm32mp1/bl2_plat_setup.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <boot_api.h>
+#include <console.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <desc_image_load.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_pmic.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_context.h>
+#include <stm32mp1_pwr.h>
+#include <stm32mp1_ram.h>
+#include <stm32mp1_rcc.h>
+#include <stm32mp1_reset.h>
+#include <string.h>
+#include <xlat_tables_v2.h>
+
+void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ stm32mp1_save_boot_ctx_address(arg0);
+}
+
+void bl2_platform_setup(void)
+{
+ int ret;
+
+ if (dt_check_pmic()) {
+ initialize_pmic();
+ }
+
+ ret = stm32mp1_ddr_probe();
+ if (ret < 0) {
+ ERROR("Invalid DDR init: error %d\n", ret);
+ panic();
+ }
+
+ INFO("BL2 runs SP_MIN setup\n");
+}
+
+void bl2_el3_plat_arch_setup(void)
+{
+ int32_t result;
+ struct dt_node_info dt_dev_info;
+ const char *board_model;
+ boot_api_context_t *boot_context =
+ (boot_api_context_t *)stm32mp1_get_boot_ctx_address();
+ uint32_t clk_rate;
+
+ /*
+ * Disable the backup domain write protection.
+ * The protection is enable at each reset by hardware
+ * and must be disabled by software.
+ */
+ mmio_setbits_32(PWR_BASE + PWR_CR1, PWR_CR1_DBP);
+
+ while ((mmio_read_32(PWR_BASE + PWR_CR1) & PWR_CR1_DBP) == 0U) {
+ ;
+ }
+
+ /* Reset backup domain on cold boot cases */
+ if ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_RTCSRC_MASK) == 0U) {
+ mmio_setbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
+
+ while ((mmio_read_32(RCC_BASE + RCC_BDCR) & RCC_BDCR_VSWRST) ==
+ 0U) {
+ ;
+ }
+
+ mmio_clrbits_32(RCC_BASE + RCC_BDCR, RCC_BDCR_VSWRST);
+ }
+
+ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+ BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE);
+
+ /* Prevent corruption of preloaded BL32 */
+ mmap_add_region(BL32_BASE, BL32_BASE,
+ BL32_LIMIT - BL32_BASE,
+ MT_MEMORY | MT_RO | MT_SECURE);
+
+ /* Prevent corruption of preloaded Device Tree */
+ mmap_add_region(DTB_BASE, DTB_BASE,
+ DTB_LIMIT - DTB_BASE,
+ MT_MEMORY | MT_RO | MT_SECURE);
+
+ configure_mmu();
+
+ generic_delay_timer_init();
+
+ if (dt_open_and_check() < 0) {
+ panic();
+ }
+
+ if (stm32mp1_clk_probe() < 0) {
+ panic();
+ }
+
+ if (stm32mp1_clk_init() < 0) {
+ panic();
+ }
+
+ result = dt_get_stdout_uart_info(&dt_dev_info);
+
+ if ((result <= 0) ||
+ (dt_dev_info.status == 0U) ||
+ (dt_dev_info.clock < 0) ||
+ (dt_dev_info.reset < 0)) {
+ goto skip_console_init;
+ }
+
+ if (dt_set_stdout_pinctrl() != 0) {
+ goto skip_console_init;
+ }
+
+ if (stm32mp1_clk_enable((unsigned long)dt_dev_info.clock) != 0) {
+ goto skip_console_init;
+ }
+
+ stm32mp1_reset_assert((uint32_t)dt_dev_info.reset);
+ udelay(2);
+ stm32mp1_reset_deassert((uint32_t)dt_dev_info.reset);
+ mdelay(1);
+
+ clk_rate = stm32mp1_clk_get_rate((unsigned long)dt_dev_info.clock);
+
+ if (console_init(dt_dev_info.base, clk_rate,
+ STM32MP1_UART_BAUDRATE) == 0) {
+ panic();
+ }
+
+ board_model = dt_get_board_model();
+ if (board_model != NULL) {
+ NOTICE("%s\n", board_model);
+ }
+
+skip_console_init:
+
+ if (stm32_save_boot_interface(boot_context->boot_interface_selected,
+ boot_context->boot_interface_instance) !=
+ 0) {
+ ERROR("Cannot save boot interface\n");
+ }
+
+ stm32mp1_arch_security_setup();
+
+ stm32mp1_io_setup();
+}
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
new file mode 100644
index 000000000..71c359347
--- /dev/null
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2017, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BOOT_API_H
+#define __BOOT_API_H
+
+#include <stdint.h>
+
+/*
+ * Possible value of boot context field 'boot_interface_sel'
+ */
+
+/* Value of field 'boot_interface_sel' when no boot occurred */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_NO 0x0U
+
+/* Boot occurred on SD */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD 0x1U
+
+/* Boot occurred on EMMC */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC 0x2U
+
+/**
+ * @brief Possible value of boot context field 'EmmcXferStatus'
+ */
+/*
+ * Possible value of boot context field 'emmc_xfer_status'
+ */
+#define BOOT_API_CTX_EMMC_XFER_STATUS_NOT_STARTED 0x0U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_DATAEND_DETECTED 0x1U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_OVERALL_TIMEOUT_DETECTED 0x2U
+#define BOOT_API_CTX_EMMC_XFER_STATUS_XFER_DATA_TIMEOUT 0x3U
+
+/*
+ * Possible value of boot context field 'emmc_error_status'
+ */
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_NONE 0x0U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_CMD_TIMEOUT 0x1U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_ACK_TIMEOUT 0x2U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_DATA_CRC_FAIL 0x3U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_NOT_ENOUGH_BOOT_DATA_RX 0x4U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_NOT_FOUND 0x5U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_HEADER_SIZE_ZERO 0x6U
+#define BOOT_API_CTX_EMMC_ERROR_STATUS_IMAGE_NOT_COMPLETE 0x7U
+
+/* Image Header related definitions */
+
+/* Definition of header version */
+#define BOOT_API_HEADER_VERSION 0x00010000U
+
+/*
+ * Magic number used to detect header in memory
+ * Its value must be 'S' 'T' 'M' 0x32, i.e 0x324D5453 as field
+ * 'bootapi_image_header_t.magic'
+ * This identifies the start of a boot image.
+ */
+#define BOOT_API_IMAGE_HEADER_MAGIC_NB 0x324D5453U
+
+/* Definitions related to Authentication used in image header structure */
+#define BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES 64
+#define BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES 64
+#define BOOT_API_SHA256_DIGEST_SIZE_IN_BYTES 32
+
+/* Possible values of the field 'boot_api_image_header_t.ecc_algo_type' */
+#define BOOT_API_ECDSA_ALGO_TYPE_P256NIST 1
+#define BOOT_API_ECDSA_ALGO_TYPE_BRAINPOOL256 2
+
+/*
+ * Cores secure magic numbers
+ * Constant to be stored in bakcup register
+ * BOOT_API_MAGIC_NUMBER_TAMP_BCK_REG_IDX
+ */
+#define BOOT_API_A7_CORE0_MAGIC_NUMBER 0xCA7FACE0U
+#define BOOT_API_A7_CORE1_MAGIC_NUMBER 0xCA7FACE1U
+
+/*
+ * TAMP_BCK4R register index
+ * This register is used to write a Magic Number in order to restart
+ * Cortex A7 Core 1 and make it execute @ branch address from TAMP_BCK5R
+ */
+#define BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX 4U
+
+/*
+ * TAMP_BCK5R register index
+ * This register is used to contain the branch address of
+ * Cortex A7 Core 1 when restarted by a TAMP_BCK4R magic number writing
+ */
+#define BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX 5U
+
+/*
+ * Possible value of boot context field 'hse_clock_value_in_hz'
+ */
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_UNDEFINED 0U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_24_MHZ 24000000U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_25_MHZ 25000000U
+#define BOOT_API_CTX_HSE_CLOCK_VALUE_26_MHZ 26000000U
+
+/*
+ * Possible value of boot context field 'boot_partition_used_toboot'
+ */
+#define BOOT_API_CTX_BOOT_PARTITION_UNDEFINED 0U
+
+/* Used FSBL1 to boot */
+#define BOOT_API_CTX_BOOT_PARTITION_FSBL1 1U
+
+/* Used FSBL2 to boot */
+#define BOOT_API_CTX_BOOT_PARTITION_FSBL2 2U
+
+/* OTP_CFG0 */
+#define BOOT_API_OTP_MODE_WORD_NB 0
+/* Closed = OTP_CFG0[6] */
+#define BOOT_API_OTP_MODE_CLOSED_BIT_POS 6
+
+/*
+ * Boot Context related definitions
+ */
+
+/*
+ * Boot core boot configuration structure
+ * Specifies all items of the cold boot configuration
+ * Memory and peripheral part.
+ */
+typedef struct {
+ /*
+ * Boot interface used to boot : take values from defines
+ * BOOT_API_CTX_BOOT_INTERFACE_SEL_XXX above
+ */
+ uint16_t boot_interface_selected;
+ uint16_t boot_interface_instance;
+ uint32_t reserved1[13];
+ uint32_t otp_afmux_values[3];
+ uint32_t reserved[9];
+ /*
+ * Information specific to an SD boot
+ * Updated each time an SD boot is at least attempted,
+ * even if not successful
+ * Note : This is useful to understand why an SD boot failed
+ * in particular
+ */
+ uint32_t sd_err_internal_timeout_cnt;
+ uint32_t sd_err_dcrc_fail_cnt;
+ uint32_t sd_err_dtimeout_cnt;
+ uint32_t sd_err_ctimeout_cnt;
+ uint32_t sd_err_ccrc_fail_cnt;
+ uint32_t sd_overall_retry_cnt;
+ /*
+ * Information specific to an eMMC boot
+ * Updated each time an eMMC boot is at least attempted,
+ * even if not successful
+ * Note : This is useful to understand why an eMMC boot failed
+ * in particular
+ */
+ uint32_t emmc_xfer_status;
+ uint32_t emmc_error_status;
+ uint32_t emmc_nbbytes_rxcopied_tosysram_download_area;
+ uint32_t hse_clock_value_in_hz;
+ /*
+ * Boot partition :
+ * ie FSBL partition on which the boot was successful
+ */
+ uint32_t boot_partition_used_toboot;
+
+} __packed boot_api_context_t;
+
+/*
+ * Image Header related definitions
+ */
+
+/*
+ * Structure used to define the common Header format used for FSBL, xloader,
+ * ... and in particular used by bootROM for FSBL header readout.
+ * FSBL header size is 256 Bytes = 0x100
+ */
+typedef struct {
+ /* BOOT_API_IMAGE_HEADER_MAGIC_NB */
+ uint32_t magic;
+ uint8_t image_signature[BOOT_API_ECDSA_SIGNATURE_LEN_IN_BYTES];
+ /*
+ * Checksum of payload
+ * 32-bit sum all all payload bytes considered as 8 bit unigned numbers,
+ * discarding any overflow bits.
+ * Use to check UART/USB downloaded image integrity when signature
+ * is not used (i.e bit 0 : 'No_sig_check' = 1 in option flags)
+ */
+ uint32_t payload_checksum;
+ /* Image header version : should have value BOOT_API_HEADER_VERSION */
+ uint32_t header_version;
+ /* Image length in bytes */
+ uint32_t image_length;
+ /*
+ * Image Entry point address : should be in the SYSRAM area
+ * and at least within the download area range
+ */
+ uint32_t image_entry_point;
+ /* Reserved */
+ uint32_t reserved1;
+ /*
+ * Image load address : not used by bootROM but to be consistent
+ * with header format for other packages (xloader, ...)
+ */
+ uint32_t load_address;
+ /* Reserved */
+ uint32_t reserved2;
+ /* Image version to be compared by bootROM with monotonic
+ * counter value in OTP_CFG4 prior executing the downloaded image
+ */
+ uint32_t image_version;
+ /*
+ * Option flags:
+ * Bit 0 : No signature check request : 'No_sig_check'
+ * value 1 : for No signature check request
+ * value 0 : No request to bypass the signature check
+ * Note : No signature check is never allowed on a Secured chip
+ */
+ uint32_t option_flags;
+ /*
+ * Type of ECC algorithm to use :
+ * value 1 : for P-256 NIST algorithm
+ * value 2 : for Brainpool 256 algorithm
+ * See definitions 'BOOT_API_ECDSA_ALGO_TYPE_XXX' above.
+ */
+ uint32_t ecc_algo_type;
+ /*
+ * OEM ECC Public Key (aka Root pubk) provided in header on 512 bits.
+ * The SHA-256 hash of the OEM ECC pubk must match the one stored
+ * in OTP cells.
+ */
+ uint8_t ecc_pubk[BOOT_API_ECDSA_PUB_KEY_LEN_IN_BYTES];
+ /* Pad up to 256 byte total size */
+ uint8_t pad[84];
+} __packed boot_api_image_header_t;
+
+#endif /* __BOOT_API_H */
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
new file mode 100644
index 000000000..47e1ffcf5
--- /dev/null
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common_def.h>
+#include <gic_common.h>
+#include <utils_def.h>
+#include "../stm32mp1_def.h"
+
+/*******************************************************************************
+ * Generic platform constants
+ ******************************************************************************/
+
+/* Size of cacheable stacks */
+#if defined(IMAGE_BL32)
+#define PLATFORM_STACK_SIZE 0x600
+#else
+#define PLATFORM_STACK_SIZE 0xC00
+#endif
+
+/* SSBL = second stage boot loader */
+#define BL33_IMAGE_NAME "ssbl"
+
+#define STM32MP1_PRIMARY_CPU U(0x0)
+
+#define PLATFORM_CACHE_LINE_SIZE 64
+#define PLATFORM_CLUSTER_COUNT ULL(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT U(2)
+#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
+#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
+ PLATFORM_CLUSTER0_CORE_COUNT)
+#define PLATFORM_MAX_CPUS_PER_CLUSTER 2
+
+#define MAX_IO_DEVICES 4
+#define MAX_IO_HANDLES 4
+
+/*******************************************************************************
+ * BL2 specific defines.
+ ******************************************************************************/
+/*
+ * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
+ * size plus a little space for growth.
+ */
+#define BL2_BASE STM32MP1_BL2_BASE
+#define BL2_LIMIT (STM32MP1_BL2_BASE + \
+ STM32MP1_BL2_SIZE)
+
+/*******************************************************************************
+ * BL32 specific defines.
+ ******************************************************************************/
+#define BL32_BASE STM32MP1_BL32_BASE
+#define BL32_LIMIT (STM32MP1_BL32_BASE + \
+ STM32MP1_BL32_SIZE)
+
+/*******************************************************************************
+ * BL33 specific defines.
+ ******************************************************************************/
+#define BL33_BASE STM32MP1_BL33_BASE
+
+/*
+ * Load address of BL33 for this platform port
+ */
+#define PLAT_STM32MP1_NS_IMAGE_OFFSET BL33_BASE
+
+/*******************************************************************************
+ * DTB specific defines.
+ ******************************************************************************/
+#define DTB_BASE STM32MP1_DTB_BASE
+#define DTB_LIMIT (STM32MP1_DTB_BASE + \
+ STM32MP1_DTB_SIZE)
+
+/*******************************************************************************
+ * Platform specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32)
+
+/*******************************************************************************
+ * Declarations and constants to access the mailboxes safely. Each mailbox is
+ * aligned on the biggest cache line size in the platform. This is known only
+ * to the platform as it might have a combination of integrated and external
+ * caches. Such alignment ensures that two maiboxes do not sit on the same cache
+ * line at any cache level. They could belong to different cpus/clusters &
+ * get written while being protected by different locks causing corruption of
+ * a valid mailbox address.
+ ******************************************************************************/
+#define CACHE_WRITEBACK_SHIFT 6
+#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * Secure Interrupt: based on the standard ARM mapping
+ */
+#define ARM_IRQ_SEC_PHY_TIMER U(29)
+
+#define ARM_IRQ_SEC_SGI_0 U(8)
+#define ARM_IRQ_SEC_SGI_1 U(9)
+#define ARM_IRQ_SEC_SGI_2 U(10)
+#define ARM_IRQ_SEC_SGI_3 U(11)
+#define ARM_IRQ_SEC_SGI_4 U(12)
+#define ARM_IRQ_SEC_SGI_5 U(13)
+#define ARM_IRQ_SEC_SGI_6 U(14)
+#define ARM_IRQ_SEC_SGI_7 U(15)
+
+#define STM32MP1_IRQ_TZC400 U(36)
+#define STM32MP1_IRQ_TAMPSERRS U(229)
+#define STM32MP1_IRQ_AXIERRIRQ U(244)
+
+/*
+ * 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
+ * as Group 0 interrupts.
+ */
+#define PLATFORM_G1S_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(STM32MP1_IRQ_TAMPSERRS, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(STM32MP1_IRQ_AXIERRIRQ, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(STM32MP1_IRQ_TZC400, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE)
+
+#define PLATFORM_G0_PROPS(grp) \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_0, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, \
+ GIC_HIGHEST_SEC_PRIORITY, \
+ grp, GIC_INTR_CFG_EDGE)
+
+/*
+ * Power
+ */
+#define PLAT_MAX_PWR_LVL U(1)
+
+/* Local power state for power domains in Run state. */
+#define ARM_LOCAL_STATE_RUN U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define ARM_LOCAL_STATE_RET U(1)
+/* Local power state for power-down. Valid for CPU and cluster power domains */
+#define ARM_LOCAL_STATE_OFF U(2)
+/*
+ * This macro defines the deepest retention state possible.
+ * A higher state id will represent an invalid or a power down state.
+ */
+#define PLAT_MAX_RET_STATE ARM_LOCAL_STATE_RET
+/*
+ * This macro defines the deepest power down states possible. Any state ID
+ * higher than this is invalid.
+ */
+#define PLAT_MAX_OFF_STATE ARM_LOCAL_STATE_OFF
+
+/*******************************************************************************
+ * Size of the per-cpu data in bytes that should be reserved in the generic
+ * per-cpu data structure for the FVP port.
+ ******************************************************************************/
+#define PLAT_PCPU_DATA_SIZE 2
+
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/st/stm32mp1/include/stm32mp1_context.h b/plat/st/stm32mp1/include/stm32mp1_context.h
new file mode 100644
index 000000000..fd08afc7d
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_context.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_CONTEXT_H__
+#define __STM32MP1_CONTEXT_H__
+
+#include <stdint.h>
+
+int stm32_save_boot_interface(uint32_t interface, uint32_t instance);
+
+#endif /* __STM32MP1_CONTEXT_H__ */
diff --git a/plat/st/stm32mp1/include/stm32mp1_dt.h b/plat/st/stm32mp1/include/stm32mp1_dt.h
new file mode 100644
index 000000000..58e10d19a
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_dt.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_DT_H__
+#define __STM32MP1_DT_H__
+
+#include <stdbool.h>
+
+struct dt_node_info {
+ uint32_t base;
+ int32_t clock;
+ int32_t reset;
+ bool status;
+ bool sec_status;
+};
+
+/*******************************************************************************
+ * Function and variable prototypes
+ ******************************************************************************/
+int dt_open_and_check(void);
+int fdt_get_address(void **fdt_addr);
+bool fdt_check_node(int node);
+bool fdt_check_status(int node);
+bool fdt_check_secure_status(int node);
+uint32_t fdt_read_uint32_default(int node, const char *prop_name,
+ uint32_t dflt_value);
+int fdt_read_uint32_array(int node, const char *prop_name,
+ uint32_t *array, uint32_t count);
+int dt_set_pinctrl_config(int node);
+int dt_set_stdout_pinctrl(void);
+void dt_fill_device_info(struct dt_node_info *info, int node);
+int dt_get_node(struct dt_node_info *info, int offset, const char *compat);
+int dt_get_stdout_uart_info(struct dt_node_info *info);
+int dt_get_stdout_node_offset(void);
+uint32_t dt_get_ddr_size(void);
+const char *dt_get_board_model(void);
+
+#endif /* __STM32MP1_DT_H__ */
diff --git a/plat/st/stm32mp1/include/stm32mp1_private.h b/plat/st/stm32mp1/include/stm32mp1_private.h
new file mode 100644
index 000000000..a789d53e6
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_private.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_PRIVATE_H__
+#define __STM32MP1_PRIVATE_H__
+
+void stm32mp1_io_setup(void);
+void configure_mmu(void);
+
+void stm32mp1_arch_security_setup(void);
+void stm32mp1_security_setup(void);
+
+void stm32mp1_save_boot_ctx_address(uintptr_t address);
+uintptr_t stm32mp1_get_boot_ctx_address(void);
+
+void stm32mp1_gic_pcpu_init(void);
+void stm32mp1_gic_init(void);
+
+#endif /* __STM32MP1_PRIVATE_H__ */
diff --git a/plat/st/stm32mp1/plat_bl2_mem_params_desc.c b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
new file mode 100644
index 000000000..6f5bc4cc1
--- /dev/null
+++ b/plat/st/stm32mp1/plat_bl2_mem_params_desc.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <desc_image_load.h>
+#include <platform.h>
+#include <platform_def.h>
+
+/*******************************************************************************
+ * Following descriptor provides BL image/ep information that gets used
+ * by BL2 to load the images and also subset of this information is
+ * passed to next BL image. The image loading sequence is managed by
+ * populating the images in required loading order. The image execution
+ * sequence is managed by populating the `next_handoff_image_id` with
+ * the next executable image id.
+ ******************************************************************************/
+static bl_mem_params_node_t bl2_mem_params_descs[] = {
+ /* Fill BL32 related information */
+ {
+ .image_id = BL32_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ SECURE | EXECUTABLE | EP_FIRST_EXE),
+
+ .ep_info.pc = BL32_BASE,
+ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t,
+ IMAGE_ATTRIB_PLAT_SETUP),
+
+ .image_info.image_base = BL32_BASE,
+ .image_info.image_max_size = BL32_LIMIT - BL32_BASE,
+
+ .next_handoff_image_id = BL33_IMAGE_ID,
+ },
+
+ /* Fill BL33 related information */
+ {
+ .image_id = BL33_IMAGE_ID,
+
+ SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP,
+ VERSION_2, entry_point_info_t,
+ NON_SECURE | EXECUTABLE),
+
+ .ep_info.pc = PLAT_STM32MP1_NS_IMAGE_OFFSET,
+ .ep_info.spsr = SPSR_MODE32(MODE32_svc, SPSR_T_ARM,
+ SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS),
+
+ SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
+ VERSION_2, image_info_t, 0),
+
+ .image_info.image_base = PLAT_STM32MP1_NS_IMAGE_OFFSET,
+ .image_info.image_max_size = STM32MP1_DDR_MAX_SIZE -
+ (PLAT_STM32MP1_NS_IMAGE_OFFSET - STM32MP1_DDR_BASE),
+
+ .next_handoff_image_id = INVALID_IMAGE_ID,
+ }
+};
+
+REGISTER_BL_IMAGE_DESCS(bl2_mem_params_descs)
diff --git a/plat/st/stm32mp1/plat_image_load.c b/plat/st/stm32mp1/plat_image_load.c
new file mode 100644
index 000000000..3c6d677a0
--- /dev/null
+++ b/plat/st/stm32mp1/plat_image_load.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <desc_image_load.h>
+
+/*******************************************************************************
+ * This function flushes the data structures so that they are visible
+ * in memory for the next BL image.
+ ******************************************************************************/
+void plat_flush_next_bl_params(void)
+{
+ flush_bl_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of loadable images.
+ ******************************************************************************/
+bl_load_info_t *plat_get_bl_image_load_info(void)
+{
+ return get_bl_load_info_from_mem_params_desc();
+}
+
+/*******************************************************************************
+ * This function returns the list of executable images.
+ ******************************************************************************/
+bl_params_t *plat_get_next_bl_params(void)
+{
+ return get_next_bl_params_from_mem_params_desc();
+}
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
new file mode 100644
index 000000000..3f938d904
--- /dev/null
+++ b/plat/st/stm32mp1/platform.mk
@@ -0,0 +1,148 @@
+#
+# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ARM_CORTEX_A7 := yes
+ARM_WITH_NEON := yes
+LOAD_IMAGE_V2 := 1
+BL2_AT_EL3 := 1
+ENABLE_PLAT_COMPAT := 0
+USE_COHERENT_MEM := 0
+
+STM32_TF_VERSION ?= 0
+
+# Not needed for Cortex-A7
+WORKAROUND_CVE_2017_5715:= 0
+
+PLAT_INCLUDES := -Iplat/st/stm32mp1/include/
+PLAT_INCLUDES += -Iinclude/common/tbbr
+PLAT_INCLUDES += -Iinclude/drivers/st
+
+# Device tree
+STM32_DTB_FILE_NAME ?= stm32mp157c-ev1.dtb
+FDT_SOURCES := $(addprefix fdts/, $(patsubst %.dtb,%.dts,$(STM32_DTB_FILE_NAME)))
+DTC_FLAGS += -Wno-unit_address_vs_reg
+
+include lib/libfdt/libfdt.mk
+
+PLAT_BL_COMMON_SOURCES := plat/st/stm32mp1/stm32mp1_common.c
+
+PLAT_BL_COMMON_SOURCES += drivers/console/aarch32/console.S \
+ drivers/st/uart/aarch32/stm32_console.S
+
+ifneq (${ENABLE_STACK_PROTECTOR},0)
+PLAT_BL_COMMON_SOURCES += plat/st/stm32mp1/stm32mp1_stack_protector.c
+endif
+
+include lib/xlat_tables_v2/xlat_tables.mk
+PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS}
+
+PLAT_BL_COMMON_SOURCES += lib/cpus/aarch32/cortex_a7.S
+
+PLAT_BL_COMMON_SOURCES += ${LIBFDT_SRCS} \
+ drivers/arm/tzc/tzc400.c \
+ drivers/delay_timer/delay_timer.c \
+ drivers/delay_timer/generic_delay_timer.c \
+ drivers/st/clk/stm32mp1_clk.c \
+ drivers/st/clk/stm32mp1_clkfunc.c \
+ drivers/st/ddr/stm32mp1_ddr_helpers.c \
+ drivers/st/gpio/stm32_gpio.c \
+ drivers/st/pmic/stm32_i2c.c \
+ drivers/st/pmic/stm32mp1_pmic.c \
+ drivers/st/pmic/stpmu1.c \
+ drivers/st/reset/stm32mp1_reset.c \
+ plat/st/stm32mp1/stm32mp1_context.c \
+ plat/st/stm32mp1/stm32mp1_dt.c \
+ plat/st/stm32mp1/stm32mp1_helper.S \
+ plat/st/stm32mp1/stm32mp1_security.c
+
+BL2_SOURCES += drivers/io/io_dummy.c \
+ drivers/io/io_storage.c \
+ plat/st/stm32mp1/bl2_io_storage.c \
+ plat/st/stm32mp1/bl2_plat_setup.c
+
+BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \
+ drivers/st/ddr/stm32mp1_ram.c
+
+BL2_SOURCES += common/desc_image_load.c \
+ plat/st/stm32mp1/plat_bl2_mem_params_desc.c \
+ plat/st/stm32mp1/plat_image_load.c
+
+# For memory footprint optimization, build with thumb and interwork support
+ASFLAGS += -mthumb -mthumb-interwork
+TF_CFLAGS += -mthumb -mthumb-interwork
+
+# Macros and rules to build TF binary
+STM32_TF_ELF_LDFLAGS := --hash-style=gnu --as-needed
+STM32_DT_BASENAME := $(STM32_DTB_FILE_NAME:.dtb=)
+STM32_TF_STM32 := ${BUILD_PLAT}/tf-a-${STM32_DT_BASENAME}.stm32
+STM32_TF_BINARY := $(STM32_TF_STM32:.stm32=.bin)
+STM32_TF_MAPFILE := $(STM32_TF_STM32:.stm32=.map)
+STM32_TF_LINKERFILE := $(STM32_TF_STM32:.stm32=.ld)
+STM32_TF_ELF := $(STM32_TF_STM32:.stm32=.elf)
+STM32_TF_DTBFILE := ${BUILD_PLAT}/fdts/${STM32_DTB_FILE_NAME}
+STM32_TF_OBJS := ${BUILD_PLAT}/stm32mp1.o
+
+# Variables for use with stm32image
+STM32IMAGEPATH ?= tools/stm32image
+STM32IMAGE ?= ${STM32IMAGEPATH}/stm32image${BIN_EXT}
+
+.PHONY: ${STM32_TF_STM32}
+.SUFFIXES:
+
+all: check_dtc_version ${STM32_TF_STM32} stm32image
+
+ifeq ($(AARCH32_SP),sp_min)
+# BL32 is built only if using SP_MIN
+BL32_DEP := bl32
+BL32_PATH := -DBL32_BIN_PATH=\"${BUILD_PLAT}/bl32.bin\"
+endif
+
+distclean realclean clean: clean_stm32image
+
+stm32image:
+ ${Q}${MAKE} CPPFLAGS="" --no-print-directory -C ${STM32IMAGEPATH}
+
+clean_stm32image:
+ ${Q}${MAKE} --no-print-directory -C ${STM32IMAGEPATH} clean
+
+check_dtc_version:
+ $(eval DTC_V = $(shell $(DTC) -v | awk '{print $$NF}'))
+ $(eval DTC_VERSION = $(shell printf "%d" $(shell echo ${DTC_V} | cut -d- -f1 | sed "s/\./0/g")))
+ @if [ ${DTC_VERSION} -lt 10404 ]; then \
+ echo "dtc version too old (${DTC_V}), you need at least version 1.4.4"; \
+ false; \
+ fi
+
+
+${STM32_TF_OBJS}: plat/st/stm32mp1/stm32mp1.S bl2 ${BL32_DEP} ${STM32_TF_DTBFILE}
+ @echo " AS $<"
+ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} \
+ ${BL32_PATH} \
+ -DBL2_BIN_PATH=\"${BUILD_PLAT}/bl2.bin\" \
+ -DDTB_BIN_PATH=\"${STM32_TF_DTBFILE}\" \
+ -c plat/st/stm32mp1/stm32mp1.S -o $@
+
+${STM32_TF_LINKERFILE}: plat/st/stm32mp1/stm32mp1.ld.S
+ @echo " LDS $<"
+ ${Q}${AS} ${ASFLAGS} ${TF_CFLAGS} -P -E $< -o $@
+
+${STM32_TF_ELF}: ${STM32_TF_OBJS} ${STM32_TF_LINKERFILE}
+ @echo " LDS $<"
+ ${Q}${LD} -o $@ ${STM32_TF_ELF_LDFLAGS} -Map=${STM32_TF_MAPFILE} --script ${STM32_TF_LINKERFILE} ${STM32_TF_OBJS}
+
+${STM32_TF_BINARY}: ${STM32_TF_ELF}
+ ${Q}${OC} -O binary ${STM32_TF_ELF} $@
+ @echo
+ @echo "Built $@ successfully"
+ @echo
+
+${STM32_TF_STM32}: stm32image ${STM32_TF_BINARY}
+ @echo
+ @echo "Generated $@"
+ $(eval LOADADDR = $(shell cat ${STM32_TF_MAPFILE} | grep RAM | awk '{print $$2}'))
+ $(eval ENTRY = $(shell cat ${STM32_TF_MAPFILE} | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
+ ${STM32IMAGE} -s ${STM32_TF_BINARY} -d $@ -l $(LOADADDR) -e ${ENTRY} -v ${STM32_TF_VERSION}
+ @echo
diff --git a/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
new file mode 100644
index 000000000..9fde15387
--- /dev/null
+++ b/plat/st/stm32mp1/sp_min/sp_min-stm32mp1.mk
@@ -0,0 +1,21 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+SP_MIN_WITH_SECURE_FIQ := 1
+
+BL32_SOURCES += plat/common/aarch32/platform_mp_stack.S \
+ plat/st/stm32mp1/sp_min/sp_min_setup.c \
+ plat/st/stm32mp1/stm32mp1_pm.c \
+ plat/st/stm32mp1/stm32mp1_topology.c
+# Generic GIC v2
+BL32_SOURCES += drivers/arm/gic/common/gic_common.c \
+ drivers/arm/gic/v2/gicv2_helpers.c \
+ drivers/arm/gic/v2/gicv2_main.c \
+ plat/common/plat_gicv2.c \
+ plat/st/stm32mp1/stm32mp1_gic.c
+
+# Generic PSCI
+BL32_SOURCES += plat/common/plat_psci_common.c
diff --git a/plat/st/stm32mp1/sp_min/sp_min_setup.c b/plat/st/stm32mp1/sp_min/sp_min_setup.c
new file mode 100644
index 000000000..1329bdb89
--- /dev/null
+++ b/plat/st/stm32mp1/sp_min/sp_min_setup.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_gic.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <console.h>
+#include <context.h>
+#include <context_mgmt.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <generic_delay_timer.h>
+#include <mmio.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <platform_sp_min.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <string.h>
+#include <tzc400.h>
+#include <xlat_tables_v2.h>
+
+/******************************************************************************
+ * Placeholder variables for copying the arguments that have been passed to
+ * BL32 from BL2.
+ ******************************************************************************/
+static entry_point_info_t bl33_image_ep_info;
+
+/*******************************************************************************
+ * Interrupt handler for FIQ (secure IRQ)
+ ******************************************************************************/
+void sp_min_plat_fiq_handler(uint32_t id)
+{
+ switch (id) {
+ case STM32MP1_IRQ_TZC400:
+ ERROR("STM32MP1_IRQ_TZC400 generated\n");
+ panic();
+ break;
+ case STM32MP1_IRQ_AXIERRIRQ:
+ ERROR("STM32MP1_IRQ_AXIERRIRQ generated\n");
+ panic();
+ break;
+ default:
+ ERROR("SECURE IT handler not define for it : %i", id);
+ break;
+ }
+}
+
+/*******************************************************************************
+ * Return a pointer to the 'entry_point_info' structure of the next image for
+ * the security state specified. BL33 corresponds to the non-secure image type
+ * while BL32 corresponds to the secure image type. A NULL pointer is returned
+ * if the image does not exist.
+ ******************************************************************************/
+entry_point_info_t *sp_min_plat_get_bl33_ep_info(void)
+{
+ entry_point_info_t *next_image_info;
+
+ next_image_info = &bl33_image_ep_info;
+
+ if (next_image_info->pc == 0U) {
+ return NULL;
+ }
+
+ return next_image_info;
+}
+
+/*******************************************************************************
+ * Perform any BL32 specific platform actions.
+ ******************************************************************************/
+void sp_min_early_platform_setup2(u_register_t arg0, u_register_t arg1,
+ u_register_t arg2, u_register_t arg3)
+{
+ struct dt_node_info dt_dev_info;
+ int result;
+ bl_params_t *params_from_bl2 = (bl_params_t *)arg0;
+
+ /* Imprecise aborts can be masked in NonSecure */
+ write_scr(read_scr() | SCR_AW_BIT);
+
+ assert(params_from_bl2 != NULL);
+ assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
+ assert(params_from_bl2->h.version >= VERSION_2);
+
+ bl_params_node_t *bl_params = params_from_bl2->head;
+
+ /*
+ * Copy BL33 entry point information.
+ * They are stored in Secure RAM, in BL2's address space.
+ */
+ while (bl_params != NULL) {
+ if (bl_params->image_id == BL33_IMAGE_ID) {
+ bl33_image_ep_info = *bl_params->ep_info;
+ break;
+ }
+
+ bl_params = bl_params->next_params_info;
+ }
+
+ if (dt_open_and_check() < 0) {
+ panic();
+ }
+
+ if (stm32mp1_clk_probe() < 0) {
+ panic();
+ }
+
+ result = dt_get_stdout_uart_info(&dt_dev_info);
+
+ if ((result > 0) && dt_dev_info.status) {
+ if (console_init(dt_dev_info.base, 0, STM32MP1_UART_BAUDRATE)
+ == 0) {
+ panic();
+ }
+ }
+}
+
+/*******************************************************************************
+ * Initialize the MMU, security and the GIC.
+ ******************************************************************************/
+void sp_min_platform_setup(void)
+{
+ mmap_add_region(BL_CODE_BASE, BL_CODE_BASE,
+ BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE);
+
+ configure_mmu();
+
+ /* Initialize tzc400 after DDR initialization */
+ stm32mp1_security_setup();
+
+ generic_delay_timer_init();
+
+ stm32mp1_gic_init();
+}
+
+void sp_min_plat_arch_setup(void)
+{
+}
diff --git a/plat/st/stm32mp1/stm32mp1.S b/plat/st/stm32mp1/stm32mp1.S
new file mode 100644
index 000000000..7255fe5aa
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1.S
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef BL32_BIN_PATH
+.section .bl32_image
+.incbin BL32_BIN_PATH
+#endif
+
+.section .bl2_image
+.incbin BL2_BIN_PATH
+
+.section .dtb_image
+.incbin DTB_BIN_PATH
diff --git a/plat/st/stm32mp1/stm32mp1.ld.S b/plat/st/stm32mp1/stm32mp1.ld.S
new file mode 100644
index 000000000..0d7a8bb7c
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1.ld.S
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __STM32MP1_LD_S__
+#define __STM32MP1_LD_S__
+#include <platform_def.h>
+#include <xlat_tables_defs.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+
+ENTRY(__BL2_IMAGE_START__)
+
+MEMORY {
+ HEADER (rw) : ORIGIN = 0x00000000, LENGTH = 0x3000
+ RAM (rwx) : ORIGIN = STM32MP1_BINARY_BASE, LENGTH = STM32MP1_BINARY_SIZE
+}
+
+SECTIONS
+{
+ /*
+ * TF mapping must conform to ROM code specification.
+ */
+ .header : {
+ __HEADER_START__ = .;
+ KEEP(*(.header))
+ . = ALIGN(4);
+ __HEADER_END__ = .;
+ } >HEADER
+
+ . = STM32MP1_BINARY_BASE;
+ .data . : {
+ . = ALIGN(PAGE_SIZE);
+ __DATA_START__ = .;
+ *(.data*)
+
+ /*
+ * dtb.
+ * The strongest and only alignment contraint is MMU 4K page.
+ * Indeed as images below will be removed, 4K pages will be re-used.
+ */
+ . = ( STM32MP1_DTB_BASE - STM32MP1_BINARY_BASE );
+ __DTB_IMAGE_START__ = .;
+ *(.dtb_image*)
+ __DTB_IMAGE_END__ = .;
+
+ /*
+ * bl2.
+ * The strongest and only alignment contraint is MMU 4K page.
+ * Indeed as images below will be removed, 4K pages will be re-used.
+ */
+ . = ( STM32MP1_BL2_BASE - STM32MP1_BINARY_BASE );
+ __BL2_IMAGE_START__ = .;
+ *(.bl2_image*)
+ __BL2_IMAGE_END__ = .;
+
+ /*
+ * bl32 will be settled by bl2.
+ * The strongest and only alignment constraint is 8 words to simplify
+ * memraise8 assembly code.
+ */
+ . = ( STM32MP1_BL32_BASE - STM32MP1_BINARY_BASE );
+ __BL32_IMAGE_START__ = .;
+ *(.bl32_image*)
+ __BL32_IMAGE_END__ = .;
+
+ __DATA_END__ = .;
+ } >RAM
+
+ __TF_END__ = .;
+
+}
+#endif /*__STM32MP1_LD_S__*/
diff --git a/plat/st/stm32mp1/stm32mp1_common.c b/plat/st/stm32mp1/stm32mp1_common.c
new file mode 100644
index 000000000..7d84da1f8
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_common.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <bl_common.h>
+#include <debug.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <platform.h>
+#include <stm32mp1_private.h>
+#include <xlat_tables_v2.h>
+
+#define MAP_SRAM MAP_REGION_FLAT(STM32MP1_SRAM_BASE, \
+ STM32MP1_SRAM_SIZE, \
+ MT_MEMORY | \
+ MT_RW | \
+ MT_SECURE | \
+ MT_EXECUTE_NEVER)
+
+#define MAP_DEVICE1 MAP_REGION_FLAT(STM32MP1_DEVICE1_BASE, \
+ STM32MP1_DEVICE1_SIZE, \
+ MT_DEVICE | \
+ MT_RW | \
+ MT_SECURE | \
+ MT_EXECUTE_NEVER)
+
+#define MAP_DEVICE2 MAP_REGION_FLAT(STM32MP1_DEVICE2_BASE, \
+ STM32MP1_DEVICE2_SIZE, \
+ MT_DEVICE | \
+ MT_RW | \
+ MT_SECURE | \
+ MT_EXECUTE_NEVER)
+
+#define MAP_DDR MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
+ STM32MP1_DDR_MAX_SIZE, \
+ MT_MEMORY | \
+ MT_RW | \
+ MT_SECURE | \
+ MT_EXECUTE_NEVER)
+
+#define MAP_DDR_NS MAP_REGION_FLAT(STM32MP1_DDR_BASE, \
+ STM32MP1_DDR_MAX_SIZE, \
+ MT_MEMORY | \
+ MT_RW | \
+ MT_NS | \
+ MT_EXECUTE_NEVER)
+
+#if defined(IMAGE_BL2)
+static const mmap_region_t stm32mp1_mmap[] = {
+ MAP_SRAM,
+ MAP_DEVICE1,
+ MAP_DEVICE2,
+ MAP_DDR,
+ {0}
+};
+#endif
+#if defined(IMAGE_BL32)
+static const mmap_region_t stm32mp1_mmap[] = {
+ MAP_SRAM,
+ MAP_DEVICE1,
+ MAP_DEVICE2,
+ MAP_DDR_NS,
+ {0}
+};
+#endif
+
+void configure_mmu(void)
+{
+ mmap_add(stm32mp1_mmap);
+ init_xlat_tables();
+
+ enable_mmu_svc_mon(0);
+}
+
+uintptr_t plat_get_ns_image_entrypoint(void)
+{
+ return BL33_BASE;
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return read_cntfrq_el0();
+}
+
+/* Functions to save and get boot context address given by ROM code */
+static uintptr_t boot_ctx_address;
+
+void stm32mp1_save_boot_ctx_address(uintptr_t address)
+{
+ boot_ctx_address = address;
+}
+
+uintptr_t stm32mp1_get_boot_ctx_address(void)
+{
+ return boot_ctx_address;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_context.c b/plat/st/stm32mp1/stm32mp1_context.c
new file mode 100644
index 000000000..245fd17d7
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_context.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_context.h>
+
+#define TAMP_BOOT_ITF_BACKUP_REG_ID U(20)
+#define TAMP_BOOT_ITF_MASK U(0x0000FF00)
+#define TAMP_BOOT_ITF_SHIFT 8
+
+int stm32_save_boot_interface(uint32_t interface, uint32_t instance)
+{
+ uint32_t tamp_clk_off = 0;
+ uint32_t bkpr_itf_idx = tamp_bkpr(TAMP_BOOT_ITF_BACKUP_REG_ID);
+
+ if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+ tamp_clk_off = 1;
+ if (stm32mp1_clk_enable(RTCAPB) != 0) {
+ return -EINVAL;
+ }
+ }
+
+ mmio_clrsetbits_32(bkpr_itf_idx,
+ TAMP_BOOT_ITF_MASK,
+ ((interface << 4) | (instance & 0xFU)) <<
+ TAMP_BOOT_ITF_SHIFT);
+
+ if (tamp_clk_off != 0U) {
+ if (stm32mp1_clk_disable(RTCAPB) != 0) {
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
new file mode 100644
index 000000000..bb3fecf6d
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_DEF_H
+#define STM32MP1_DEF_H
+
+#include <tbbr_img_def.h>
+#include <utils_def.h>
+#include <xlat_tables_defs.h>
+
+/*******************************************************************************
+ * STM32MP1 memory map related constants
+ ******************************************************************************/
+
+#define STM32MP1_SRAM_BASE U(0x2FFC0000)
+#define STM32MP1_SRAM_SIZE U(0x00040000)
+
+/* DDR configuration */
+#define STM32MP1_DDR_BASE U(0xC0000000)
+#define STM32MP1_DDR_SIZE_DFLT U(0x20000000) /* 512 MB */
+#define STM32MP1_DDR_MAX_SIZE U(0x40000000) /* Max 1GB */
+#define STM32MP1_DDR_SPEED_DFLT 528
+
+/* DDR power initializations */
+#ifndef __ASSEMBLY__
+enum ddr_type {
+ STM32MP_DDR3,
+ STM32MP_LPDDR2,
+};
+#endif
+
+/* Section used inside TF binaries */
+#define STM32MP1_PARAM_LOAD_SIZE U(0x00002400) /* 9 Ko for param */
+/* 256 Octets reserved for header */
+#define STM32MP1_HEADER_SIZE U(0x00000100)
+
+#define STM32MP1_BINARY_BASE (STM32MP1_SRAM_BASE + \
+ STM32MP1_PARAM_LOAD_SIZE + \
+ STM32MP1_HEADER_SIZE)
+
+#define STM32MP1_BINARY_SIZE (STM32MP1_SRAM_SIZE - \
+ (STM32MP1_PARAM_LOAD_SIZE + \
+ STM32MP1_HEADER_SIZE))
+
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP1_BL32_SIZE U(0x00012000) /* 72 Ko for BL32 */
+#else
+#define STM32MP1_BL32_SIZE U(0x00011000) /* 68 Ko for BL32 */
+#endif
+
+#define STM32MP1_BL32_BASE (STM32MP1_SRAM_BASE + \
+ STM32MP1_SRAM_SIZE - \
+ STM32MP1_BL32_SIZE)
+
+#if STACK_PROTECTOR_ENABLED
+#define STM32MP1_BL2_SIZE U(0x00015000) /* 84 Ko for BL2 */
+#else
+#define STM32MP1_BL2_SIZE U(0x00013000) /* 76 Ko for BL2 */
+#endif
+
+#define STM32MP1_BL2_BASE (STM32MP1_BL32_BASE - \
+ STM32MP1_BL2_SIZE)
+
+/* BL2 and BL32/sp_min require 5 tables */
+#define MAX_XLAT_TABLES 5
+
+/*
+ * MAX_MMAP_REGIONS is usually:
+ * BL stm32mp1_mmap size + mmap regions in *_plat_arch_setup
+ */
+#if defined(IMAGE_BL2)
+ #define MAX_MMAP_REGIONS 11
+#endif
+#if defined(IMAGE_BL32)
+ #define MAX_MMAP_REGIONS 6
+#endif
+
+/* DTB initialization value */
+#define STM32MP1_DTB_SIZE U(0x00004000) /* 16Ko for DTB */
+
+#define STM32MP1_DTB_BASE (STM32MP1_BL2_BASE - \
+ STM32MP1_DTB_SIZE)
+
+#define STM32MP1_BL33_BASE (STM32MP1_DDR_BASE + U(0x100000))
+
+/*******************************************************************************
+ * STM32MP1 device/io map related constants (used for MMU)
+ ******************************************************************************/
+#define STM32MP1_DEVICE1_BASE U(0x40000000)
+#define STM32MP1_DEVICE1_SIZE U(0x40000000)
+
+#define STM32MP1_DEVICE2_BASE U(0x80000000)
+#define STM32MP1_DEVICE2_SIZE U(0x40000000)
+
+/*******************************************************************************
+ * STM32MP1 RCC
+ ******************************************************************************/
+#define RCC_BASE U(0x50000000)
+
+/*******************************************************************************
+ * STM32MP1 PWR
+ ******************************************************************************/
+#define PWR_BASE U(0x50001000)
+
+/*******************************************************************************
+ * STM32MP1 UART
+ ******************************************************************************/
+#define USART1_BASE U(0x5C000000)
+#define USART2_BASE U(0x4000E000)
+#define USART3_BASE U(0x4000F000)
+#define UART4_BASE U(0x40010000)
+#define UART5_BASE U(0x40011000)
+#define USART6_BASE U(0x44003000)
+#define UART7_BASE U(0x40018000)
+#define UART8_BASE U(0x40019000)
+#define STM32MP1_DEBUG_USART_BASE UART4_BASE
+#define STM32MP1_UART_BAUDRATE 115200
+
+/*******************************************************************************
+ * STM32MP1 GIC-400
+ ******************************************************************************/
+#define STM32MP1_GICD_BASE U(0xA0021000)
+#define STM32MP1_GICC_BASE U(0xA0022000)
+#define STM32MP1_GICH_BASE U(0xA0024000)
+#define STM32MP1_GICV_BASE U(0xA0026000)
+
+/*******************************************************************************
+ * STM32MP1 TZC (TZ400)
+ ******************************************************************************/
+#define STM32MP1_TZC_BASE U(0x5C006000)
+
+#define STM32MP1_TZC_A7_ID U(0)
+#define STM32MP1_TZC_LCD_ID U(3)
+#define STM32MP1_TZC_GPU_ID U(4)
+#define STM32MP1_TZC_MDMA_ID U(5)
+#define STM32MP1_TZC_DMA_ID U(6)
+#define STM32MP1_TZC_USB_HOST_ID U(7)
+#define STM32MP1_TZC_USB_OTG_ID U(8)
+#define STM32MP1_TZC_SDMMC_ID U(9)
+#define STM32MP1_TZC_ETH_ID U(10)
+#define STM32MP1_TZC_DAP_ID U(15)
+
+#define STM32MP1_MEMORY_NS 0
+#define STM32MP1_MEMORY_SECURE 1
+
+#define STM32MP1_FILTER_BIT_ALL 3
+
+/*******************************************************************************
+ * STM32MP1 SDMMC
+ ******************************************************************************/
+#define STM32MP1_SDMMC1_BASE U(0x58005000)
+#define STM32MP1_SDMMC2_BASE U(0x58007000)
+#define STM32MP1_SDMMC3_BASE U(0x48004000)
+
+#define STM32MP1_SD_INIT_FREQ 400000 /*400 KHz*/
+#define STM32MP1_SD_NORMAL_SPEED_MAX_FREQ 25000000 /*25 MHz*/
+#define STM32MP1_SD_HIGH_SPEED_MAX_FREQ 50000000 /*50 MHz*/
+#define STM32MP1_EMMC_INIT_FREQ STM32MP1_SD_INIT_FREQ
+#define STM32MP1_EMMC_NORMAL_SPEED_MAX_FREQ 26000000 /*26 MHz*/
+#define STM32MP1_EMMC_HIGH_SPEED_MAX_FREQ 52000000 /*52 MHz*/
+
+/*******************************************************************************
+ * STM32MP1 TAMP
+ ******************************************************************************/
+#define TAMP_BASE U(0x5C00A000)
+#define TAMP_BKP_REGISTER_BASE (TAMP_BASE + U(0x100))
+
+#if !(defined(__LINKER__) || defined(__ASSEMBLY__))
+static inline uint32_t tamp_bkpr(uint32_t idx)
+{
+ return TAMP_BKP_REGISTER_BASE + (idx << 2);
+}
+#endif
+
+/*******************************************************************************
+ * STM32MP1 DDRCTRL
+ ******************************************************************************/
+#define DDRCTRL_BASE U(0x5A003000)
+
+/*******************************************************************************
+ * STM32MP1 DDRPHYC
+ ******************************************************************************/
+#define DDRPHYC_BASE U(0x5A004000)
+
+/*******************************************************************************
+ * STM32MP1 I2C4
+ ******************************************************************************/
+#define I2C4_BASE U(0x5C002000)
+
+#endif /* STM32MP1_DEF_H */
diff --git a/plat/st/stm32mp1/stm32mp1_dt.c b/plat/st/stm32mp1/stm32mp1_dt.c
new file mode 100644
index 000000000..bde968a0b
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_dt.c
@@ -0,0 +1,476 @@
+/*
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <libfdt.h>
+#include <platform_def.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_clkfunc.h>
+#include <stm32mp1_ddr.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_ram.h>
+
+#define DT_GPIO_BANK_SHIFT 12
+#define DT_GPIO_BANK_MASK 0x1F000U
+#define DT_GPIO_PIN_SHIFT 8
+#define DT_GPIO_PIN_MASK 0xF00U
+#define DT_GPIO_MODE_MASK 0xFFU
+
+static int fdt_checked;
+
+static void *fdt = (void *)(uintptr_t)STM32MP1_DTB_BASE;
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Return 0 on success, else return a negative FDT_ERR_xxx error code.
+ ******************************************************************************/
+static int dt_set_gpio_config(int node)
+{
+ const fdt32_t *cuint, *slewrate;
+ int len, pinctrl_node, pinctrl_subnode;
+ uint32_t i;
+ uint32_t speed = GPIO_SPEED_LOW;
+ uint32_t pull = GPIO_NO_PULL;
+
+ cuint = fdt_getprop(fdt, node, "pinmux", &len);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ pinctrl_node = fdt_parent_offset(fdt, fdt_parent_offset(fdt, node));
+ if (pinctrl_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ slewrate = fdt_getprop(fdt, node, "slew-rate", NULL);
+ if (slewrate != NULL) {
+ speed = fdt32_to_cpu(*slewrate);
+ }
+
+ if (fdt_getprop(fdt, node, "bias-pull-up", NULL) != NULL) {
+ pull = GPIO_PULL_UP;
+ } else if (fdt_getprop(fdt, node, "bias-pull-down", NULL) != NULL) {
+ pull = GPIO_PULL_DOWN;
+ } else {
+ VERBOSE("No bias configured in node %d\n", node);
+ }
+
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ uint32_t pincfg;
+ uint32_t bank;
+ uint32_t pin;
+ uint32_t mode;
+ uint32_t alternate = GPIO_ALTERNATE_0;
+
+ pincfg = fdt32_to_cpu(*cuint);
+ cuint++;
+
+ bank = (pincfg & DT_GPIO_BANK_MASK) >> DT_GPIO_BANK_SHIFT;
+
+ pin = (pincfg & DT_GPIO_PIN_MASK) >> DT_GPIO_PIN_SHIFT;
+
+ mode = pincfg & DT_GPIO_MODE_MASK;
+
+ switch (mode) {
+ case 0:
+ mode = GPIO_MODE_INPUT;
+ break;
+ case 1 ... 16:
+ alternate = mode - 1U;
+ mode = GPIO_MODE_ALTERNATE;
+ break;
+ case 17:
+ mode = GPIO_MODE_ANALOG;
+ break;
+ default:
+ mode = GPIO_MODE_OUTPUT;
+ break;
+ }
+
+ if (fdt_getprop(fdt, node, "drive-open-drain", NULL) != NULL) {
+ mode |= GPIO_OPEN_DRAIN;
+ }
+
+ fdt_for_each_subnode(pinctrl_subnode, fdt, pinctrl_node) {
+ uint32_t bank_offset;
+ const fdt32_t *cuint2;
+
+ if (fdt_getprop(fdt, pinctrl_subnode,
+ "gpio-controller", NULL) == NULL) {
+ continue;
+ }
+
+ cuint2 = fdt_getprop(fdt, pinctrl_subnode, "reg", NULL);
+ if (cuint2 == NULL) {
+ continue;
+ }
+
+ if (bank == GPIO_BANK_Z) {
+ bank_offset = 0;
+ } else {
+ bank_offset = bank * STM32_GPIO_BANK_OFFSET;
+ }
+
+ if (fdt32_to_cpu(*cuint2) == bank_offset) {
+ int clk_id = fdt_get_clock_id(pinctrl_subnode);
+
+ if (clk_id < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if (stm32mp1_clk_enable((unsigned long)clk_id) <
+ 0) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ break;
+ }
+ }
+
+ set_gpio(bank, pin, mode, speed, pull, alternate);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function checks device tree file with its header.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_open_and_check(void)
+{
+ int ret = fdt_check_header(fdt);
+
+ if (ret == 0) {
+ fdt_checked = 1;
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * This function gets the address of the DT.
+ * If DT is OK, fdt_addr is filled with DT address.
+ * Returns 1 if success, 0 otherwise.
+ ******************************************************************************/
+int fdt_get_address(void **fdt_addr)
+{
+ if (fdt_checked == 1) {
+ *fdt_addr = fdt;
+ }
+
+ return fdt_checked;
+}
+
+/*******************************************************************************
+ * This function check the presence of a node (generic use of fdt library).
+ * Returns true if present, false else.
+ ******************************************************************************/
+bool fdt_check_node(int node)
+{
+ int len;
+ const char *cchar;
+
+ cchar = fdt_get_name(fdt, node, &len);
+
+ return (cchar != NULL) && (len >= 0);
+}
+
+/*******************************************************************************
+ * This function check the status of a node (generic use of fdt library).
+ * Returns true if "okay" or missing, false else.
+ ******************************************************************************/
+bool fdt_check_status(int node)
+{
+ int len;
+ const char *cchar;
+
+ cchar = fdt_getprop(fdt, node, "status", &len);
+ if (cchar == NULL) {
+ return true;
+ }
+
+ return strncmp(cchar, "okay", (size_t)len) == 0;
+}
+
+/*******************************************************************************
+ * This function check the secure-status of a node (generic use of fdt library).
+ * Returns true if "okay" or missing, false else.
+ ******************************************************************************/
+bool fdt_check_secure_status(int node)
+{
+ int len;
+ const char *cchar;
+
+ cchar = fdt_getprop(fdt, node, "secure-status", &len);
+ if (cchar == NULL) {
+ return true;
+ }
+
+ return strncmp(cchar, "okay", (size_t)len) == 0;
+}
+
+/*******************************************************************************
+ * This function reads a value of a node property (generic use of fdt
+ * library).
+ * Returns value if success, and a default value if property not found.
+ * Default value is passed as parameter.
+ ******************************************************************************/
+uint32_t fdt_read_uint32_default(int node, const char *prop_name,
+ uint32_t dflt_value)
+{
+ const fdt32_t *cuint;
+ int lenp;
+
+ cuint = fdt_getprop(fdt, node, prop_name, &lenp);
+ if (cuint == NULL) {
+ return dflt_value;
+ }
+
+ return fdt32_to_cpu(*cuint);
+}
+
+/*******************************************************************************
+ * This function reads a series of parameters in a node property
+ * (generic use of fdt library).
+ * It reads the values inside the device tree, from property name and node.
+ * The number of parameters is also indicated as entry parameter.
+ * Returns 0 if success, and a negative value else.
+ * If success, values are stored at the third parameter address.
+ ******************************************************************************/
+int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
+ uint32_t count)
+{
+ const fdt32_t *cuint;
+ int len;
+ uint32_t i;
+
+ cuint = fdt_getprop(fdt, node, prop_name, &len);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if ((uint32_t)len != (count * sizeof(uint32_t))) {
+ return -FDT_ERR_BADLAYOUT;
+ }
+
+ for (i = 0; i < ((uint32_t)len / sizeof(uint32_t)); i++) {
+ *array = fdt32_to_cpu(*cuint);
+ array++;
+ cuint++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the pin settings from DT information.
+ * When analyze and parsing is done, set the GPIO registers.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_set_pinctrl_config(int node)
+{
+ const fdt32_t *cuint;
+ int lenp = 0;
+ uint32_t i;
+
+ if (!fdt_check_status(node)) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cuint = fdt_getprop(fdt, node, "pinctrl-0", &lenp);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ for (i = 0; i < ((uint32_t)lenp / 4U); i++) {
+ int phandle_node, phandle_subnode;
+
+ phandle_node =
+ fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*cuint));
+ if (phandle_node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ fdt_for_each_subnode(phandle_subnode, fdt, phandle_node) {
+ int ret = dt_set_gpio_config(phandle_subnode);
+
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
+ cuint++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function gets the stdout pin configuration information from the DT.
+ * And then calls the sub-function to treat it and set GPIO registers.
+ * Returns 0 if success, and a negative value else.
+ ******************************************************************************/
+int dt_set_stdout_pinctrl(void)
+{
+ int node;
+
+ node = dt_get_stdout_node_offset();
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return dt_set_pinctrl_config(node);
+}
+
+/*******************************************************************************
+ * This function fills the generic information from a given node.
+ ******************************************************************************/
+void dt_fill_device_info(struct dt_node_info *info, int node)
+{
+ const fdt32_t *cuint;
+
+ cuint = fdt_getprop(fdt, node, "reg", NULL);
+ if (cuint != NULL) {
+ info->base = fdt32_to_cpu(*cuint);
+ } else {
+ info->base = 0;
+ }
+
+ cuint = fdt_getprop(fdt, node, "clocks", NULL);
+ if (cuint != NULL) {
+ cuint++;
+ info->clock = (int)fdt32_to_cpu(*cuint);
+ } else {
+ info->clock = -1;
+ }
+
+ cuint = fdt_getprop(fdt, node, "resets", NULL);
+ if (cuint != NULL) {
+ cuint++;
+ info->reset = (int)fdt32_to_cpu(*cuint);
+ } else {
+ info->reset = -1;
+ }
+
+ info->status = fdt_check_status(node);
+ info->sec_status = fdt_check_secure_status(node);
+}
+
+/*******************************************************************************
+ * This function retrieve the generic information from DT.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_node(struct dt_node_info *info, int offset, const char *compat)
+{
+ int node;
+
+ node = fdt_node_offset_by_compatible(fdt, offset, compat);
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ dt_fill_device_info(info, node);
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets the UART instance info of stdout from the DT.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_stdout_uart_info(struct dt_node_info *info)
+{
+ int node;
+
+ node = dt_get_stdout_node_offset();
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ dt_fill_device_info(info, node);
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets the stdout path node.
+ * It reads the value indicated inside the device tree.
+ * Returns node if success, and a negative value else.
+ ******************************************************************************/
+int dt_get_stdout_node_offset(void)
+{
+ int node;
+ const char *cchar;
+
+ node = fdt_path_offset(fdt, "/chosen");
+ if (node < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ cchar = fdt_getprop(fdt, node, "stdout-path", NULL);
+ if (cchar == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ node = -FDT_ERR_NOTFOUND;
+ if (strchr(cchar, (int)':') != NULL) {
+ const char *name;
+ char *str = (char *)cchar;
+ int len = 0;
+
+ while (strncmp(":", str, 1)) {
+ len++;
+ str++;
+ }
+
+ name = fdt_get_alias_namelen(fdt, cchar, len);
+
+ if (name != NULL) {
+ node = fdt_path_offset(fdt, name);
+ }
+ } else {
+ node = fdt_path_offset(fdt, cchar);
+ }
+
+ return node;
+}
+
+/*******************************************************************************
+ * This function gets DDR size information from the DT.
+ * Returns value in bytes if success, and STM32MP1_DDR_SIZE_DFLT else.
+ ******************************************************************************/
+uint32_t dt_get_ddr_size(void)
+{
+ int node;
+
+ node = fdt_node_offset_by_compatible(fdt, -1, DT_DDR_COMPAT);
+ if (node < 0) {
+ INFO("%s: Cannot read DDR node in DT\n", __func__);
+ return STM32MP1_DDR_SIZE_DFLT;
+ }
+
+ return fdt_read_uint32_default(node, "st,mem-size",
+ STM32MP1_DDR_SIZE_DFLT);
+}
+
+/*******************************************************************************
+ * This function retrieves board model from DT
+ * Returns string taken from model node, NULL otherwise
+ ******************************************************************************/
+const char *dt_get_board_model(void)
+{
+ int node = fdt_path_offset(fdt, "/");
+
+ if (node < 0) {
+ return NULL;
+ }
+
+ return (const char *)fdt_getprop(fdt, node, "model", NULL);
+}
diff --git a/plat/st/stm32mp1/stm32mp1_gic.c b/plat/st/stm32mp1/stm32mp1_gic.c
new file mode 100644
index 000000000..11eb0a3e2
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_gic.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <bl_common.h>
+#include <gicv2.h>
+#include <platform.h>
+#include <platform_def.h>
+#include <utils.h>
+
+#include <stm32mp1_private.h>
+
+/******************************************************************************
+ * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0
+ * interrupts.
+ *****************************************************************************/
+static const interrupt_prop_t stm32mp1_interrupt_props[] = {
+ PLATFORM_G1S_PROPS(GICV2_INTR_GROUP0),
+ PLATFORM_G0_PROPS(GICV2_INTR_GROUP0)
+};
+
+static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
+
+static const gicv2_driver_data_t platform_gic_data = {
+ .gicd_base = STM32MP1_GICD_BASE,
+ .gicc_base = STM32MP1_GICC_BASE,
+ .interrupt_props = stm32mp1_interrupt_props,
+ .interrupt_props_num = ARRAY_SIZE(stm32mp1_interrupt_props),
+ .target_masks = target_mask_array,
+ .target_masks_num = ARRAY_SIZE(target_mask_array),
+};
+
+void stm32mp1_gic_init(void)
+{
+ gicv2_driver_init(&platform_gic_data);
+ gicv2_distif_init();
+
+ stm32mp1_gic_pcpu_init();
+}
+
+void stm32mp1_gic_pcpu_init(void)
+{
+ gicv2_pcpu_distif_init();
+ gicv2_set_pe_target_mask(plat_my_core_pos());
+ gicv2_cpuif_enable();
+}
diff --git a/plat/st/stm32mp1/stm32mp1_helper.S b/plat/st/stm32mp1/stm32mp1_helper.S
new file mode 100644
index 000000000..b0ea0d8ed
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_helper.S
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <bl_common.h>
+#include <platform_def.h>
+#include <stm32_gpio.h>
+#include <stm32mp1_rcc.h>
+
+#define GPIO_BANK_G_ADDRESS 0x50008000
+#define GPIO_TX_PORT 11
+#define GPIO_TX_SHIFT (GPIO_TX_PORT << 1)
+#define GPIO_TX_ALT_SHIFT ((GPIO_TX_PORT - GPIO_ALT_LOWER_LIMIT) << 2)
+#define STM32MP1_HSI_CLK 64000000
+
+ .globl platform_mem_init
+ .globl plat_report_exception
+ .globl plat_get_my_entrypoint
+ .globl plat_secondary_cold_boot_setup
+ .globl plat_reset_handler
+ .globl plat_is_my_cpu_primary
+ .globl plat_my_core_pos
+ .globl plat_crash_console_init
+ .globl plat_crash_console_flush
+ .globl plat_crash_console_putc
+ .globl plat_panic_handler
+
+func platform_mem_init
+ /* Nothing to do, don't need to init SYSRAM */
+ bx lr
+endfunc platform_mem_init
+
+func plat_report_exception
+ bx lr
+endfunc plat_report_exception
+
+func plat_reset_handler
+ bx lr
+endfunc plat_reset_handler
+
+ /* ------------------------------------------------------------------
+ * unsigned long plat_get_my_entrypoint (void);
+ *
+ * Main job of this routine is to distinguish between a cold and warm
+ * boot.
+ *
+ * Currently supports only cold boot
+ * ------------------------------------------------------------------
+ */
+func plat_get_my_entrypoint
+ mov r0, #0
+ bx lr
+endfunc plat_get_my_entrypoint
+
+ /* ---------------------------------------------
+ * void plat_secondary_cold_boot_setup (void);
+ *
+ * Cold-booting secondary CPUs is not supported.
+ * ---------------------------------------------
+ */
+func plat_secondary_cold_boot_setup
+ b .
+endfunc plat_secondary_cold_boot_setup
+
+ /* -----------------------------------------------------
+ * unsigned int plat_is_my_cpu_primary (void);
+ *
+ * Find out whether the current cpu is the primary cpu.
+ * -----------------------------------------------------
+ */
+func plat_is_my_cpu_primary
+ ldcopr r0, MPIDR
+ ldr r1, =(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
+ and r0, r1
+ cmp r0, #STM32MP1_PRIMARY_CPU
+ moveq r0, #1
+ movne r0, #0
+ bx lr
+endfunc plat_is_my_cpu_primary
+
+ /* -------------------------------------------
+ * int plat_stm32mp1_get_core_pos(int mpidr);
+ *
+ * Return CorePos = (ClusterId * 4) + CoreId
+ * -------------------------------------------
+ */
+func plat_stm32mp1_get_core_pos
+ and r1, r0, #MPIDR_CPU_MASK
+ and r0, r0, #MPIDR_CLUSTER_MASK
+ add r0, r1, r0, LSR #6
+ bx lr
+endfunc plat_stm32mp1_get_core_pos
+
+ /* ------------------------------------
+ * unsigned int plat_my_core_pos(void)
+ * ------------------------------------
+ */
+func plat_my_core_pos
+ ldcopr r0, MPIDR
+ b plat_stm32mp1_get_core_pos
+endfunc plat_my_core_pos
+
+ /* ---------------------------------------------
+ * int plat_crash_console_init(void)
+ *
+ * Initialize the crash console without a C Runtime stack.
+ * ---------------------------------------------
+ */
+func plat_crash_console_init
+ /* Enable GPIOs for UART4 TX */
+ ldr r1, =(RCC_BASE + RCC_MP_AHB4ENSETR)
+ ldr r2, [r1]
+ /* Configure GPIO G11 */
+ orr r2, r2, #RCC_MP_AHB4ENSETR_GPIOGEN
+ str r2, [r1]
+ ldr r1, =GPIO_BANK_G_ADDRESS
+ /* Set GPIO mode alternate */
+ ldr r2, [r1, #GPIO_MODE_OFFSET]
+ bic r2, r2, #(GPIO_MODE_MASK << GPIO_TX_SHIFT)
+ orr r2, r2, #(GPIO_MODE_ALTERNATE << GPIO_TX_SHIFT)
+ str r2, [r1, #GPIO_MODE_OFFSET]
+ /* Set GPIO speed low */
+ ldr r2, [r1, #GPIO_SPEED_OFFSET]
+ bic r2, r2, #(GPIO_SPEED_MASK << GPIO_TX_SHIFT)
+ str r2, [r1, #GPIO_SPEED_OFFSET]
+ /* Set no-pull */
+ ldr r2, [r1, #GPIO_PUPD_OFFSET]
+ bic r2, r2, #(GPIO_PULL_MASK << GPIO_TX_SHIFT)
+ str r2, [r1, #GPIO_PUPD_OFFSET]
+ /* Set alternate AF6 */
+ ldr r2, [r1, #GPIO_AFRH_OFFSET]
+ bic r2, r2, #(GPIO_ALTERNATE_MASK << GPIO_TX_ALT_SHIFT)
+ orr r2, r2, #(GPIO_ALTERNATE_6 << GPIO_TX_ALT_SHIFT)
+ str r2, [r1, #GPIO_AFRH_OFFSET]
+
+ /* Enable UART clock, with HSI source */
+ ldr r1, =(RCC_BASE + RCC_UART24CKSELR)
+ mov r2, #RCC_UART24CKSELR_HSI
+ str r2, [r1]
+ ldr r1, =(RCC_BASE + RCC_MP_APB1ENSETR)
+ ldr r2, [r1]
+ orr r2, r2, #RCC_MP_APB1ENSETR_UART4EN
+ str r2, [r1]
+
+ ldr r0, =STM32MP1_DEBUG_USART_BASE
+ ldr r1, =STM32MP1_HSI_CLK
+ ldr r2, =STM32MP1_UART_BAUDRATE
+ b console_core_init
+endfunc plat_crash_console_init
+
+ /* ---------------------------------------------
+ * int plat_crash_console_flush(void)
+ *
+ * Flush the crash console without a C Runtime stack.
+ * ---------------------------------------------
+ */
+func plat_crash_console_flush
+ ldr r1, =STM32MP1_DEBUG_USART_BASE
+ b console_core_flush
+endfunc plat_crash_console_flush
+
+ /* ---------------------------------------------
+ * int plat_crash_console_putc(int c)
+ *
+ * Print a character on the crash console without a C Runtime stack.
+ * Clobber list : r1 - r3
+ *
+ * In case of bootloading through uart, we keep console crash as this.
+ * Characters could be sent to the programmer, but will be ignored.
+ * No specific code in that case.
+ * ---------------------------------------------
+ */
+func plat_crash_console_putc
+ ldr r1, =STM32MP1_DEBUG_USART_BASE
+ b console_core_putc
+endfunc plat_crash_console_putc
diff --git a/plat/st/stm32mp1/stm32mp1_pm.c b/plat/st/stm32mp1/stm32mp1_pm.c
new file mode 100644
index 000000000..e24af0e55
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_pm.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <boot_api.h>
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <errno.h>
+#include <gic_common.h>
+#include <gicv2.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <platform.h>
+#include <psci.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+
+static uint32_t stm32_sec_entrypoint;
+static uint32_t cntfrq_core0;
+
+#define SEND_SECURE_IT_TO_CORE_1 0x20000U
+
+/*******************************************************************************
+ * STM32MP1 handler called when a CPU is about to enter standby.
+ * call by core 1 to enter in wfi
+ ******************************************************************************/
+static void stm32_cpu_standby(plat_local_state_t cpu_state)
+{
+ uint32_t interrupt = GIC_SPURIOUS_INTERRUPT;
+
+ assert(cpu_state == ARM_LOCAL_STATE_RET);
+
+ /*
+ * Enter standby state
+ * dsb is good practice before using wfi to enter low power states
+ */
+ dsb();
+ while (interrupt == GIC_SPURIOUS_INTERRUPT) {
+ wfi();
+
+ /* Acknoledge IT */
+ interrupt = gicv2_acknowledge_interrupt();
+ /* If Interrupt == 1022 it will be acknowledged by non secure */
+ if ((interrupt != PENDING_G1_INTID) &&
+ (interrupt != GIC_SPURIOUS_INTERRUPT)) {
+ gicv2_end_of_interrupt(interrupt);
+ }
+ }
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be turned on. The
+ * mpidr determines the CPU to be turned on.
+ * call by core 0 to activate core 1
+ ******************************************************************************/
+static int stm32_pwr_domain_on(u_register_t mpidr)
+{
+ unsigned long current_cpu_mpidr = read_mpidr_el1();
+ uint32_t tamp_clk_off = 0;
+ uint32_t bkpr_core1_addr =
+ tamp_bkpr(BOOT_API_CORE1_BRANCH_ADDRESS_TAMP_BCK_REG_IDX);
+ uint32_t bkpr_core1_magic =
+ tamp_bkpr(BOOT_API_CORE1_MAGIC_NUMBER_TAMP_BCK_REG_IDX);
+
+ if (mpidr == current_cpu_mpidr) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if ((stm32_sec_entrypoint < STM32MP1_SRAM_BASE) ||
+ (stm32_sec_entrypoint > (STM32MP1_SRAM_BASE +
+ (STM32MP1_SRAM_SIZE - 1)))) {
+ return PSCI_E_INVALID_ADDRESS;
+ }
+
+ if (!stm32mp1_clk_is_enabled(RTCAPB)) {
+ tamp_clk_off = 1;
+ if (stm32mp1_clk_enable(RTCAPB) != 0) {
+ panic();
+ }
+ }
+
+ cntfrq_core0 = read_cntfrq_el0();
+
+ /* Write entrypoint in backup RAM register */
+ mmio_write_32(bkpr_core1_addr, stm32_sec_entrypoint);
+
+ /* Write magic number in backup register */
+ mmio_write_32(bkpr_core1_magic, BOOT_API_A7_CORE1_MAGIC_NUMBER);
+
+ if (tamp_clk_off != 0U) {
+ if (stm32mp1_clk_disable(RTCAPB) != 0) {
+ panic();
+ }
+ }
+
+ /* Generate an IT to core 1 */
+ mmio_write_32(STM32MP1_GICD_BASE + GICD_SGIR,
+ SEND_SECURE_IT_TO_CORE_1 | ARM_IRQ_SEC_SGI_0);
+
+ return PSCI_E_SUCCESS;
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be turned off. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+static void stm32_pwr_domain_off(const psci_power_state_t *target_state)
+{
+ /* Nothing to do */
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain is about to be suspended. The
+ * target_state encodes the power state that each level should transition to.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend(const psci_power_state_t *target_state)
+{
+ /* Nothing to do, power domain is not disabled */
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain has just been powered on after
+ * being turned off earlier. The target_state encodes the low power state that
+ * each level has woken up from.
+ * call by core 1 just after wake up
+ ******************************************************************************/
+static void stm32_pwr_domain_on_finish(const psci_power_state_t *target_state)
+{
+ stm32mp1_gic_pcpu_init();
+
+ write_cntfrq_el0(cntfrq_core0);
+}
+
+/*******************************************************************************
+ * STM32MP1 handler called when a power domain has just been powered on after
+ * having been suspended earlier. The target_state encodes the low power state
+ * that each level has woken up from.
+ ******************************************************************************/
+static void stm32_pwr_domain_suspend_finish(const psci_power_state_t
+ *target_state)
+{
+ /* Nothing to do, power domain is not disabled */
+}
+
+static void __dead2 stm32_pwr_domain_pwr_down_wfi(const psci_power_state_t
+ *target_state)
+{
+ ERROR("stm32mpu1 Power Down WFI: operation not handled.\n");
+ panic();
+}
+
+static void __dead2 stm32_system_off(void)
+{
+ ERROR("stm32mpu1 System Off: operation not handled.\n");
+ panic();
+}
+
+static void __dead2 stm32_system_reset(void)
+{
+ mmio_setbits_32(RCC_BASE + RCC_MP_GRSTCSETR, RCC_MP_GRSTCSETR_MPSYSRST);
+
+ /* Loop in case system reset is not immediately caught */
+ for ( ; ; ) {
+ ;
+ }
+}
+
+static int stm32_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ int pstate = psci_get_pstate_type(power_state);
+
+ if (pstate != 0) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if (psci_get_pstate_pwrlvl(power_state)) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if (psci_get_pstate_id(power_state)) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_RET;
+ req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_RUN;
+
+ return PSCI_E_SUCCESS;
+}
+
+static int stm32_validate_ns_entrypoint(uintptr_t entrypoint)
+{
+ /* The non-secure entry point must be in DDR */
+ if (entrypoint < STM32MP1_DDR_BASE) {
+ return PSCI_E_INVALID_ADDRESS;
+ }
+
+ return PSCI_E_SUCCESS;
+}
+
+static int stm32_node_hw_state(u_register_t target_cpu,
+ unsigned int power_level)
+{
+ /*
+ * The format of 'power_level' is implementation-defined, but 0 must
+ * mean a CPU. Only allow level 0.
+ */
+ if (power_level != MPIDR_AFFLVL0) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ /*
+ * From psci view the CPU 0 is always ON,
+ * CPU 1 can be SUSPEND or RUNNING.
+ * Therefore do not manage POWER OFF state and always return HW_ON.
+ */
+
+ return (int)HW_ON;
+}
+
+/*******************************************************************************
+ * Export the platform handlers. The ARM Standard platform layer will take care
+ * of registering the handlers with PSCI.
+ ******************************************************************************/
+static const plat_psci_ops_t stm32_psci_ops = {
+ .cpu_standby = stm32_cpu_standby,
+ .pwr_domain_on = stm32_pwr_domain_on,
+ .pwr_domain_off = stm32_pwr_domain_off,
+ .pwr_domain_suspend = stm32_pwr_domain_suspend,
+ .pwr_domain_on_finish = stm32_pwr_domain_on_finish,
+ .pwr_domain_suspend_finish = stm32_pwr_domain_suspend_finish,
+ .pwr_domain_pwr_down_wfi = stm32_pwr_domain_pwr_down_wfi,
+ .system_off = stm32_system_off,
+ .system_reset = stm32_system_reset,
+ .validate_power_state = stm32_validate_power_state,
+ .validate_ns_entrypoint = stm32_validate_ns_entrypoint,
+ .get_node_hw_state = stm32_node_hw_state
+};
+
+/*******************************************************************************
+ * Export the platform specific power ops.
+ ******************************************************************************/
+int plat_setup_psci_ops(uintptr_t sec_entrypoint,
+ const plat_psci_ops_t **psci_ops)
+{
+ stm32_sec_entrypoint = sec_entrypoint;
+ *psci_ops = &stm32_psci_ops;
+
+ return 0;
+}
diff --git a/plat/st/stm32mp1/stm32mp1_security.c b/plat/st/stm32mp1/stm32mp1_security.c
new file mode 100644
index 000000000..e783c14e4
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_security.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <dt-bindings/clock/stm32mp1-clks.h>
+#include <mmio.h>
+#include <stdint.h>
+#include <stm32mp1_clk.h>
+#include <stm32mp1_dt.h>
+#include <stm32mp1_private.h>
+#include <stm32mp1_rcc.h>
+#include <tzc400.h>
+#include "platform_def.h"
+
+/*******************************************************************************
+ * Initialize the TrustZone Controller. Configure Region 0 with Secure RW access
+ * and allow Non-Secure masters full access.
+ ******************************************************************************/
+static void init_tzc400(void)
+{
+ unsigned long long region_base, region_top;
+ unsigned long long ddr_base = STM32MP1_DDR_BASE;
+ unsigned long long ddr_size = (unsigned long long)dt_get_ddr_size();
+
+ tzc400_init(STM32MP1_TZC_BASE);
+
+ tzc400_disable_filters();
+
+ /* Region 1 set to cover all DRAM at 0xC000_0000. Apply the
+ * same configuration to all filters in the TZC.
+ */
+ region_base = ddr_base;
+ region_top = ddr_base + (ddr_size - 1U);
+ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+ region_base,
+ region_top,
+ TZC_REGION_S_RDWR,
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_A7_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_GPU_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_LCD_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_MDMA_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DMA_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_HOST_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_USB_OTG_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_ETH_ID) |
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_DAP_ID));
+
+ /* Raise an exception if a NS device tries to access secure memory */
+ tzc400_set_action(TZC_ACTION_ERR);
+
+ tzc400_enable_filters();
+}
+
+/*******************************************************************************
+ * Initialize the TrustZone Controller.
+ * Early initialization create only one region with full access to secure.
+ * This setting is used before and during DDR initialization.
+ ******************************************************************************/
+static void early_init_tzc400(void)
+{
+ uint32_t rstsr, rst_standby;
+
+ rstsr = mmio_read_32(RCC_BASE + RCC_MP_RSTSCLRR);
+
+ /* No warning if return from (C)STANDBY */
+ rst_standby = rstsr &
+ (RCC_MP_RSTSCLRR_STDBYRSTF | RCC_MP_RSTSCLRR_CSTDBYRSTF);
+
+ if (stm32mp1_clk_is_enabled(TZC1) && (rst_standby == 0U)) {
+ WARN("TZC400 port 1 clock already enable\n");
+ }
+
+ if (stm32mp1_clk_is_enabled(TZC2) && (rst_standby == 0U)) {
+ WARN("TZC400 port 2 clock already enable\n");
+ }
+
+ if (stm32mp1_clk_enable(TZC1) != 0) {
+ ERROR("Cannot enable TZC1 clock\n");
+ panic();
+ }
+ if (stm32mp1_clk_enable(TZC2) != 0) {
+ ERROR("Cannot enable TZC2 clock\n");
+ panic();
+ }
+
+ tzc400_init(STM32MP1_TZC_BASE);
+
+ tzc400_disable_filters();
+
+ /*
+ * Region 1 set to cover Non-Secure DRAM at 0x8000_0000. Apply the
+ * same configuration to all filters in the TZC.
+ */
+ tzc400_configure_region(STM32MP1_FILTER_BIT_ALL, 1,
+ STM32MP1_DDR_BASE,
+ STM32MP1_DDR_BASE +
+ (STM32MP1_DDR_MAX_SIZE - 1U),
+ TZC_REGION_S_RDWR,
+ TZC_REGION_ACCESS_RDWR(STM32MP1_TZC_SDMMC_ID));
+
+ /* Raise an exception if a NS device tries to access secure memory */
+ tzc400_set_action(TZC_ACTION_ERR);
+
+ tzc400_enable_filters();
+}
+
+/*******************************************************************************
+ * Initialize the secure environment. At this moment only the TrustZone
+ * Controller is initialized.
+ ******************************************************************************/
+void stm32mp1_arch_security_setup(void)
+{
+ early_init_tzc400();
+}
+
+/*******************************************************************************
+ * Initialize the secure environment. At this moment only the TrustZone
+ * Controller is initialized.
+ ******************************************************************************/
+void stm32mp1_security_setup(void)
+{
+ init_tzc400();
+}
diff --git a/plat/st/stm32mp1/stm32mp1_stack_protector.c b/plat/st/stm32mp1/stm32mp1_stack_protector.c
new file mode 100644
index 000000000..c68130097
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_stack_protector.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <platform.h>
+#include <stdint.h>
+
+#define RANDOM_CANARY_VALUE 2144346116U
+
+u_register_t plat_get_stack_protector_canary(void)
+{
+ /*
+ * Ideally, a random number should be returned instead of the
+ * combination of a timer's value and a compile-time constant.
+ */
+ return RANDOM_CANARY_VALUE ^ (u_register_t)read_cntpct_el0();
+}
+
diff --git a/plat/st/stm32mp1/stm32mp1_topology.c b/plat/st/stm32mp1/stm32mp1_topology.c
new file mode 100644
index 000000000..405aa33eb
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_topology.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+#include <platform.h>
+#include <psci.h>
+
+/* 1 cluster, all cores into */
+static const unsigned char stm32mp1_power_domain_tree_desc[] = {
+ PLATFORM_CLUSTER_COUNT,
+ PLATFORM_CORE_COUNT,
+};
+
+/* This function returns the platform topology */
+const unsigned char *plat_get_power_domain_tree_desc(void)
+{
+ return stm32mp1_power_domain_tree_desc;
+}
+
+/*******************************************************************************
+ * This function implements a part of the critical interface between the psci
+ * generic layer and the platform that allows the former to query the platform
+ * to convert an MPIDR to a unique linear index. An error code (-1) is returned
+ * in case the MPIDR is invalid.
+ ******************************************************************************/
+int plat_core_pos_by_mpidr(u_register_t mpidr)
+{
+ unsigned int cluster_id, cpu_id;
+ u_register_t mpidr_copy = mpidr;
+
+ mpidr_copy &= MPIDR_AFFINITY_MASK;
+
+ if ((mpidr_copy & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) != 0U) {
+ return -1;
+ }
+
+ cluster_id = (mpidr_copy >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+ cpu_id = (mpidr_copy >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+
+ if (cluster_id >= PLATFORM_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 >= PLATFORM_CORE_COUNT) {
+ return -1;
+ }
+
+ return (int)cpu_id;
+}
diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h
index 4c59c758c..1bf58eda8 100644
--- a/plat/ti/k3/board/generic/include/board_def.h
+++ b/plat/ti/k3/board/generic/include/board_def.h
@@ -4,8 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __BOARD_DEF_H__
-#define __BOARD_DEF_H__
+#ifndef BOARD_DEF_H
+#define BOARD_DEF_H
+
+#include <utils_def.h>
/* The ports must be in order and contiguous */
#define K3_CLUSTER0_CORE_COUNT 2
@@ -27,7 +29,10 @@
#define SEC_SRAM_BASE 0x70000000 /* Base of MSMC SRAM */
#define SEC_SRAM_SIZE 0x00020000 /* 128k */
-#define PLAT_MAX_OFF_STATE 2
-#define PLAT_MAX_RET_STATE 1
+#define PLAT_MAX_OFF_STATE U(2)
+#define PLAT_MAX_RET_STATE U(1)
+
+#define PLAT_PROC_START_ID 32
+#define PLAT_PROC_DEVICE_START_ID 202
-#endif /* __BOARD_DEF_H__ */
+#endif /* BOARD_DEF_H */
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
new file mode 100644
index 000000000..92414b905
--- /dev/null
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.c
@@ -0,0 +1,289 @@
+/*
+ * Texas Instruments K3 Secure Proxy Driver
+ * Based on Linux and U-Boot implementation
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <errno.h>
+#include <mmio.h>
+#include <platform_def.h>
+#include <stdlib.h>
+#include <utils.h>
+#include <utils_def.h>
+
+#include "sec_proxy.h"
+
+/* SEC PROXY RT THREAD STATUS */
+#define RT_THREAD_STATUS (0x0)
+#define RT_THREAD_STATUS_ERROR_SHIFT (31)
+#define RT_THREAD_STATUS_ERROR_MASK BIT(31)
+#define RT_THREAD_STATUS_CUR_CNT_SHIFT (0)
+#define RT_THREAD_STATUS_CUR_CNT_MASK GENMASK(7, 0)
+
+/* SEC PROXY SCFG THREAD CTRL */
+#define SCFG_THREAD_CTRL (0x1000)
+#define SCFG_THREAD_CTRL_DIR_SHIFT (31)
+#define SCFG_THREAD_CTRL_DIR_MASK BIT(31)
+
+#define SEC_PROXY_THREAD(base, x) ((base) + (0x1000 * (x)))
+#define THREAD_IS_RX (1)
+#define THREAD_IS_TX (0)
+
+/**
+ * struct k3_sec_proxy_desc - Description of secure proxy integration
+ * @timeout_us: Timeout for communication (in Microseconds)
+ * @max_msg_size: Message size in bytes
+ * @data_start_offset: Offset of the First data register of the thread
+ * @data_end_offset: Offset of the Last data register of the thread
+ */
+struct k3_sec_proxy_desc {
+ uint32_t timeout_us;
+ uint16_t max_msg_size;
+ uint16_t data_start_offset;
+ uint16_t data_end_offset;
+};
+
+/**
+ * struct k3_sec_proxy_thread - Description of a secure proxy Thread
+ * @id: Thread ID
+ * @data: Thread Data path region for target
+ * @scfg: Secure Config Region for Thread
+ * @rt: RealTime Region for Thread
+ */
+struct k3_sec_proxy_thread {
+ uint32_t id;
+ uintptr_t data;
+ uintptr_t scfg;
+ uintptr_t rt;
+};
+
+/**
+ * struct k3_sec_proxy_mbox - Description of a Secure Proxy Instance
+ * @desc: Description of the SoC integration
+ * @chans: Array for valid thread instances
+ */
+struct k3_sec_proxy_mbox {
+ const struct k3_sec_proxy_desc desc;
+ struct k3_sec_proxy_thread threads[];
+};
+
+/*
+ * Thread ID #0: DMSC notify
+ * Thread ID #1: DMSC request response
+ * Thread ID #2: DMSC request high priority
+ * Thread ID #3: DMSC request low priority
+ * Thread ID #4: DMSC notify response
+ */
+#define SP_THREAD(_x) \
+ [_x] = { \
+ .id = _x, \
+ .data = SEC_PROXY_THREAD(SEC_PROXY_DATA_BASE, _x), \
+ .scfg = SEC_PROXY_THREAD(SEC_PROXY_SCFG_BASE, _x), \
+ .rt = SEC_PROXY_THREAD(SEC_PROXY_RT_BASE, _x), \
+ }
+
+static struct k3_sec_proxy_mbox spm = {
+ .desc = {
+ .timeout_us = SEC_PROXY_TIMEOUT_US,
+ .max_msg_size = SEC_PROXY_MAX_MESSAGE_SIZE,
+ .data_start_offset = 0x4,
+ .data_end_offset = 0x3C,
+ },
+ .threads = {
+ SP_THREAD(SP_NOTIFY),
+ SP_THREAD(SP_RESPONSE),
+ SP_THREAD(SP_HIGH_PRIORITY),
+ SP_THREAD(SP_LOW_PRIORITY),
+ SP_THREAD(SP_NOTIFY_RESP),
+ },
+};
+
+/**
+ * struct sec_msg_hdr - Message header for secure messages and responses
+ * @checksum: CRC of message for integrity checking
+ */
+union sec_msg_hdr {
+ struct {
+ uint16_t checksum;
+ uint16_t reserved;
+ } __packed;
+ uint32_t data;
+};
+
+/**
+ * k3_sec_proxy_verify_thread() - Verify thread status before
+ * sending/receiving data
+ * @spt: Pointer to Secure Proxy thread description
+ * @dir: Direction of the thread
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+static inline int k3_sec_proxy_verify_thread(struct k3_sec_proxy_thread *spt,
+ uint32_t dir)
+{
+ /* Check for any errors already available */
+ if (mmio_read_32(spt->rt + RT_THREAD_STATUS) &
+ RT_THREAD_STATUS_ERROR_MASK) {
+ ERROR("Thread %d is corrupted, cannot send data\n", spt->id);
+ return -EINVAL;
+ }
+
+ /* Make sure thread is configured for right direction */
+ if ((mmio_read_32(spt->scfg + SCFG_THREAD_CTRL) & SCFG_THREAD_CTRL_DIR_MASK)
+ != (dir << SCFG_THREAD_CTRL_DIR_SHIFT)) {
+ if (dir)
+ ERROR("Trying to receive data on tx Thread %d\n",
+ spt->id);
+ else
+ ERROR("Trying to send data on rx Thread %d\n",
+ spt->id);
+ return -EINVAL;
+ }
+
+ /* Check the message queue before sending/receiving data */
+ uint32_t tick_start = (uint32_t)read_cntpct_el0();
+ uint32_t ticks_per_us = SYS_COUNTER_FREQ_IN_TICKS / 1000000;
+ while (!(mmio_read_32(spt->rt + RT_THREAD_STATUS) & RT_THREAD_STATUS_CUR_CNT_MASK)) {
+ VERBOSE("Waiting for thread %d to clear\n", spt->id);
+ if (((uint32_t)read_cntpct_el0() - tick_start) >
+ (spm.desc.timeout_us * ticks_per_us)) {
+ ERROR("Timeout waiting for thread %d to clear\n", spt->id);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg)
+{
+ struct k3_sec_proxy_thread *spt = &spm.threads[id];
+ union sec_msg_hdr secure_header;
+ int num_words, trail_bytes, i, ret;
+ uintptr_t data_reg;
+
+ ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_TX);
+ if (ret) {
+ ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
+ return ret;
+ }
+
+ /* Check the message size */
+ if (msg->len + sizeof(secure_header) > spm.desc.max_msg_size) {
+ ERROR("Thread %d message length %lu > max msg size\n",
+ spt->id, msg->len);
+ return -EINVAL;
+ }
+
+ /* TODO: Calculate checksum */
+ secure_header.checksum = 0;
+
+ /* Send the secure header */
+ data_reg = spm.desc.data_start_offset;
+ mmio_write_32(spt->data + data_reg, secure_header.data);
+ data_reg += sizeof(uint32_t);
+
+ /* Send whole words */
+ num_words = msg->len / sizeof(uint32_t);
+ for (i = 0; i < num_words; i++) {
+ mmio_write_32(spt->data + data_reg, ((uint32_t *)msg->buf)[i]);
+ data_reg += sizeof(uint32_t);
+ }
+
+ /* Send remaining bytes */
+ trail_bytes = msg->len % sizeof(uint32_t);
+ if (trail_bytes) {
+ uint32_t data_trail = 0;
+
+ i = msg->len - trail_bytes;
+ while (trail_bytes--) {
+ data_trail <<= 8;
+ data_trail |= msg->buf[i++];
+ }
+
+ mmio_write_32(spt->data + data_reg, data_trail);
+ data_reg += sizeof(uint32_t);
+ }
+ /*
+ * 'data_reg' indicates next register to write. If we did not already
+ * write on tx complete reg(last reg), we must do so for transmit
+ */
+ if (data_reg <= spm.desc.data_end_offset)
+ mmio_write_32(spt->data + spm.desc.data_end_offset, 0);
+
+ VERBOSE("Message successfully sent on thread %ud\n", id);
+
+ return 0;
+}
+
+/**
+ * k3_sec_proxy_recv() - Receive data from a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_recv(uint32_t id, struct k3_sec_proxy_msg *msg)
+{
+ struct k3_sec_proxy_thread *spt = &spm.threads[id];
+ union sec_msg_hdr secure_header;
+ uintptr_t data_reg;
+ int num_words, trail_bytes, i, ret;
+
+ ret = k3_sec_proxy_verify_thread(spt, THREAD_IS_RX);
+ if (ret) {
+ ERROR("Thread %d verification failed (%d)\n", spt->id, ret);
+ return ret;
+ }
+
+ /* Read secure header */
+ data_reg = spm.desc.data_start_offset;
+ secure_header.data = mmio_read_32(spt->data + data_reg);
+ data_reg += sizeof(uint32_t);
+
+ /* Read whole words */
+ num_words = msg->len / sizeof(uint32_t);
+ for (i = 0; i < num_words; i++) {
+ ((uint32_t *)msg->buf)[i] = mmio_read_32(spt->data + data_reg);
+ data_reg += sizeof(uint32_t);
+ }
+
+ /* Read remaining bytes */
+ trail_bytes = msg->len % sizeof(uint32_t);
+ if (trail_bytes) {
+ uint32_t data_trail = mmio_read_32(spt->data + data_reg);
+ data_reg += sizeof(uint32_t);
+
+ i = msg->len - trail_bytes;
+ while (trail_bytes--) {
+ msg->buf[i] = data_trail & 0xff;
+ data_trail >>= 8;
+ }
+ }
+
+ /*
+ * 'data_reg' indicates next register to read. If we did not already
+ * read on rx complete reg(last reg), we must do so for receive
+ */
+ if (data_reg <= spm.desc.data_end_offset)
+ mmio_read_32(spt->data + spm.desc.data_end_offset);
+
+ /* TODO: Verify checksum */
+ (void)secure_header.checksum;
+
+ VERBOSE("Message successfully received from thread %ud\n", id);
+
+ return 0;
+}
diff --git a/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
new file mode 100644
index 000000000..facfd1988
--- /dev/null
+++ b/plat/ti/k3/common/drivers/sec_proxy/sec_proxy.h
@@ -0,0 +1,58 @@
+/*
+ * Texas Instruments K3 Secure Proxy Driver
+ * Based on Linux and U-Boot implementation
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef K3_SEC_PROXY_H
+#define K3_SEC_PROXY_H
+
+#include <stdint.h>
+
+/**
+ * enum k3_sec_proxy_chan_id - Secure Proxy thread IDs
+ *
+ * These the available IDs used in k3_sec_proxy_{send,recv}()
+ */
+enum k3_sec_proxy_chan_id {
+ SP_NOTIFY = 0,
+ SP_RESPONSE,
+ SP_HIGH_PRIORITY,
+ SP_LOW_PRIORITY,
+ SP_NOTIFY_RESP,
+};
+
+/**
+ * struct k3_sec_proxy_msg - Secure proxy message structure
+ * @len: Length of data in the Buffer
+ * @buf: Buffer pointer
+ *
+ * This is the structure for data used in k3_sec_proxy_{send,recv}()
+ */
+struct k3_sec_proxy_msg {
+ size_t len;
+ uint8_t *buf;
+};
+
+/**
+ * k3_sec_proxy_send() - Send data over a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_send(enum k3_sec_proxy_chan_id id, const struct k3_sec_proxy_msg *msg);
+
+/**
+ * k3_sec_proxy_recv() - Receive data from a Secure Proxy thread
+ * @id: Channel Identifier
+ * @msg: Pointer to k3_sec_proxy_msg
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int k3_sec_proxy_recv(enum k3_sec_proxy_chan_id id, struct k3_sec_proxy_msg *msg);
+
+#endif /* K3_SEC_PROXY_H */
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
new file mode 100644
index 000000000..7ba0267dc
--- /dev/null
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c
@@ -0,0 +1,1482 @@
+/*
+ * Texas Instruments System Control Interface Driver
+ * Based on Linux and U-Boot implementation
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <errno.h>
+#include <platform_def.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <sec_proxy.h>
+
+#include "ti_sci_protocol.h"
+#include "ti_sci.h"
+
+/**
+ * struct ti_sci_desc - Description of SoC integration
+ * @host_id: Host identifier representing the compute entity
+ * @max_msg_size: Maximum size of data per message that can be handled
+ */
+struct ti_sci_desc {
+ uint8_t host_id;
+ int max_msg_size;
+};
+
+/**
+ * struct ti_sci_info - Structure representing a TI SCI instance
+ * @desc: SoC description for this instance
+ * @seq: Seq id used for verification for tx and rx message
+ */
+struct ti_sci_info {
+ const struct ti_sci_desc desc;
+ uint8_t seq;
+};
+
+static struct ti_sci_info info = {
+ .desc = {
+ .host_id = TI_SCI_HOST_ID,
+ .max_msg_size = TI_SCI_MAX_MESSAGE_SIZE,
+ },
+ .seq = 0x0a,
+};
+
+/**
+ * struct ti_sci_xfer - Structure representing a message flow
+ * @tx_message: Transmit message
+ * @rx_message: Receive message
+ */
+struct ti_sci_xfer {
+ struct k3_sec_proxy_msg tx_message;
+ struct k3_sec_proxy_msg rx_message;
+};
+
+/**
+ * ti_sci_setup_one_xfer() - Setup one message type
+ *
+ * @msg_type: Message type
+ * @msg_flags: Flag to set for the message
+ * @tx_buf: Buffer to be sent to mailbox channel
+ * @tx_message_size: transmit message size
+ * @rx_buf: Buffer to be received from mailbox channel
+ * @rx_message_size: receive message size
+ *
+ * Helper function which is used by various command functions that are
+ * exposed to clients of this driver for allocating a message traffic event.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags,
+ void *tx_buf,
+ size_t tx_message_size,
+ void *rx_buf,
+ size_t rx_message_size,
+ struct ti_sci_xfer *xfer)
+{
+ struct ti_sci_msg_hdr *hdr;
+
+ /* Ensure we have sane transfer sizes */
+ if (rx_message_size > info.desc.max_msg_size ||
+ tx_message_size > info.desc.max_msg_size ||
+ rx_message_size < sizeof(*hdr) ||
+ tx_message_size < sizeof(*hdr))
+ return -ERANGE;
+
+ info.seq++;
+
+ hdr = (struct ti_sci_msg_hdr *)tx_buf;
+ hdr->seq = info.seq;
+ hdr->type = msg_type;
+ hdr->host = info.desc.host_id;
+ hdr->flags = msg_flags;
+
+ xfer->tx_message.buf = tx_buf;
+ xfer->tx_message.len = tx_message_size;
+
+ xfer->rx_message.buf = rx_buf;
+ xfer->rx_message.len = rx_message_size;
+
+ return 0;
+}
+
+/**
+ * ti_sci_get_response() - Receive response from mailbox channel
+ *
+ * @xfer: Transfer to initiate and wait for response
+ * @chan: Channel to receive the response
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+static inline int ti_sci_get_response(struct ti_sci_xfer *xfer,
+ enum k3_sec_proxy_chan_id chan)
+{
+ struct k3_sec_proxy_msg *msg = &xfer->rx_message;
+ struct ti_sci_msg_hdr *hdr;
+ int ret;
+
+ /* Receive the response */
+ ret = k3_sec_proxy_recv(chan, msg);
+ if (ret) {
+ ERROR("Message receive failed (%d)\n", ret);
+ return ret;
+ }
+
+ /* msg is updated by Secure Proxy driver */
+ hdr = (struct ti_sci_msg_hdr *)msg->buf;
+
+ /* Sanity check for message response */
+ if (hdr->seq != info.seq) {
+ ERROR("Message for %d is not expected\n", hdr->seq);
+ return -EINVAL;
+ }
+
+ if (msg->len > info.desc.max_msg_size) {
+ ERROR("Unable to handle %lu xfer (max %d)\n",
+ msg->len, info.desc.max_msg_size);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * ti_sci_do_xfer() - Do one transfer
+ *
+ * @xfer: Transfer to initiate and wait for response
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+static inline int ti_sci_do_xfer(struct ti_sci_xfer *xfer)
+{
+ struct k3_sec_proxy_msg *msg = &xfer->tx_message;
+ int ret;
+
+ /* Send the message */
+ ret = k3_sec_proxy_send(SP_HIGH_PRIORITY, msg);
+ if (ret) {
+ ERROR("Message sending failed (%d)\n", ret);
+ return ret;
+ }
+
+ ret = ti_sci_get_response(xfer, SP_RESPONSE);
+ if (ret) {
+ ERROR("Failed to get response (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * ti_sci_get_revision() - Get the revision of the SCI entity
+ *
+ * Updates the SCI information in the internal data structure.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_get_revision(struct ti_sci_msg_resp_version *rev_info)
+{
+ struct ti_sci_msg_hdr hdr;
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_VERSION, 0x0,
+ &hdr, sizeof(hdr),
+ rev_info, sizeof(*rev_info),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/**
+ * ti_sci_is_response_ack() - Generic ACK/NACK message check
+ *
+ * @r: pointer to response buffer
+ *
+ * Return: true if the response was an ACK, else returns false
+ */
+static inline bool ti_sci_is_response_ack(void *r)
+{
+ struct ti_sci_msg_hdr *hdr = r;
+
+ return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false;
+}
+
+/**
+ * ti_sci_device_set_state() - Set device state
+ *
+ * @id: Device identifier
+ * @flags: flags to setup for the device
+ * @state: State to move the device to
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state)
+{
+ struct ti_sci_msg_req_set_device_state req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_STATE,
+ flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.id = id;
+ req.state = state;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_get_state() - Get device state
+ *
+ * @id: Device Identifier
+ * @clcnt: Pointer to Context Loss Count
+ * @resets: pointer to resets
+ * @p_state: pointer to p_state
+ * @c_state: pointer to c_state
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets,
+ uint8_t *p_state, uint8_t *c_state)
+{
+ struct ti_sci_msg_req_get_device_state req;
+ struct ti_sci_msg_resp_get_device_state resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ if (!clcnt && !resets && !p_state && !c_state)
+ return -EINVAL;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_DEVICE_STATE, 0,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.id = id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ if (clcnt)
+ *clcnt = resp.context_loss_count;
+ if (resets)
+ *resets = resp.resets;
+ if (p_state)
+ *p_state = resp.programmed_state;
+ if (c_state)
+ *c_state = resp.current_state;
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_get() - Request for device managed by TISCI
+ *
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * NOTE: The request is for exclusive access for the processor.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_get(uint32_t id)
+{
+ return ti_sci_device_set_state(id,
+ MSG_FLAG_DEVICE_EXCLUSIVE,
+ MSG_DEVICE_SW_STATE_ON);
+}
+
+/**
+ * ti_sci_device_idle() - Idle a device managed by TISCI
+ *
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_idle(uint32_t id)
+{
+ return ti_sci_device_set_state(id,
+ MSG_FLAG_DEVICE_EXCLUSIVE,
+ MSG_DEVICE_SW_STATE_RETENTION);
+}
+
+/**
+ * ti_sci_device_put() - Release a device managed by TISCI
+ *
+ * @id: Device Identifier
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_put(uint32_t id)
+{
+ return ti_sci_device_set_state(id, 0, MSG_DEVICE_SW_STATE_AUTO_OFF);
+}
+
+/**
+ * ti_sci_device_is_valid() - Is the device valid
+ *
+ * @id: Device Identifier
+ *
+ * Return: 0 if all goes well and the device ID is valid, else return
+ * appropriate error
+ */
+int ti_sci_device_is_valid(uint32_t id)
+{
+ uint8_t unused;
+
+ /* check the device state which will also tell us if the ID is valid */
+ return ti_sci_device_get_state(id, NULL, NULL, NULL, &unused);
+}
+
+/**
+ * ti_sci_device_get_clcnt() - Get context loss counter
+ *
+ * @id: Device Identifier
+ * @count: Pointer to Context Loss counter to populate
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count)
+{
+ return ti_sci_device_get_state(id, count, NULL, NULL, NULL);
+}
+
+/**
+ * ti_sci_device_is_idle() - Check if the device is requested to be idle
+ *
+ * @id: Device Identifier
+ * @r_state: true if requested to be idle
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_is_idle(uint32_t id, bool *r_state)
+{
+ int ret;
+ uint8_t state;
+
+ if (!r_state)
+ return -EINVAL;
+
+ ret = ti_sci_device_get_state(id, NULL, NULL, &state, NULL);
+ if (ret)
+ return ret;
+
+ *r_state = (state == MSG_DEVICE_SW_STATE_RETENTION);
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_is_stop() - Check if the device is requested to be stopped
+ *
+ * @id: Device Identifier
+ * @r_state: true if requested to be stopped
+ * @curr_state: true if currently stopped
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_is_stop(uint32_t id, bool *r_state, bool *curr_state)
+{
+ int ret;
+ uint8_t p_state, c_state;
+
+ if (!r_state && !curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (r_state)
+ *r_state = (p_state == MSG_DEVICE_SW_STATE_AUTO_OFF);
+ if (curr_state)
+ *curr_state = (c_state == MSG_DEVICE_HW_STATE_OFF);
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_is_on() - Check if the device is requested to be ON
+ *
+ * @id: Device Identifier
+ * @r_state: true if requested to be ON
+ * @curr_state: true if currently ON and active
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_is_on(uint32_t id, bool *r_state, bool *curr_state)
+{
+ int ret;
+ uint8_t p_state, c_state;
+
+ if (!r_state && !curr_state)
+ return -EINVAL;
+
+ ret =
+ ti_sci_device_get_state(id, NULL, NULL, &p_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (r_state)
+ *r_state = (p_state == MSG_DEVICE_SW_STATE_ON);
+ if (curr_state)
+ *curr_state = (c_state == MSG_DEVICE_HW_STATE_ON);
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_is_trans() - Check if the device is currently transitioning
+ *
+ * @id: Device Identifier
+ * @curr_state: true if currently transitioning
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_is_trans(uint32_t id, bool *curr_state)
+{
+ int ret;
+ uint8_t state;
+
+ if (!curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_device_get_state(id, NULL, NULL, NULL, &state);
+ if (ret)
+ return ret;
+
+ *curr_state = (state == MSG_DEVICE_HW_STATE_TRANS);
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_set_resets() - Set resets for device managed by TISCI
+ *
+ * @id: Device Identifier
+ * @reset_state: Device specific reset bit field
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state)
+{
+ struct ti_sci_msg_req_set_device_resets req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_DEVICE_RESETS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.id = id;
+ req.resets = reset_state;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_device_get_resets() - Get reset state for device managed by TISCI
+ *
+ * @id: Device Identifier
+ * @reset_state: Pointer to reset state to populate
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state)
+{
+ return ti_sci_device_get_state(id, NULL, reset_state, NULL, NULL);
+}
+
+/**
+ * ti_sci_clock_set_state() - Set clock state helper
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request,
+ * Each device has its own set of clock inputs, This indexes
+ * which clock input to modify
+ * @flags: Header flags as needed
+ * @state: State to request for the clock
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id,
+ uint32_t flags, uint8_t state)
+{
+ struct ti_sci_msg_req_set_clock_state req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_STATE,
+ flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+ req.request_state = state;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get_state() - Get clock state helper
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @programmed_state: State requested for clock to move to
+ * @current_state: State that the clock is currently in
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id,
+ uint8_t *programmed_state,
+ uint8_t *current_state)
+{
+ struct ti_sci_msg_req_get_clock_state req;
+ struct ti_sci_msg_resp_get_clock_state resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ if (!programmed_state && !current_state)
+ return -EINVAL;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_STATE,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ if (programmed_state)
+ *programmed_state = resp.programmed_state;
+ if (current_state)
+ *current_state = resp.current_state;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get() - Get control of a clock from TI SCI
+
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @needs_ssc: 'true' iff Spread Spectrum clock is desired
+ * @can_change_freq: 'true' iff frequency change is desired
+ * @enable_input_term: 'true' iff input termination is desired
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id,
+ bool needs_ssc, bool can_change_freq,
+ bool enable_input_term)
+{
+ uint32_t flags = 0;
+
+ flags |= needs_ssc ? MSG_FLAG_CLOCK_ALLOW_SSC : 0;
+ flags |= can_change_freq ? MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE : 0;
+ flags |= enable_input_term ? MSG_FLAG_CLOCK_INPUT_TERM : 0;
+
+ return ti_sci_clock_set_state(dev_id, clk_id, flags,
+ MSG_CLOCK_SW_STATE_REQ);
+}
+
+/**
+ * ti_sci_clock_idle() - Idle a clock which is in our control
+
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_idle(uint32_t dev_id, uint8_t clk_id)
+{
+ return ti_sci_clock_set_state(dev_id, clk_id, 0,
+ MSG_CLOCK_SW_STATE_UNREQ);
+}
+
+/**
+ * ti_sci_clock_put() - Release a clock from our control
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ *
+ * NOTE: This clock must have been requested by get_clock previously.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_put(uint32_t dev_id, uint8_t clk_id)
+{
+ return ti_sci_clock_set_state(dev_id, clk_id, 0,
+ MSG_CLOCK_SW_STATE_AUTO);
+}
+
+/**
+ * ti_sci_clock_is_auto() - Is the clock being auto managed
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is auto managed
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_is_auto(uint32_t dev_id, uint8_t clk_id, bool *req_state)
+{
+ uint8_t state = 0;
+ int ret;
+
+ if (!req_state)
+ return -EINVAL;
+
+ ret = ti_sci_clock_get_state(dev_id, clk_id, &state, NULL);
+ if (ret)
+ return ret;
+
+ *req_state = (state == MSG_CLOCK_SW_STATE_AUTO);
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_is_on() - Is the clock ON
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and enabled
+ * @curr_state: state indicating if the clock is ready for operation
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_is_on(uint32_t dev_id, uint8_t clk_id,
+ bool *req_state, bool *curr_state)
+{
+ uint8_t c_state = 0, r_state = 0;
+ int ret;
+
+ if (!req_state && !curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (req_state)
+ *req_state = (r_state == MSG_CLOCK_SW_STATE_REQ);
+ if (curr_state)
+ *curr_state = (c_state == MSG_CLOCK_HW_STATE_READY);
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_is_off() - Is the clock OFF
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @req_state: state indicating if the clock is managed by us and disabled
+ * @curr_state: state indicating if the clock is NOT ready for operation
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_is_off(uint32_t dev_id, uint8_t clk_id,
+ bool *req_state, bool *curr_state)
+{
+ uint8_t c_state = 0, r_state = 0;
+ int ret;
+
+ if (!req_state && !curr_state)
+ return -EINVAL;
+
+ ret = ti_sci_clock_get_state(dev_id, clk_id, &r_state, &c_state);
+ if (ret)
+ return ret;
+
+ if (req_state)
+ *req_state = (r_state == MSG_CLOCK_SW_STATE_UNREQ);
+ if (curr_state)
+ *curr_state = (c_state == MSG_CLOCK_HW_STATE_NOT_READY);
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_set_parent() - Set the clock source of a specific device clock
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: Parent clock identifier to set
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id, uint8_t parent_id)
+{
+ struct ti_sci_msg_req_set_clock_parent req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_PARENT,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+ req.parent_id = parent_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get_parent() - Get current parent clock source
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: Current clock parent
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id, uint8_t *parent_id)
+{
+ struct ti_sci_msg_req_get_clock_parent req;
+ struct ti_sci_msg_resp_get_clock_parent resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_PARENT,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ *parent_id = resp.parent_id;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get_num_parents() - Get num parents of the current clk source
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @num_parents: Returns he number of parents to the current clock.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id,
+ uint8_t *num_parents)
+{
+ struct ti_sci_msg_req_get_clock_num_parents req;
+ struct ti_sci_msg_resp_get_clock_num_parents resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_NUM_CLOCK_PARENTS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ *num_parents = resp.num_parents;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get_match_freq() - Find a good match for frequency
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * @max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @match_freq: Frequency match in Hz response.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id,
+ uint64_t min_freq, uint64_t target_freq,
+ uint64_t max_freq, uint64_t *match_freq)
+{
+ struct ti_sci_msg_req_query_clock_freq req;
+ struct ti_sci_msg_resp_query_clock_freq resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_QUERY_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+ req.min_freq_hz = min_freq;
+ req.target_freq_hz = target_freq;
+ req.max_freq_hz = max_freq;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ *match_freq = resp.freq_hz;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_set_freq() - Set a frequency for clock
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * @max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id, uint64_t min_freq,
+ uint64_t target_freq, uint64_t max_freq)
+{
+ struct ti_sci_msg_req_set_clock_freq req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SET_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+ req.min_freq_hz = min_freq;
+ req.target_freq_hz = target_freq;
+ req.max_freq_hz = max_freq;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_clock_get_freq() - Get current frequency
+ *
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @freq: Currently frequency in Hz
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq)
+{
+ struct ti_sci_msg_req_get_clock_freq req;
+ struct ti_sci_msg_resp_get_clock_freq resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_GET_CLOCK_FREQ,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.dev_id = dev_id;
+ req.clk_id = clk_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ *freq = resp.freq_hz;
+
+ return 0;
+}
+
+/**
+ * ti_sci_core_reboot() - Command to request system reset
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_core_reboot(void)
+{
+ struct ti_sci_msg_req_reboot req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TI_SCI_MSG_SYS_RESET,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_request() - Request a physical processor control
+ *
+ * @proc_id: Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_request(uint8_t proc_id)
+{
+ struct ti_sci_msg_req_proc_request req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_REQUEST,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_release() - Release a physical processor control
+ *
+ * @proc_id: Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_release(uint8_t proc_id)
+{
+ struct ti_sci_msg_req_proc_release req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_RELEASE,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_handover() - Handover a physical processor control to a host in
+ * the processor's access control list.
+ *
+ * @proc_id: Processor ID this request is for
+ * @host_id: Host ID to get the control of the processor
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id)
+{
+ struct ti_sci_msg_req_proc_handover req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_HANDOVER,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+ req.host_id = host_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_set_boot_cfg() - Set the processor boot configuration flags
+ *
+ * @proc_id: Processor ID this request is for
+ * @config_flags_set: Configuration flags to be set
+ * @config_flags_clear: Configuration flags to be cleared
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector,
+ uint32_t config_flags_set,
+ uint32_t config_flags_clear)
+{
+ struct ti_sci_msg_req_set_proc_boot_config req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CONFIG,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+ req.bootvector_low = bootvector & TISCI_ADDR_LOW_MASK;
+ req.bootvector_high = (bootvector & TISCI_ADDR_HIGH_MASK) >>
+ TISCI_ADDR_HIGH_SHIFT;
+ req.config_flags_set = config_flags_set;
+ req.config_flags_clear = config_flags_clear;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_set_boot_ctrl() - Set the processor boot control flags
+ *
+ * @proc_id: Processor ID this request is for
+ * @control_flags_set: Control flags to be set
+ * @control_flags_clear: Control flags to be cleared
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
+ uint32_t control_flags_clear)
+{
+ struct ti_sci_msg_req_set_proc_boot_ctrl req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_SET_PROC_BOOT_CTRL,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+ req.control_flags_set = control_flags_set;
+ req.control_flags_clear = control_flags_clear;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_auth_boot_image() - Authenticate and load image and then set the
+ * processor configuration flags
+ *
+ * @proc_id: Processor ID this request is for
+ * @cert_addr: Memory address at which payload image certificate is located
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr)
+{
+ struct ti_sci_msg_req_proc_auth_boot_image req;
+ struct ti_sci_msg_hdr resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_PROC_AUTH_BOOT_IMIAGE,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+ req.cert_addr_low = cert_addr & TISCI_ADDR_LOW_MASK;
+ req.cert_addr_high = (cert_addr & TISCI_ADDR_HIGH_MASK) >>
+ TISCI_ADDR_HIGH_SHIFT;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ return 0;
+}
+
+/**
+ * ti_sci_proc_get_boot_status() - Get the processor boot status
+ *
+ * @proc_id: Processor ID this request is for
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
+ uint32_t *cfg_flags,
+ uint32_t *ctrl_flags,
+ uint32_t *sts_flags)
+{
+ struct ti_sci_msg_req_get_proc_boot_status req;
+ struct ti_sci_msg_resp_get_proc_boot_status resp;
+
+ struct ti_sci_xfer xfer;
+ int ret;
+
+ ret = ti_sci_setup_one_xfer(TISCI_MSG_GET_PROC_BOOT_STATUS,
+ TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+ &req, sizeof(req),
+ &resp, sizeof(resp),
+ &xfer);
+ if (ret) {
+ ERROR("Message alloc failed (%d)\n", ret);
+ return ret;
+ }
+
+ req.processor_id = proc_id;
+
+ ret = ti_sci_do_xfer(&xfer);
+ if (ret) {
+ ERROR("Transfer send failed (%d)\n", ret);
+ return ret;
+ }
+
+ if (!ti_sci_is_response_ack(&resp))
+ return -ENODEV;
+
+ *bv = (resp.bootvector_low & TISCI_ADDR_LOW_MASK) |
+ (((uint64_t)resp.bootvector_high << TISCI_ADDR_HIGH_SHIFT) &
+ TISCI_ADDR_HIGH_MASK);
+ *cfg_flags = resp.config_flags;
+ *ctrl_flags = resp.control_flags;
+ *sts_flags = resp.status_flags;
+
+ return 0;
+}
+
+/**
+ * ti_sci_init() - Basic initialization
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_init(void)
+{
+ struct ti_sci_msg_resp_version rev_info;
+ int ret;
+
+ ret = ti_sci_get_revision(&rev_info);
+ if (ret) {
+ ERROR("Unable to communicate with control firmware (%d)\n", ret);
+ return ret;
+ }
+
+ INFO("SYSFW ABI: %d.%d (firmware rev 0x%04x '%s')\n",
+ rev_info.abi_major, rev_info.abi_minor,
+ rev_info.firmware_revision,
+ rev_info.firmware_description);
+
+ return 0;
+}
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
new file mode 100644
index 000000000..e40ad6bc5
--- /dev/null
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.h
@@ -0,0 +1,208 @@
+/*
+ * Texas Instruments System Control Interface API
+ * Based on Linux and U-Boot implementation
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TI_SCI_H
+#define __TI_SCI_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * Device control operations
+ *
+ * - ti_sci_device_set_state - Set device state helper
+ * @flags: flags to setup for the device
+ * @state: State to move the device to
+ * - ti_sci_device_get_state - Get device state helper
+ * @clcnt: Pointer to Context Loss Count
+ * @resets: pointer to resets
+ * @p_state: pointer to p_state
+ * @c_state: pointer to c_state
+ * - ti_sci_device_get - command to request for device managed by TISCI
+ * - ti_sci_device_idle - Command to idle a device managed by TISCI
+ * - ti_sci_device_put - command to release a device managed by TISCI
+ * - ti_sci_device_is_valid - Is the device valid
+ * - ti_sci_device_get_clcnt - Get context loss counter
+ * @count: Pointer to Context Loss counter to populate
+ * - ti_sci_device_is_idle - Check if the device is requested to be idle
+ * @r_state: true if requested to be idle
+ * - ti_sci_device_is_stop - Check if the device is requested to be stopped
+ * @r_state: true if requested to be stopped
+ * @curr_state: true if currently stopped.
+ * - ti_sci_device_is_on - Check if the device is requested to be ON
+ * @r_state: true if requested to be ON
+ * @curr_state: true if currently ON and active
+ * - ti_sci_device_is_trans - Check if the device is currently transitioning
+ * @curr_state: true if currently transitioning.
+ * - ti_sci_device_set_resets - Command to set resets for
+ * device managed by TISCI
+ * @reset_state: Device specific reset bit field
+ * - ti_sci_device_get_resets - Get reset state for device managed by TISCI
+ * @reset_state: Pointer to reset state to populate
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * @id: Device Identifier
+ * Returns 0 for successful request, else returns corresponding error message.
+ *
+ * Request for the device - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_device with put_device. No refcounting is
+ * managed by driver for that purpose.
+ */
+int ti_sci_device_set_state(uint32_t id, uint32_t flags, uint8_t state);
+int ti_sci_device_get_state(uint32_t id, uint32_t *clcnt, uint32_t *resets,
+ uint8_t *p_state, uint8_t *c_state);
+int ti_sci_device_get(uint32_t id);
+int ti_sci_device_idle(uint32_t id);
+int ti_sci_device_put(uint32_t id);
+int ti_sci_device_is_valid(uint32_t id);
+int ti_sci_device_get_clcnt(uint32_t id, uint32_t *count);
+int ti_sci_device_is_idle(uint32_t id, bool *r_state);
+int ti_sci_device_is_stop(uint32_t id, bool *r_state, bool *curr_state);
+int ti_sci_device_is_on(uint32_t id, bool *r_state, bool *curr_state);
+int ti_sci_device_is_trans(uint32_t id, bool *curr_state);
+int ti_sci_device_set_resets(uint32_t id, uint32_t reset_state);
+int ti_sci_device_get_resets(uint32_t id, uint32_t *reset_state);
+
+/**
+ * Clock control operations
+ *
+ * - ti_sci_clock_set_state - Set clock state helper
+ * @flags: Header flags as needed
+ * @state: State to request for the clock.
+ * - ti_sci_clock_get_state - Get clock state helper
+ * @programmed_state: State requested for clock to move to
+ * @current_state: State that the clock is currently in
+ * - ti_sci_clock_get - Get control of a clock from TI SCI
+ * @needs_ssc: 'true' iff Spread Spectrum clock is desired
+ * @can_change_freq: 'true' iff frequency change is desired
+ * @enable_input_term: 'true' iff input termination is desired
+ * - ti_sci_clock_idle - Idle a clock which is in our control
+ * - ti_sci_clock_put - Release a clock from our control
+ * - ti_sci_clock_is_auto - Is the clock being auto managed
+ * @req_state: state indicating if the clock is auto managed
+ * - ti_sci_clock_is_on - Is the clock ON
+ * @req_state: state indicating if the clock is managed by us and enabled
+ * @curr_state: state indicating if the clock is ready for operation
+ * - ti_sci_clock_is_off - Is the clock OFF
+ * @req_state: state indicating if the clock is managed by us and disabled
+ * @curr_state: state indicating if the clock is NOT ready for operation
+ * - ti_sci_clock_set_parent - Set the clock source of a specific device clock
+ * @parent_id: Parent clock identifier to set
+ * - ti_sci_clock_get_parent - Get current parent clock source
+ * @parent_id: Current clock parent
+ * - ti_sci_clock_get_num_parents - Get num parents of the current clk source
+ * @num_parents: Returns he number of parents to the current clock.
+ * - ti_sci_clock_get_match_freq - Find a good match for frequency
+ * @match_freq: Frequency match in Hz response.
+ * - ti_sci_clock_set_freq - Set a frequency for clock
+ * - ti_sci_clock_get_freq - Get current frequency
+ * @freq: Currently frequency in Hz
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has its own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @min_freq: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq: The target clock frequency in Hz. A frequency will be
+ * processed as close to this target frequency as possible.
+ * @max_freq: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * Returns 0 for successful request, else returns corresponding error message.
+ *
+ * Request for the clock - NOTE: the client MUST maintain integrity of
+ * usage count by balancing get_clock with put_clock. No refcounting is
+ * managed by driver for that purpose.
+ */
+int ti_sci_clock_set_state(uint32_t dev_id, uint8_t clk_id,
+ uint32_t flags, uint8_t state);
+int ti_sci_clock_get_state(uint32_t dev_id, uint8_t clk_id,
+ uint8_t *programmed_state, uint8_t *current_state);
+int ti_sci_clock_get(uint32_t dev_id, uint8_t clk_id,
+ bool needs_ssc, bool can_change_freq,
+ bool enable_input_term);
+int ti_sci_clock_idle(uint32_t dev_id, uint8_t clk_id);
+int ti_sci_clock_put(uint32_t dev_id, uint8_t clk_id);
+int ti_sci_clock_is_auto(uint32_t dev_id, uint8_t clk_id,
+ bool *req_state);
+int ti_sci_clock_is_on(uint32_t dev_id, uint8_t clk_id,
+ bool *req_state, bool *curr_state);
+int ti_sci_clock_is_off(uint32_t dev_id, uint8_t clk_id,
+ bool *req_state, bool *curr_state);
+int ti_sci_clock_set_parent(uint32_t dev_id, uint8_t clk_id,
+ uint8_t parent_id);
+int ti_sci_clock_get_parent(uint32_t dev_id, uint8_t clk_id,
+ uint8_t *parent_id);
+int ti_sci_clock_get_num_parents(uint32_t dev_id, uint8_t clk_id,
+ uint8_t *num_parents);
+int ti_sci_clock_get_match_freq(uint32_t dev_id, uint8_t clk_id,
+ uint64_t min_freq, uint64_t target_freq,
+ uint64_t max_freq, uint64_t *match_freq);
+int ti_sci_clock_set_freq(uint32_t dev_id, uint8_t clk_id,
+ uint64_t min_freq, uint64_t target_freq,
+ uint64_t max_freq);
+int ti_sci_clock_get_freq(uint32_t dev_id, uint8_t clk_id, uint64_t *freq);
+
+/**
+ * Core control operations
+ *
+ * - ti_sci_core_reboot() - Command to request system reset
+ *
+ * Return: 0 if all went well, else returns appropriate error value.
+ */
+int ti_sci_core_reboot(void);
+
+/**
+ * Processor control operations
+ *
+ * - ti_sci_proc_request - Command to request a physical processor control
+ * - ti_sci_proc_release - Command to release a physical processor control
+ * - ti_sci_proc_handover - Command to handover a physical processor control to
+ * a host in the processor's access control list.
+ * @host_id: Host ID to get the control of the processor
+ * - ti_sci_proc_set_boot_cfg - Command to set the processor boot configuration flags
+ * @config_flags_set: Configuration flags to be set
+ * @config_flags_clear: Configuration flags to be cleared.
+ * - ti_sci_proc_set_boot_ctrl - Command to set the processor boot control flags
+ * @control_flags_set: Control flags to be set
+ * @control_flags_clear: Control flags to be cleared
+ * - ti_sci_proc_auth_boot_image - Command to authenticate and load the image
+ * and then set the processor configuration flags.
+ * @cert_addr: Memory address at which payload image certificate is located.
+ * - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ *
+ * NOTE: for all these functions, the following are generic in nature:
+ * @proc_id: Processor ID
+ * Returns 0 for successful request, else returns corresponding error message.
+ */
+int ti_sci_proc_request(uint8_t proc_id);
+int ti_sci_proc_release(uint8_t proc_id);
+int ti_sci_proc_handover(uint8_t proc_id, uint8_t host_id);
+int ti_sci_proc_set_boot_cfg(uint8_t proc_id, uint64_t bootvector,
+ uint32_t config_flags_set,
+ uint32_t config_flags_clear);
+int ti_sci_proc_set_boot_ctrl(uint8_t proc_id, uint32_t control_flags_set,
+ uint32_t control_flags_clear);
+int ti_sci_proc_auth_boot_image(uint8_t proc_id, uint64_t cert_addr);
+int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
+ uint32_t *cfg_flags,
+ uint32_t *ctrl_flags,
+ uint32_t *sts_flags);
+
+/**
+ * ti_sci_init() - Basic initialization
+ *
+ * Return: 0 if all goes good, else appropriate error message.
+ */
+int ti_sci_init(void);
+
+#endif /* __TI_SCI_H */
diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
new file mode 100644
index 000000000..2c4b23fcb
--- /dev/null
+++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h
@@ -0,0 +1,650 @@
+/*
+ * Texas Instruments System Control Interface (TISCI) Protocol
+ *
+ * Communication protocol with TI SCI hardware
+ * The system works in a message response protocol
+ * See: http://processors.wiki.ti.com/index.php/TISCI for details
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TI_SCI_PROTOCOL_H
+#define __TI_SCI_PROTOCOL_H
+
+#include <stdint.h>
+
+/* Generic Messages */
+#define TI_SCI_MSG_ENABLE_WDT 0x0000
+#define TI_SCI_MSG_WAKE_RESET 0x0001
+#define TI_SCI_MSG_VERSION 0x0002
+#define TI_SCI_MSG_WAKE_REASON 0x0003
+#define TI_SCI_MSG_GOODBYE 0x0004
+#define TI_SCI_MSG_SYS_RESET 0x0005
+
+/* Device requests */
+#define TI_SCI_MSG_SET_DEVICE_STATE 0x0200
+#define TI_SCI_MSG_GET_DEVICE_STATE 0x0201
+#define TI_SCI_MSG_SET_DEVICE_RESETS 0x0202
+
+/* Clock requests */
+#define TI_SCI_MSG_SET_CLOCK_STATE 0x0100
+#define TI_SCI_MSG_GET_CLOCK_STATE 0x0101
+#define TI_SCI_MSG_SET_CLOCK_PARENT 0x0102
+#define TI_SCI_MSG_GET_CLOCK_PARENT 0x0103
+#define TI_SCI_MSG_GET_NUM_CLOCK_PARENTS 0x0104
+#define TI_SCI_MSG_SET_CLOCK_FREQ 0x010c
+#define TI_SCI_MSG_QUERY_CLOCK_FREQ 0x010d
+#define TI_SCI_MSG_GET_CLOCK_FREQ 0x010e
+
+/* Processor Control Messages */
+#define TISCI_MSG_PROC_REQUEST 0xc000
+#define TISCI_MSG_PROC_RELEASE 0xc001
+#define TISCI_MSG_PROC_HANDOVER 0xc005
+#define TISCI_MSG_SET_PROC_BOOT_CONFIG 0xc100
+#define TISCI_MSG_SET_PROC_BOOT_CTRL 0xc101
+#define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE 0xc120
+#define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
+
+/**
+ * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
+ * @type: Type of messages: One of TI_SCI_MSG* values
+ * @host: Host of the message
+ * @seq: Message identifier indicating a transfer sequence
+ * @flags: Flag for the message
+ */
+struct ti_sci_msg_hdr {
+ uint16_t type;
+ uint8_t host;
+ uint8_t seq;
+#define TI_SCI_MSG_FLAG(val) (1 << (val))
+#define TI_SCI_FLAG_REQ_GENERIC_NORESPONSE 0x0
+#define TI_SCI_FLAG_REQ_ACK_ON_RECEIVED TI_SCI_MSG_FLAG(0)
+#define TI_SCI_FLAG_REQ_ACK_ON_PROCESSED TI_SCI_MSG_FLAG(1)
+#define TI_SCI_FLAG_RESP_GENERIC_NACK 0x0
+#define TI_SCI_FLAG_RESP_GENERIC_ACK TI_SCI_MSG_FLAG(1)
+ /* Additional Flags */
+ uint32_t flags;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_version - Response for a message
+ * @hdr: Generic header
+ * @firmware_description: String describing the firmware
+ * @firmware_revision: Firmware revision
+ * @abi_major: Major version of the ABI that firmware supports
+ * @abi_minor: Minor version of the ABI that firmware supports
+ *
+ * In general, ABI version changes follow the rule that minor version increments
+ * are backward compatible. Major revision changes in ABI may not be
+ * backward compatible.
+ *
+ * Response to a generic message with message type TI_SCI_MSG_VERSION
+ */
+struct ti_sci_msg_resp_version {
+ struct ti_sci_msg_hdr hdr;
+#define FIRMWARE_DESCRIPTION_LENGTH 32
+ char firmware_description[FIRMWARE_DESCRIPTION_LENGTH];
+ uint16_t firmware_revision;
+ uint8_t abi_major;
+ uint8_t abi_minor;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_reboot - Reboot the SoC
+ * @hdr: Generic Header
+ *
+ * Request type is TI_SCI_MSG_SYS_RESET, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_reboot {
+ struct ti_sci_msg_hdr hdr;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_device_state - Set the desired state of the device
+ * @hdr: Generic header
+ * @id: Indicates which device to modify
+ * @reserved: Reserved space in message, must be 0 for backward compatibility
+ * @state: The desired state of the device.
+ *
+ * Certain flags can also be set to alter the device state:
+ * + MSG_FLAG_DEVICE_WAKE_ENABLED - Configure the device to be a wake source.
+ * The meaning of this flag will vary slightly from device to device and from
+ * SoC to SoC but it generally allows the device to wake the SoC out of deep
+ * suspend states.
+ * + MSG_FLAG_DEVICE_RESET_ISO - Enable reset isolation for this device.
+ * + MSG_FLAG_DEVICE_EXCLUSIVE - Claim this device exclusively. When passed
+ * with STATE_RETENTION or STATE_ON, it will claim the device exclusively.
+ * If another host already has this device set to STATE_RETENTION or STATE_ON,
+ * the message will fail. Once successful, other hosts attempting to set
+ * STATE_RETENTION or STATE_ON will fail.
+ *
+ * Request type is TI_SCI_MSG_SET_DEVICE_STATE, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_set_device_state {
+ /* Additional hdr->flags options */
+#define MSG_FLAG_DEVICE_WAKE_ENABLED TI_SCI_MSG_FLAG(8)
+#define MSG_FLAG_DEVICE_RESET_ISO TI_SCI_MSG_FLAG(9)
+#define MSG_FLAG_DEVICE_EXCLUSIVE TI_SCI_MSG_FLAG(10)
+ struct ti_sci_msg_hdr hdr;
+ uint32_t id;
+ uint32_t reserved;
+
+#define MSG_DEVICE_SW_STATE_AUTO_OFF 0
+#define MSG_DEVICE_SW_STATE_RETENTION 1
+#define MSG_DEVICE_SW_STATE_ON 2
+ uint8_t state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_device_state - Request to get device.
+ * @hdr: Generic header
+ * @id: Device Identifier
+ *
+ * Request type is TI_SCI_MSG_GET_DEVICE_STATE, responded device state
+ * information
+ */
+struct ti_sci_msg_req_get_device_state {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_device_state - Response to get device request.
+ * @hdr: Generic header
+ * @context_loss_count: Indicates how many times the device has lost context. A
+ * driver can use this monotonic counter to determine if the device has
+ * lost context since the last time this message was exchanged.
+ * @resets: Programmed state of the reset lines.
+ * @programmed_state: The state as programmed by set_device.
+ * - Uses the MSG_DEVICE_SW_* macros
+ * @current_state: The actual state of the hardware.
+ *
+ * Response to request TI_SCI_MSG_GET_DEVICE_STATE.
+ */
+struct ti_sci_msg_resp_get_device_state {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t context_loss_count;
+ uint32_t resets;
+ uint8_t programmed_state;
+#define MSG_DEVICE_HW_STATE_OFF 0
+#define MSG_DEVICE_HW_STATE_ON 1
+#define MSG_DEVICE_HW_STATE_TRANS 2
+ uint8_t current_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_device_resets - Set the desired resets
+ * configuration of the device
+ * @hdr: Generic header
+ * @id: Indicates which device to modify
+ * @resets: A bit field of resets for the device. The meaning, behavior,
+ * and usage of the reset flags are device specific. 0 for a bit
+ * indicates releasing the reset represented by that bit while 1
+ * indicates keeping it held.
+ *
+ * Request type is TI_SCI_MSG_SET_DEVICE_RESETS, responded with a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_set_device_resets {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t id;
+ uint32_t resets;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_state - Request to setup a Clock state
+ * @hdr: Generic Header, Certain flags can be set specific to the clocks:
+ * MSG_FLAG_CLOCK_ALLOW_SSC: Allow this clock to be modified
+ * via spread spectrum clocking.
+ * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE: Allow this clock's
+ * frequency to be changed while it is running so long as it
+ * is within the min/max limits.
+ * MSG_FLAG_CLOCK_INPUT_TERM: Enable input termination, this
+ * is only applicable to clock inputs on the SoC pseudo-device.
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @request_state: Request the state for the clock to be set to.
+ * MSG_CLOCK_SW_STATE_UNREQ: The IP does not require this clock,
+ * it can be disabled, regardless of the state of the device
+ * MSG_CLOCK_SW_STATE_AUTO: Allow the System Controller to
+ * automatically manage the state of this clock. If the device
+ * is enabled, then the clock is enabled. If the device is set
+ * to off or retention, then the clock is internally set as not
+ * being required by the device.(default)
+ * MSG_CLOCK_SW_STATE_REQ: Configure the clock to be enabled,
+ * regardless of the state of the device.
+ *
+ * Normally, all required clocks are managed by TISCI entity, this is used
+ * only for specific control *IF* required. Auto managed state is
+ * MSG_CLOCK_SW_STATE_AUTO, in other states, TISCI entity assume remote
+ * will explicitly control.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_STATE, response is a generic
+ * ACK or NACK message.
+ */
+struct ti_sci_msg_req_set_clock_state {
+ /* Additional hdr->flags options */
+#define MSG_FLAG_CLOCK_ALLOW_SSC TI_SCI_MSG_FLAG(8)
+#define MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE TI_SCI_MSG_FLAG(9)
+#define MSG_FLAG_CLOCK_INPUT_TERM TI_SCI_MSG_FLAG(10)
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+#define MSG_CLOCK_SW_STATE_UNREQ 0
+#define MSG_CLOCK_SW_STATE_AUTO 1
+#define MSG_CLOCK_SW_STATE_REQ 2
+ uint8_t request_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_state - Request for clock state
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to get state of.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_STATE, response is state
+ * of the clock
+ */
+struct ti_sci_msg_req_get_clock_state {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_state - Response to get clock state
+ * @hdr: Generic Header
+ * @programmed_state: Any programmed state of the clock. This is one of
+ * MSG_CLOCK_SW_STATE* values.
+ * @current_state: Current state of the clock. This is one of:
+ * MSG_CLOCK_HW_STATE_NOT_READY: Clock is not ready
+ * MSG_CLOCK_HW_STATE_READY: Clock is ready
+ *
+ * Response to TI_SCI_MSG_GET_CLOCK_STATE.
+ */
+struct ti_sci_msg_resp_get_clock_state {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t programmed_state;
+#define MSG_CLOCK_HW_STATE_NOT_READY 0
+#define MSG_CLOCK_HW_STATE_READY 1
+ uint8_t current_state;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_parent - Set the clock parent
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to modify.
+ * @parent_id: The new clock parent is selectable by an index via this
+ * parameter.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_PARENT, response is generic
+ * ACK / NACK message.
+ */
+struct ti_sci_msg_req_set_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+ uint8_t parent_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_parent - Get the clock parent
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ * Each device has it's own set of clock inputs. This indexes
+ * which clock input to get the parent for.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_PARENT, response is parent information
+ */
+struct ti_sci_msg_req_get_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_parent - Response with clock parent
+ * @hdr: Generic Header
+ * @parent_id: The current clock parent
+ *
+ * Response to TI_SCI_MSG_GET_CLOCK_PARENT.
+ */
+struct ti_sci_msg_resp_get_clock_parent {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t parent_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_num_parents - Request to get clock parents
+ * @hdr: Generic header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * This request provides information about how many clock parent options
+ * are available for a given clock to a device. This is typically used
+ * for input clocks.
+ *
+ * Request type is TI_SCI_MSG_GET_NUM_CLOCK_PARENTS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_get_clock_num_parents {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_num_parents - Response for get clk parents
+ * @hdr: Generic header
+ * @num_parents: Number of clock parents
+ *
+ * Response to TI_SCI_MSG_GET_NUM_CLOCK_PARENTS
+ */
+struct ti_sci_msg_resp_get_clock_num_parents {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t num_parents;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_query_clock_freq - Request to query a frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq_hz: The target clock frequency. A frequency will be found
+ * as close to this target frequency as possible.
+ * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In case of specific requests, TISCI evaluates capability to achieve
+ * requested frequency within provided range and responds with
+ * result message.
+ *
+ * Request type is TI_SCI_MSG_QUERY_CLOCK_FREQ, response is appropriate message,
+ * or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_query_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint64_t min_freq_hz;
+ uint64_t target_freq_hz;
+ uint64_t max_freq_hz;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_query_clock_freq - Response to a clock frequency query
+ * @hdr: Generic Header
+ * @freq_hz: Frequency that is the best match in Hz.
+ *
+ * Response to request type TI_SCI_MSG_QUERY_CLOCK_FREQ. NOTE: if the request
+ * cannot be satisfied, the message will be of type NACK.
+ */
+struct ti_sci_msg_resp_query_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ uint64_t freq_hz;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_set_clock_freq - Request to setup a clock frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @min_freq_hz: The minimum allowable frequency in Hz. This is the minimum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @target_freq_hz: The target clock frequency. The clock will be programmed
+ * at a rate as close to this target frequency as possible.
+ * @max_freq_hz: The maximum allowable frequency in Hz. This is the maximum
+ * allowable programmed frequency and does not account for clock
+ * tolerances and jitter.
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In case of specific requests, TISCI evaluates capability to achieve
+ * requested range and responds with success/failure message.
+ *
+ * This sets the desired frequency for a clock within an allowable
+ * range. This message will fail on an enabled clock unless
+ * MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE is set for the clock. Additionally,
+ * if other clocks have their frequency modified due to this message,
+ * they also must have the MSG_FLAG_CLOCK_ALLOW_FREQ_CHANGE or be disabled.
+ *
+ * Calling set frequency on a clock input to the SoC pseudo-device will
+ * inform the PMMC of that clock's frequency. Setting a frequency of
+ * zero will indicate the clock is disabled.
+ *
+ * Calling set frequency on clock outputs from the SoC pseudo-device will
+ * function similarly to setting the clock frequency on a device.
+ *
+ * Request type is TI_SCI_MSG_SET_CLOCK_FREQ, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_set_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint64_t min_freq_hz;
+ uint64_t target_freq_hz;
+ uint64_t max_freq_hz;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_clock_freq - Request to get the clock frequency
+ * @hdr: Generic Header
+ * @dev_id: Device identifier this request is for
+ * @clk_id: Clock identifier for the device for this request.
+ *
+ * NOTE: Normally clock frequency management is automatically done by TISCI
+ * entity. In some cases, clock frequencies are configured by host.
+ *
+ * Request type is TI_SCI_MSG_GET_CLOCK_FREQ, responded with clock frequency
+ * that the clock is currently at.
+ */
+struct ti_sci_msg_req_get_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ uint32_t dev_id;
+ uint8_t clk_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_resp_get_clock_freq - Response of clock frequency request
+ * @hdr: Generic Header
+ * @freq_hz: Frequency that the clock is currently on, in Hz.
+ *
+ * Response to request type TI_SCI_MSG_GET_CLOCK_FREQ.
+ */
+struct ti_sci_msg_resp_get_clock_freq {
+ struct ti_sci_msg_hdr hdr;
+ uint64_t freq_hz;
+} __packed;
+
+#define TISCI_ADDR_LOW_MASK 0x00000000ffffffff
+#define TISCI_ADDR_HIGH_MASK 0xffffffff00000000
+#define TISCI_ADDR_HIGH_SHIFT 32
+
+/**
+ * struct ti_sci_msg_req_proc_request - Request a processor
+ *
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ *
+ * Request type is TISCI_MSG_PROC_REQUEST, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_proc_request {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_proc_release - Release a processor
+ *
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ *
+ * Request type is TISCI_MSG_PROC_RELEASE, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_proc_release {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_proc_handover - Handover a processor to a host
+ *
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @host_id: New Host we want to give control to
+ *
+ * Request type is TISCI_MSG_PROC_HANDOVER, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_proc_handover {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint8_t host_id;
+} __packed;
+
+/* A53 Config Flags */
+#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_EN 0x00000001
+#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_NIDEN 0x00000002
+#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPIDEN 0x00000004
+#define PROC_BOOT_CFG_FLAG_ARMV8_DBG_SPNIDEN 0x00000008
+#define PROC_BOOT_CFG_FLAG_ARMV8_AARCH32 0x00000100
+
+/* R5 Config Flags */
+#define PROC_BOOT_CFG_FLAG_R5_DBG_EN 0x00000001
+#define PROC_BOOT_CFG_FLAG_R5_DBG_NIDEN 0x00000002
+#define PROC_BOOT_CFG_FLAG_R5_LOCKSTEP 0x00000100
+#define PROC_BOOT_CFG_FLAG_R5_TEINIT 0x00000200
+#define PROC_BOOT_CFG_FLAG_R5_NMFI_EN 0x00000400
+#define PROC_BOOT_CFG_FLAG_R5_TCM_RSTBASE 0x00000800
+#define PROC_BOOT_CFG_FLAG_R5_BTCM_EN 0x00001000
+#define PROC_BOOT_CFG_FLAG_R5_ATCM_EN 0x00002000
+
+/**
+ * struct ti_sci_msg_req_set_proc_boot_config - Set Processor boot configuration
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @bootvector_low: Lower 32bit (Little Endian) of boot vector
+ * @bootvector_high: Higher 32bit (Little Endian) of boot vector
+ * @config_flags_set: Optional Processor specific Config Flags to set.
+ * Setting a bit here implies required bit sets to 1.
+ * @config_flags_clear: Optional Processor specific Config Flags to clear.
+ * Setting a bit here implies required bit gets cleared.
+ *
+ * Request type is TISCI_MSG_SET_PROC_BOOT_CONFIG, response is a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_set_proc_boot_config {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint32_t bootvector_low;
+ uint32_t bootvector_high;
+ uint32_t config_flags_set;
+ uint32_t config_flags_clear;
+} __packed;
+
+/* R5 Control Flags */
+#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001
+
+/**
+ * struct ti_sci_msg_req_set_proc_boot_ctrl - Set Processor boot control flags
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @config_flags_set: Optional Processor specific Config Flags to set.
+ * Setting a bit here implies required bit sets to 1.
+ * @config_flags_clear: Optional Processor specific Config Flags to clear.
+ * Setting a bit here implies required bit gets cleared.
+ *
+ * Request type is TISCI_MSG_SET_PROC_BOOT_CTRL, response is a generic ACK/NACK
+ * message.
+ */
+struct ti_sci_msg_req_set_proc_boot_ctrl {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint32_t control_flags_set;
+ uint32_t control_flags_clear;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_proc_auth_start_image - Authenticate and start image
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @cert_addr_low: Lower 32bit (Little Endian) of certificate
+ * @cert_addr_high: Higher 32bit (Little Endian) of certificate
+ *
+ * Request type is TISCI_MSG_PROC_AUTH_BOOT_IMAGE, response is a generic
+ * ACK/NACK message.
+ */
+struct ti_sci_msg_req_proc_auth_boot_image {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint32_t cert_addr_low;
+ uint32_t cert_addr_high;
+} __packed;
+
+/**
+ * struct ti_sci_msg_req_get_proc_boot_status - Get processor boot status
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ *
+ * Request type is TISCI_MSG_GET_PROC_BOOT_STATUS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_get_proc_boot_status {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+} __packed;
+
+/* ARMv8 Status Flags */
+#define PROC_BOOT_STATUS_FLAG_ARMV8_WFE 0x00000001
+#define PROC_BOOT_STATUS_FLAG_ARMV8_WFI 0x00000002
+
+/* R5 Status Flags */
+#define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001
+#define PROC_BOOT_STATUS_FLAG_R5_WFI 0x00000002
+#define PROC_BOOT_STATUS_FLAG_R5_CLK_GATED 0x00000004
+#define PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED 0x00000100
+
+/**
+ * \brief Processor Status Response
+ * struct ti_sci_msg_resp_get_proc_boot_status - Processor boot status response
+ * @hdr: Generic Header
+ * @processor_id: ID of processor
+ * @bootvector_low: Lower 32bit (Little Endian) of boot vector
+ * @bootvector_high: Higher 32bit (Little Endian) of boot vector
+ * @config_flags: Optional Processor specific Config Flags set.
+ * @control_flags: Optional Processor specific Control Flags.
+ * @status_flags: Optional Processor specific Status Flags set.
+ *
+ * Response to TISCI_MSG_GET_PROC_BOOT_STATUS.
+ */
+struct ti_sci_msg_resp_get_proc_boot_status {
+ struct ti_sci_msg_hdr hdr;
+ uint8_t processor_id;
+ uint32_t bootvector_low;
+ uint32_t bootvector_high;
+ uint32_t config_flags;
+ uint32_t control_flags;
+ uint32_t status_flags;
+} __packed;
+
+#endif /* __TI_SCI_PROTOCOL_H */
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index ca7d214a1..2d4d1c278 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -14,6 +14,7 @@
#include <platform_def.h>
#include <k3_gicv3.h>
#include <string.h>
+#include <ti_sci.h>
/* Table of regions to map using the MMU */
const mmap_region_t plat_arm_mmap[] = {
@@ -21,6 +22,9 @@ const mmap_region_t plat_arm_mmap[] = {
MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
{ /* sentinel */ }
};
@@ -99,12 +103,18 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
void bl31_plat_arch_setup(void)
{
- arm_setup_page_tables(BL31_BASE,
- BL31_END - BL31_BASE,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END);
+
+ const mmap_region_t bl_regions[] = {
+ MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_END,
+ MT_RO_DATA | MT_SECURE),
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el3(0);
}
@@ -112,6 +122,8 @@ void bl31_platform_setup(void)
{
k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
k3_gic_init();
+
+ ti_sci_init();
}
void platform_mem_init(void)
diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c
index 4d6428b5c..e75ebac8c 100644
--- a/plat/ti/k3/common/k3_psci.c
+++ b/plat/ti/k3/common/k3_psci.c
@@ -9,8 +9,11 @@
#include <debug.h>
#include <k3_gicv3.h>
#include <psci.h>
+#include <platform.h>
#include <stdbool.h>
+#include <ti_sci.h>
+
#define STUB() ERROR("stub %s called\n", __func__)
uintptr_t k3_sec_entrypoint;
@@ -33,19 +36,59 @@ static void k3_cpu_standby(plat_local_state_t cpu_state)
static int k3_pwr_domain_on(u_register_t mpidr)
{
- sev();
-
- /* TODO: Indicate to System firmware about powering up */
+ int core_id, proc, device, ret;
+
+ core_id = plat_core_pos_by_mpidr(mpidr);
+ if (core_id < 0) {
+ ERROR("Could not get target core id: %d\n", core_id);
+ return PSCI_E_INTERN_FAIL;
+ }
+
+ proc = PLAT_PROC_START_ID + core_id;
+ device = PLAT_PROC_DEVICE_START_ID + core_id;
+
+ ret = ti_sci_proc_request(proc);
+ if (ret) {
+ ERROR("Request for processor failed: %d\n", ret);
+ return PSCI_E_INTERN_FAIL;
+ }
+
+ ret = ti_sci_proc_set_boot_cfg(proc, k3_sec_entrypoint, 0, 0);
+ if (ret) {
+ ERROR("Request to set core boot address failed: %d\n", ret);
+ return PSCI_E_INTERN_FAIL;
+ }
+
+ ret = ti_sci_device_get(device);
+ if (ret) {
+ ERROR("Request to start core failed: %d\n", ret);
+ return PSCI_E_INTERN_FAIL;
+ }
+
+ ret = ti_sci_proc_release(proc);
+ if (ret) {
+ /* this is not fatal */
+ WARN("Could not release processor control: %d\n", ret);
+ }
return PSCI_E_SUCCESS;
}
void k3_pwr_domain_off(const psci_power_state_t *target_state)
{
+ int core_id, device, ret;
+
/* Prevent interrupts from spuriously waking up this cpu */
k3_gic_cpuif_disable();
- /* TODO: Indicate to System firmware about powering down */
+ core_id = plat_my_core_pos();
+ device = PLAT_PROC_DEVICE_START_ID + core_id;
+
+ ret = ti_sci_device_put(device);
+ if (ret) {
+ ERROR("Request to stop core failed: %d\n", ret);
+ return;
+ }
}
void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
@@ -58,8 +101,8 @@ void k3_pwr_domain_on_finish(const psci_power_state_t *target_state)
static void __dead2 k3_system_reset(void)
{
- /* TODO: Indicate to System firmware about system reset */
- STUB();
+ /* Send the system reset request to system firmware */
+ ti_sci_core_reboot();
while (true)
wfi();
diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk
index bf2a73fbb..446d8afba 100644
--- a/plat/ti/k3/common/plat_common.mk
+++ b/plat/ti/k3/common/plat_common.mk
@@ -12,7 +12,7 @@ COLD_BOOT_SINGLE_CPU := 1
PROGRAMMABLE_RESET_ADDRESS:= 1
# System coherency is managed in hardware
-HW_ASSISTED_COHERENCY := 1
+WARMBOOT_ENABLE_DCACHE_EARLY:= 1
USE_COHERENT_MEM := 0
ERROR_DEPRECATED := 1
@@ -36,6 +36,8 @@ PLAT_INCLUDES += \
-I${PLAT_PATH}/include \
-Iinclude/plat/arm/common/ \
-Iinclude/plat/arm/common/aarch64/ \
+ -I${PLAT_PATH}/common/drivers/sec_proxy \
+ -I${PLAT_PATH}/common/drivers/ti_sci \
K3_CONSOLE_SOURCES += \
drivers/console/aarch64/console.S \
@@ -53,6 +55,12 @@ K3_PSCI_SOURCES += \
plat/common/plat_psci_common.c \
${PLAT_PATH}/common/k3_psci.c \
+K3_SEC_PROXY_SOURCES += \
+ ${PLAT_PATH}/common/drivers/sec_proxy/sec_proxy.c \
+
+K3_TI_SCI_SOURCES += \
+ ${PLAT_PATH}/common/drivers/ti_sci/ti_sci.c \
+
PLAT_BL_COMMON_SOURCES += \
plat/arm/common/arm_common.c \
lib/cpus/aarch64/cortex_a53.S \
@@ -65,3 +73,5 @@ BL31_SOURCES += \
${PLAT_PATH}/common/k3_topology.c \
${K3_GIC_SOURCES} \
${K3_PSCI_SOURCES} \
+ ${K3_SEC_PROXY_SOURCES} \
+ ${K3_TI_SCI_SOURCES} \
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index ebc9c4770..ab0739e90 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -106,7 +106,7 @@
* runtime memory used, choose the smallest value needed to register the
* required regions for each BL stage.
*/
-#define MAX_MMAP_REGIONS 8
+#define MAX_MMAP_REGIONS 11
/*
* Defines the total size of the address space in bytes. For example, for a 32
@@ -193,4 +193,17 @@
#define K3_GICR_BASE 0x01880000
#define K3_GICR_SIZE 0x100000
+#define SEC_PROXY_DATA_BASE 0x32C00000
+#define SEC_PROXY_DATA_SIZE 0x80000
+#define SEC_PROXY_SCFG_BASE 0x32800000
+#define SEC_PROXY_SCFG_SIZE 0x80000
+#define SEC_PROXY_RT_BASE 0x32400000
+#define SEC_PROXY_RT_SIZE 0x80000
+
+#define SEC_PROXY_TIMEOUT_US 1000000
+#define SEC_PROXY_MAX_MESSAGE_SIZE 56
+
+#define TI_SCI_HOST_ID 10
+#define TI_SCI_MAX_MESSAGE_SIZE 52
+
#endif /* __PLATFORM_DEF_H__ */
diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
index 0b3106f7a..abfb8c6fc 100644
--- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
+++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c
@@ -179,13 +179,20 @@ void bl31_plat_arch_setup(void)
plat_arm_interconnect_init();
plat_arm_interconnect_enter_coherency();
- arm_setup_page_tables(BL31_BASE,
- BL31_END - BL31_BASE,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END,
- BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END);
+
+ const mmap_region_t bl_regions[] = {
+ MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+ MT_RO_DATA | MT_SECURE),
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el3(0);
}
diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h
index 49766cc92..d721778d3 100644
--- a/plat/xilinx/zynqmp/include/platform_def.h
+++ b/plat/xilinx/zynqmp/include/platform_def.h
@@ -1,15 +1,16 @@
/*
- * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PLATFORM_DEF_H__
-#define __PLATFORM_DEF_H__
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
#include <arch.h>
#include <gic_common.h>
#include <interrupt_props.h>
+#include <utils_def.h>
#include "../zynqmp_def.h"
/*******************************************************************************
@@ -21,9 +22,9 @@
#define PLATFORM_CORE_COUNT 4
#define PLAT_NUM_POWER_DOMAINS 5
-#define PLAT_MAX_PWR_LVL 1
-#define PLAT_MAX_RET_STATE 1
-#define PLAT_MAX_OFF_STATE 2
+#define PLAT_MAX_PWR_LVL U(1)
+#define PLAT_MAX_RET_STATE U(1)
+#define PLAT_MAX_OFF_STATE U(2)
/*******************************************************************************
* BL31 specific defines.
@@ -142,4 +143,4 @@
#define PLAT_ARM_G0_IRQ_PROPS(grp)
-#endif /* __PLATFORM_DEF_H__ */
+#endif /* PLATFORM_DEF_H */
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index a41eebbc0..fefd9ea8f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -2307,6 +2307,21 @@ static unsigned int pm_clock_type(unsigned int clock_id)
}
/**
+ * pm_api_clock_get_num_clocks() - PM call to request number of clocks
+ * @nclocks Number of clocks
+ *
+ * This function is used by master to get number of clocks.
+ *
+ * @return Returns success.
+ */
+enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
+{
+ *nclocks = CLK_MAX;
+
+ return PM_RET_SUCCESS;
+}
+
+/**
* pm_api_clock_get_name() - PM call to request a clock's name
* @clock_id Clock ID
* @name Name of clock (max 16 bytes)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 56f850a49..386f2753b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -276,6 +276,7 @@ enum {
enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name);
+enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks);
enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
unsigned int index,
uint32_t *topology);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index 133043da5..fe1029f66 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -713,6 +713,19 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid,
}
/**
+ * pm_clock_get_num_clocks - PM call to request number of clocks
+ * @nclockss: Number of clocks
+ *
+ * This function is used by master to get number of clocks.
+ *
+ * Return: Returns status, either success or error+reason.
+ */
+static enum pm_ret_status pm_clock_get_num_clocks(uint32_t *nclocks)
+{
+ return pm_api_clock_get_num_clocks(nclocks);
+}
+
+/**
* pm_clock_get_name() - PM call to request a clock's name
* @clock_id Clock ID
* @name Name of clock (max 16 bytes)
@@ -1118,6 +1131,10 @@ enum pm_ret_status pm_query_data(enum pm_query_id qid,
(uint16_t *)&data[1]);
data[0] = (unsigned int)ret;
break;
+ case PM_QID_CLOCK_GET_NUM_CLOCKS:
+ ret = pm_clock_get_num_clocks(&data[1]);
+ data[0] = (unsigned int)ret;
+ break;
default:
ret = PM_RET_ERROR_ARGS;
WARN("Unimplemented query service call: 0x%x\n", qid);
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 55a8a6ea1..c304895ac 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -23,6 +23,7 @@ enum pm_query_id {
PM_QID_PINCTRL_GET_FUNCTION_NAME,
PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
PM_QID_PINCTRL_GET_PIN_GROUPS,
+ PM_QID_CLOCK_GET_NUM_CLOCKS,
};
/**********************************************************
diff --git a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
index ecc4d0a97..52d4bf8cc 100644
--- a/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
+++ b/plat/xilinx/zynqmp/tsp/tsp_plat_setup.c
@@ -44,14 +44,19 @@ void tsp_platform_setup(void)
******************************************************************************/
void tsp_plat_arch_setup(void)
{
- arm_setup_page_tables(BL32_BASE,
- BL32_END - BL32_BASE,
- BL_CODE_BASE,
- BL_CODE_END,
- BL_RO_DATA_BASE,
- BL_RO_DATA_END,
- BL_COHERENT_RAM_BASE,
- BL_COHERENT_RAM_END
- );
+ const mmap_region_t bl_regions[] = {
+ MAP_REGION_FLAT(BL32_BASE, BL32_END - BL32_BASE,
+ MT_MEMORY | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
+ MT_CODE | MT_SECURE),
+ MAP_REGION_FLAT(BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE,
+ MT_RO_DATA | MT_SECURE),
+ MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+ MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+ };
+
+ arm_setup_page_tables(bl_regions, plat_arm_get_mmap());
enable_mmu_el1(0);
}
diff --git a/readme.rst b/readme.rst
index c87936ced..26e1fdeea 100644
--- a/readme.rst
+++ b/readme.rst
@@ -30,19 +30,29 @@ described in the `Contributing Guidelines`_.
This project contains code from other projects as listed below. The original
license text is included in those source files.
-- The stdlib source code is derived from FreeBSD code, which uses various
- BSD licenses, including BSD-3-Clause and BSD-2-Clause.
+- The libc source code is derived from `FreeBSD`_ and `SCC`_. FreeBSD uses
+ various BSD licenses, including BSD-3-Clause and BSD-2-Clause. The SCC code
+ is used under the BSD-3-Clause license with the author's permission.
-- The libfdt source code is dual licensed. It is used by this project under
- the terms of the BSD-2-Clause license.
+- The libfdt source code is disjunctively dual licensed
+ (GPL-2.0+ OR BSD-2-Clause). It is used by this project under the terms of
+ the BSD-2-Clause license. Any contributions to this code must be made under
+ the terms of both licenses.
-- The LLVM compiler-rt source code is dual licensed. It is used by this
- project under the terms of the NCSA license (also known as the University of
- Illinois/NCSA Open Source License).
+- The LLVM compiler-rt source code is disjunctively dual licensed
+ (NCSA OR MIT). It is used by this project under the terms of the NCSA
+ license (also known as the University of Illinois/NCSA Open Source License),
+ which is a permissive license compatible with BSD-3-Clause. Any
+ contributions to this code must be made under the terms of both licenses.
- The zlib source code is licensed under the Zlib license, which is a
permissive license compatible with BSD-3-Clause.
+- Some STMicroelectronics platform source code is disjunctively dual licensed
+ (GPL-2.0+ OR BSD-3-Clause). It is used by this project under the terms of the
+ BSD-3-Clause license. Any contributions to this code must be made under the
+ terms of both licenses.
+
This release
------------
@@ -219,6 +229,13 @@ See the `Contributing Guidelines`_ for information on how to contribute to this
project and the `Acknowledgments`_ file for a list of contributors to the
project.
+IRC channel
+~~~~~~~~~~~
+
+Development discussion takes place on the #trusted-firmware-a channel
+on the Freenode IRC network. This is not an official support channel.
+If you have an issue to raise, please use the `GitHub issue tracker`_.
+
Feedback and support
~~~~~~~~~~~~~~~~~~~~
@@ -259,3 +276,5 @@ Arm licensees may contact Arm directly via their partner managers.
.. _Change Log: ./docs/change-log.rst
.. _User Guide: ./docs/user-guide.rst
.. _Porting Guide: ./docs/porting-guide.rst
+.. _FreeBSD: http://www.freebsd.org
+.. _SCC: http://www.simple-cc.org/
diff --git a/services/spd/trusty/generic-arm64-smcall.c b/services/spd/trusty/generic-arm64-smcall.c
index 38da279e4..6f766c4db 100644
--- a/services/spd/trusty/generic-arm64-smcall.c
+++ b/services/spd/trusty/generic-arm64-smcall.c
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <debug.h>
#include <runtime_svc.h>
+#include <stdio.h>
#include "generic-arm64-smcall.h"
@@ -57,14 +58,14 @@ static uint64_t trusty_get_reg_base(uint32_t reg)
}
}
-static uint64_t trusty_generic_platform_smc(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
+static uintptr_t trusty_generic_platform_smc(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
void *cookie,
void *handle,
- uint64_t flags)
+ u_register_t flags)
{
switch (smc_fid) {
case SMC_FC_DEBUG_PUTC:
diff --git a/services/std_svc/sdei/sdei_event.c b/services/std_svc/sdei/sdei_event.c
index bf0e779d0..ec69b9d27 100644
--- a/services/std_svc/sdei/sdei_event.c
+++ b/services/std_svc/sdei/sdei_event.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,7 +21,8 @@ sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
{
const sdei_mapping_t *mapping;
sdei_entry_t *cpu_priv_base;
- unsigned int idx, base_idx;
+ unsigned int base_idx;
+ long int idx;
if (is_event_private(map)) {
/*
@@ -32,7 +33,7 @@ sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
idx = MAP_OFF(map, mapping);
/* Base of private mappings for this CPU */
- base_idx = plat_my_core_pos() * mapping->num_maps;
+ base_idx = plat_my_core_pos() * ((unsigned int) mapping->num_maps);
cpu_priv_base = &sdei_private_event_table[base_idx];
/*
@@ -52,7 +53,7 @@ sdei_entry_t *get_event_entry(sdei_ev_map_t *map)
* Find event mapping for a given interrupt number: On success, returns pointer
* to the event mapping. On error, returns NULL.
*/
-sdei_ev_map_t *find_event_map_by_intr(int intr_num, int shared)
+sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared)
{
const sdei_mapping_t *mapping;
sdei_ev_map_t *map;
diff --git a/services/std_svc/sdei/sdei_intr_mgmt.c b/services/std_svc/sdei/sdei_intr_mgmt.c
index a37188ac4..e834a2b90 100644
--- a/services/std_svc/sdei/sdei_intr_mgmt.c
+++ b/services/std_svc/sdei/sdei_intr_mgmt.c
@@ -16,17 +16,14 @@
#include <string.h>
#include "sdei_private.h"
-#define PE_MASKED 1
-#define PE_NOT_MASKED 0
-
/* x0-x17 GPREGS context */
-#define SDEI_SAVED_GPREGS 18
+#define SDEI_SAVED_GPREGS 18U
/* Maximum preemption nesting levels: Critical priority and Normal priority */
-#define MAX_EVENT_NESTING 2
+#define MAX_EVENT_NESTING 2U
/* Per-CPU SDEI state access macro */
-#define sdei_get_this_pe_state() (&sdei_cpu_state[plat_my_core_pos()])
+#define sdei_get_this_pe_state() (&cpu_state[plat_my_core_pos()])
/* Structure to store information about an outstanding dispatch */
typedef struct sdei_dispatch_context {
@@ -48,31 +45,33 @@ typedef struct sdei_dispatch_context {
typedef struct sdei_cpu_state {
sdei_dispatch_context_t dispatch_stack[MAX_EVENT_NESTING];
unsigned short stack_top; /* Empty ascending */
- unsigned int pe_masked:1;
- unsigned int pending_enables:1;
+ bool pe_masked;
+ bool pending_enables;
} sdei_cpu_state_t;
/* SDEI states for all cores in the system */
-static sdei_cpu_state_t sdei_cpu_state[PLATFORM_CORE_COUNT];
+static sdei_cpu_state_t cpu_state[PLATFORM_CORE_COUNT];
-unsigned int sdei_pe_mask(void)
+int64_t sdei_pe_mask(void)
{
- unsigned int ret;
+ int64_t ret = 0;
sdei_cpu_state_t *state = sdei_get_this_pe_state();
/*
* Return value indicates whether this call had any effect in the mask
* status of this PE.
*/
- ret = (state->pe_masked ^ PE_MASKED);
- state->pe_masked = PE_MASKED;
+ if (!state->pe_masked) {
+ state->pe_masked = true;
+ ret = 1;
+ }
return ret;
}
void sdei_pe_unmask(void)
{
- int i;
+ unsigned int i;
sdei_ev_map_t *map;
sdei_entry_t *se;
sdei_cpu_state_t *state = sdei_get_this_pe_state();
@@ -95,8 +94,7 @@ void sdei_pe_unmask(void)
se = get_event_entry(map);
sdei_map_lock(map);
- if (is_map_bound(map) &&
- GET_EV_STATE(se, ENABLED) &&
+ if (is_map_bound(map) && GET_EV_STATE(se, ENABLED) &&
(se->reg_flags == SDEI_REGF_RM_PE) &&
(se->affinity == my_mpidr)) {
plat_ic_enable_interrupt(map->intr);
@@ -105,8 +103,8 @@ void sdei_pe_unmask(void)
}
}
- state->pending_enables = 0;
- state->pe_masked = PE_NOT_MASKED;
+ state->pending_enables = false;
+ state->pe_masked = false;
}
/* Push a dispatch context to the dispatch stack */
@@ -129,7 +127,7 @@ static sdei_dispatch_context_t *pop_dispatch(void)
{
sdei_cpu_state_t *state = sdei_get_this_pe_state();
- if (state->stack_top == 0)
+ if (state->stack_top == 0U)
return NULL;
assert(state->stack_top <= MAX_EVENT_NESTING);
@@ -144,27 +142,27 @@ static sdei_dispatch_context_t *get_outstanding_dispatch(void)
{
sdei_cpu_state_t *state = sdei_get_this_pe_state();
- if (state->stack_top == 0)
+ if (state->stack_top == 0U)
return NULL;
assert(state->stack_top <= MAX_EVENT_NESTING);
- return &state->dispatch_stack[state->stack_top - 1];
+ return &state->dispatch_stack[state->stack_top - 1U];
}
static sdei_dispatch_context_t *save_event_ctx(sdei_ev_map_t *map,
void *tgt_ctx)
{
sdei_dispatch_context_t *disp_ctx;
- gp_regs_t *tgt_gpregs;
- el3_state_t *tgt_el3;
+ const gp_regs_t *tgt_gpregs;
+ const el3_state_t *tgt_el3;
- assert(tgt_ctx);
+ assert(tgt_ctx != NULL);
tgt_gpregs = get_gpregs_ctx(tgt_ctx);
tgt_el3 = get_el3state_ctx(tgt_ctx);
disp_ctx = push_dispatch();
- assert(disp_ctx);
+ assert(disp_ctx != NULL);
disp_ctx->map = map;
/* Save general purpose and exception registers */
@@ -175,12 +173,12 @@ static sdei_dispatch_context_t *save_event_ctx(sdei_ev_map_t *map,
return disp_ctx;
}
-static void restore_event_ctx(sdei_dispatch_context_t *disp_ctx, void *tgt_ctx)
+static void restore_event_ctx(const sdei_dispatch_context_t *disp_ctx, void *tgt_ctx)
{
gp_regs_t *tgt_gpregs;
el3_state_t *tgt_el3;
- assert(tgt_ctx);
+ assert(tgt_ctx != NULL);
tgt_gpregs = get_gpregs_ctx(tgt_ctx);
tgt_el3 = get_el3state_ctx(tgt_ctx);
@@ -226,7 +224,7 @@ static cpu_context_t *restore_and_resume_ns_context(void)
cm_set_next_eret_context(NON_SECURE);
ns_ctx = cm_get_context(NON_SECURE);
- assert(ns_ctx);
+ assert(ns_ctx != NULL);
return ns_ctx;
}
@@ -251,7 +249,7 @@ static void setup_ns_dispatch(sdei_ev_map_t *map, sdei_entry_t *se,
* - x2: Interrupted PC
* - x3: Interrupted SPSR
*/
- SMC_SET_GP(ctx, CTX_GPREG_X0, map->ev_num);
+ SMC_SET_GP(ctx, CTX_GPREG_X0, (uint64_t) map->ev_num);
SMC_SET_GP(ctx, CTX_GPREG_X1, se->arg);
SMC_SET_GP(ctx, CTX_GPREG_X2, disp_ctx->elr_el3);
SMC_SET_GP(ctx, CTX_GPREG_X3, disp_ctx->spsr_el3);
@@ -286,7 +284,7 @@ static void handle_masked_trigger(sdei_ev_map_t *map, sdei_entry_t *se,
sdei_cpu_state_t *state, unsigned int intr_raw)
{
uint64_t my_mpidr __unused = (read_mpidr_el1() & MPIDR_AFFINITY_MASK);
- int disable = 0;
+ bool disable = false;
/* Nothing to do for event 0 */
if (map->ev_num == SDEI_EVENT_0)
@@ -297,18 +295,17 @@ static void handle_masked_trigger(sdei_ev_map_t *map, sdei_entry_t *se,
* this CPU, we disable interrupt, leave the interrupt pending, and do
* EOI.
*/
- if (is_event_private(map)) {
- disable = 1;
- } else if (se->reg_flags == SDEI_REGF_RM_PE) {
+ if (is_event_private(map) || (se->reg_flags == SDEI_REGF_RM_PE))
+ disable = true;
+
+ if (se->reg_flags == SDEI_REGF_RM_PE)
assert(se->affinity == my_mpidr);
- disable = 1;
- }
if (disable) {
plat_ic_disable_interrupt(map->intr);
plat_ic_set_interrupt_pending(map->intr);
plat_ic_end_of_interrupt(intr_raw);
- state->pending_enables = 1;
+ state->pending_enables = true;
return;
}
@@ -321,7 +318,7 @@ static void handle_masked_trigger(sdei_ev_map_t *map, sdei_entry_t *se,
* Therefore, we set the interrupt back pending so as to give other
* suitable PEs a chance of handling it.
*/
- assert(plat_ic_is_spi(map->intr));
+ assert(plat_ic_is_spi(map->intr) != 0);
plat_ic_set_interrupt_pending(map->intr);
/*
@@ -344,11 +341,12 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
sdei_entry_t *se;
cpu_context_t *ctx;
sdei_ev_map_t *map;
- sdei_dispatch_context_t *disp_ctx;
+ const sdei_dispatch_context_t *disp_ctx;
unsigned int sec_state;
sdei_cpu_state_t *state;
uint32_t intr;
struct jmpbuf dispatch_jmp;
+ const uint64_t mpidr = read_mpidr_el1();
/*
* To handle an event, the following conditions must be true:
@@ -374,8 +372,8 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
* this interrupt
*/
intr = plat_ic_get_interrupt_id(intr_raw);
- map = find_event_map_by_intr(intr, plat_ic_is_spi(intr));
- if (!map) {
+ map = find_event_map_by_intr(intr, (plat_ic_is_spi(intr) != 0));
+ if (map == NULL) {
ERROR("No SDEI map for interrupt %u\n", intr);
panic();
}
@@ -389,13 +387,13 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
se = get_event_entry(map);
state = sdei_get_this_pe_state();
- if (state->pe_masked == PE_MASKED) {
+ if (state->pe_masked) {
/*
* Interrupts received while this PE was masked can't be
* dispatched.
*/
- SDEI_LOG("interrupt %u on %lx while PE masked\n", map->intr,
- read_mpidr_el1());
+ SDEI_LOG("interrupt %u on %llx while PE masked\n", map->intr,
+ mpidr);
if (is_event_shared(map))
sdei_map_lock(map);
@@ -416,8 +414,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
/* Assert shared event routed to this PE had been configured so */
if (is_event_shared(map) && (se->reg_flags == SDEI_REGF_RM_PE)) {
- assert(se->affinity ==
- (read_mpidr_el1() & MPIDR_AFFINITY_MASK));
+ assert(se->affinity == (mpidr & MPIDR_AFFINITY_MASK));
}
if (!can_sdei_state_trans(se, DO_DISPATCH)) {
@@ -451,7 +448,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
* dispatch, assert the latter is a Normal dispatch. Critical
* events can preempt an outstanding Normal event dispatch.
*/
- if (disp_ctx)
+ if (disp_ctx != NULL)
assert(is_event_normal(disp_ctx->map));
} else {
/*
@@ -467,9 +464,8 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
if (is_event_shared(map))
sdei_map_unlock(map);
- SDEI_LOG("ACK %lx, ev:%d ss:%d spsr:%lx ELR:%lx\n", read_mpidr_el1(),
- map->ev_num, sec_state, read_spsr_el3(),
- read_elr_el3());
+ SDEI_LOG("ACK %llx, ev:%d ss:%d spsr:%lx ELR:%lx\n", mpidr, map->ev_num,
+ sec_state, read_spsr_el3(), read_elr_el3());
ctx = handle;
@@ -497,7 +493,7 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
* Non-secure context was fully saved before dispatch, and has been
* returned to its pre-dispatch state.
*/
- if ((sec_state == SECURE) && (ehf_is_ns_preemption_allowed() == 0))
+ if ((sec_state == SECURE) && (ehf_is_ns_preemption_allowed() == 0U))
restore_and_resume_secure_context();
/*
@@ -511,9 +507,6 @@ int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
}
plat_ic_end_of_interrupt(intr_raw);
- if (is_event_shared(map))
- sdei_map_unlock(map);
-
return 0;
}
@@ -539,7 +532,7 @@ int sdei_dispatch_event(int ev_num)
/* Can't dispatch if events are masked on this PE */
state = sdei_get_this_pe_state();
- if (state->pe_masked == PE_MASKED)
+ if (state->pe_masked)
return -1;
/* Event 0 can't be dispatched */
@@ -548,7 +541,7 @@ int sdei_dispatch_event(int ev_num)
/* Locate mapping corresponding to this event */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return -1;
/* Only explicit events can be dispatched */
@@ -557,7 +550,7 @@ int sdei_dispatch_event(int ev_num)
/* Examine state of dispatch stack */
disp_ctx = get_outstanding_dispatch();
- if (disp_ctx) {
+ if (disp_ctx != NULL) {
/*
* There's an outstanding dispatch. If the outstanding dispatch
* is critical, no more dispatches are possible.
@@ -606,7 +599,7 @@ static void end_sdei_synchronous_dispatch(struct jmpbuf *buffer)
longjmp(buffer);
}
-int sdei_event_complete(int resume, uint64_t pc)
+int sdei_event_complete(bool resume, uint64_t pc)
{
sdei_dispatch_context_t *disp_ctx;
sdei_entry_t *se;
@@ -617,7 +610,7 @@ int sdei_event_complete(int resume, uint64_t pc)
/* Return error if called without an active event */
disp_ctx = get_outstanding_dispatch();
- if (!disp_ctx)
+ if (disp_ctx == NULL)
return SDEI_EDENY;
/* Validate resumption point */
@@ -625,9 +618,12 @@ int sdei_event_complete(int resume, uint64_t pc)
return SDEI_EDENY;
map = disp_ctx->map;
- assert(map);
+ assert(map != NULL);
se = get_event_entry(map);
+ if (is_event_shared(map))
+ sdei_map_lock(map);
+
act = resume ? DO_COMPLETE_RESUME : DO_COMPLETE;
if (!can_sdei_state_trans(se, act)) {
if (is_event_shared(map))
@@ -635,15 +631,15 @@ int sdei_event_complete(int resume, uint64_t pc)
return SDEI_EDENY;
}
+ if (is_event_shared(map))
+ sdei_map_unlock(map);
+
/* Having done sanity checks, pop dispatch */
- pop_dispatch();
+ (void) pop_dispatch();
SDEI_LOG("EOI:%lx, %d spsr:%lx elr:%lx\n", read_mpidr_el1(),
map->ev_num, read_spsr_el3(), read_elr_el3());
- if (is_event_shared(map))
- sdei_map_lock(map);
-
/*
* Restore Non-secure to how it was originally interrupted. Once done,
* it's up-to-date with the saved copy.
@@ -684,7 +680,7 @@ int sdei_event_complete(int resume, uint64_t pc)
return 0;
}
-int sdei_event_context(void *handle, unsigned int param)
+int64_t sdei_event_context(void *handle, unsigned int param)
{
sdei_dispatch_context_t *disp_ctx;
@@ -693,10 +689,10 @@ int sdei_event_context(void *handle, unsigned int param)
/* Get outstanding dispatch on this CPU */
disp_ctx = get_outstanding_dispatch();
- if (!disp_ctx)
+ if (disp_ctx == NULL)
return SDEI_EDENY;
- assert(disp_ctx->map);
+ assert(disp_ctx->map != NULL);
if (!can_sdei_state_trans(get_event_entry(disp_ctx->map), DO_CONTEXT))
return SDEI_EDENY;
@@ -706,5 +702,5 @@ int sdei_event_context(void *handle, unsigned int param)
* which can complete the event
*/
- return disp_ctx->x[param];
+ return (int64_t) disp_ctx->x[param];
}
diff --git a/services/std_svc/sdei/sdei_main.c b/services/std_svc/sdei/sdei_main.c
index d6d092dec..9b78d7fbc 100644
--- a/services/std_svc/sdei/sdei_main.c
+++ b/services/std_svc/sdei/sdei_main.c
@@ -22,14 +22,12 @@
#include <utils.h>
#include "sdei_private.h"
-#define MAJOR_VERSION 1
-#define MINOR_VERSION 0
-#define VENDOR_VERSION 0
+#define MAJOR_VERSION 1ULL
+#define MINOR_VERSION 0ULL
+#define VENDOR_VERSION 0ULL
#define MAKE_SDEI_VERSION(_major, _minor, _vendor) \
- ((((unsigned long long)(_major)) << 48) | \
- (((unsigned long long)(_minor)) << 32) | \
- (_vendor))
+ ((((_major)) << 48ULL) | (((_minor)) << 32ULL) | (_vendor))
#define LOWEST_INTR_PRIORITY 0xff
@@ -47,7 +45,7 @@ static void init_map(sdei_ev_map_t *map)
}
/* Convert mapping to SDEI class */
-sdei_class_t map_to_class(sdei_ev_map_t *map)
+static sdei_class_t map_to_class(sdei_ev_map_t *map)
{
return is_event_critical(map) ? SDEI_CRITICAL : SDEI_NORMAL;
}
@@ -64,7 +62,7 @@ static void clear_event_entries(sdei_entry_t *se)
/* Perform CPU-specific state initialisation */
static void *sdei_cpu_on_init(const void *arg)
{
- int i;
+ unsigned int i;
sdei_ev_map_t *map;
sdei_entry_t *se;
@@ -78,15 +76,16 @@ static void *sdei_cpu_on_init(const void *arg)
SDEI_LOG("Private events initialized on %lx\n", read_mpidr_el1());
/* All PEs start with SDEI events masked */
- sdei_pe_mask();
+ (void) sdei_pe_mask();
- return 0;
+ return NULL;
}
/* Initialise an SDEI class */
-void sdei_class_init(sdei_class_t class)
+static void sdei_class_init(sdei_class_t class)
{
- unsigned int i, zero_found __unused = 0;
+ unsigned int i;
+ bool zero_found __unused = false;
int ev_num_so_far __unused;
sdei_ev_map_t *map;
@@ -126,7 +125,7 @@ void sdei_class_init(sdei_class_t class)
num_dyn_shrd_slots++;
} else {
/* Shared mappings must be bound to shared interrupt */
- assert(plat_ic_is_spi(map->intr));
+ assert(plat_ic_is_spi(map->intr) != 0);
set_map_bound(map);
}
@@ -143,7 +142,7 @@ void sdei_class_init(sdei_class_t class)
ev_num_so_far = map->ev_num;
if (map->ev_num == SDEI_EVENT_0) {
- zero_found = 1;
+ zero_found = true;
/* Event 0 must be a Secure SGI */
assert(is_secure_sgi(map->intr));
@@ -197,7 +196,7 @@ void sdei_class_init(sdei_class_t class)
* Private mappings must be bound to private
* interrupt.
*/
- assert(plat_ic_is_ppi(map->intr));
+ assert(plat_ic_is_ppi((unsigned) map->intr) != 0);
set_map_bound(map);
}
}
@@ -208,7 +207,7 @@ void sdei_class_init(sdei_class_t class)
/* Ensure event 0 is in the mapping */
assert(zero_found);
- sdei_cpu_on_init(NULL);
+ (void) sdei_cpu_on_init(NULL);
}
/* SDEI dispatcher initialisation */
@@ -236,7 +235,7 @@ static void set_sdei_entry(sdei_entry_t *se, uint64_t ep, uint64_t arg,
se->reg_flags = flags;
}
-static unsigned long long sdei_version(void)
+static uint64_t sdei_version(void)
{
return MAKE_SDEI_VERSION(MAJOR_VERSION, MINOR_VERSION, VENDOR_VERSION);
}
@@ -263,17 +262,18 @@ static int validate_flags(uint64_t flags, uint64_t mpidr)
/* Set routing of an SDEI event */
static int sdei_event_routing_set(int ev_num, uint64_t flags, uint64_t mpidr)
{
- int ret, routing;
+ int ret;
+ unsigned int routing;
sdei_ev_map_t *map;
sdei_entry_t *se;
ret = validate_flags(flags, mpidr);
- if (ret)
+ if (ret != 0)
return ret;
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
/* The event must not be private */
@@ -295,11 +295,11 @@ static int sdei_event_routing_set(int ev_num, uint64_t flags, uint64_t mpidr)
}
/* Choose appropriate routing */
- routing = (flags == SDEI_REGF_RM_ANY) ? INTR_ROUTING_MODE_ANY :
- INTR_ROUTING_MODE_PE;
+ routing = (unsigned int) ((flags == SDEI_REGF_RM_ANY) ?
+ INTR_ROUTING_MODE_ANY : INTR_ROUTING_MODE_PE);
/* Update event registration flag */
- se->reg_flags = flags;
+ se->reg_flags = (unsigned int) flags;
/*
* ROUTING_SET is permissible only when event composite state is
@@ -315,24 +315,27 @@ finish:
}
/* Register handler and argument for an SDEI event */
-static int sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
+static int64_t sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
uint64_t flags, uint64_t mpidr)
{
int ret;
+ unsigned int routing;
sdei_entry_t *se;
sdei_ev_map_t *map;
sdei_state_t backup_state;
- if (!ep || (plat_sdei_validate_entry_point(ep, sdei_client_el()) != 0))
+ if ((ep == 0U) || (plat_sdei_validate_entry_point(
+ ep, sdei_client_el()) != 0)) {
return SDEI_EINVAL;
+ }
ret = validate_flags(flags, mpidr);
- if (ret)
+ if (ret != 0)
return ret;
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
/* Private events always target the PE */
@@ -371,7 +374,7 @@ static int sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
if (is_map_bound(map)) {
/* Meanwhile, did any PE ACK the interrupt? */
- if (plat_ic_get_interrupt_active(map->intr))
+ if (plat_ic_get_interrupt_active(map->intr) != 0U)
goto fallback;
/* The interrupt must currently owned by Non-secure */
@@ -404,16 +407,15 @@ static int sdei_event_register(int ev_num, uint64_t ep, uint64_t arg,
* already ensure that shared events get bound to SPIs.
*/
if (is_event_shared(map)) {
- plat_ic_set_spi_routing(map->intr,
- ((flags == SDEI_REGF_RM_ANY) ?
- INTR_ROUTING_MODE_ANY :
- INTR_ROUTING_MODE_PE),
+ routing = (unsigned int) ((flags == SDEI_REGF_RM_ANY) ?
+ INTR_ROUTING_MODE_ANY : INTR_ROUTING_MODE_PE);
+ plat_ic_set_spi_routing(map->intr, routing,
(u_register_t) mpidr);
}
}
/* Populate event entries */
- set_sdei_entry(se, ep, arg, flags, mpidr);
+ set_sdei_entry(se, ep, arg, (unsigned int) flags, mpidr);
/* Increment register count */
map->reg_count++;
@@ -432,15 +434,16 @@ fallback:
}
/* Enable SDEI event */
-static int sdei_event_enable(int ev_num)
+static int64_t sdei_event_enable(int ev_num)
{
sdei_ev_map_t *map;
sdei_entry_t *se;
- int ret, before, after;
+ int ret;
+ bool before, after;
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
se = get_event_entry(map);
@@ -475,11 +478,12 @@ static int sdei_event_disable(int ev_num)
{
sdei_ev_map_t *map;
sdei_entry_t *se;
- int ret, before, after;
+ int ret;
+ bool before, after;
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
se = get_event_entry(map);
@@ -510,17 +514,18 @@ finish:
}
/* Query SDEI event information */
-static uint64_t sdei_event_get_info(int ev_num, int info)
+static int64_t sdei_event_get_info(int ev_num, int info)
{
sdei_entry_t *se;
sdei_ev_map_t *map;
- unsigned int flags, registered;
+ uint64_t flags;
+ bool registered;
uint64_t affinity;
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
se = get_event_entry(map);
@@ -576,7 +581,7 @@ static int sdei_event_unregister(int ev_num)
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
se = get_event_entry(map);
@@ -648,7 +653,7 @@ static int sdei_event_status(int ev_num)
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
se = get_event_entry(map);
@@ -662,27 +667,27 @@ static int sdei_event_status(int ev_num)
if (is_event_shared(map))
sdei_map_unlock(map);
- return state;
+ return (int) state;
}
/* Bind an SDEI event to an interrupt */
-static int sdei_interrupt_bind(int intr_num)
+static int sdei_interrupt_bind(unsigned int intr_num)
{
sdei_ev_map_t *map;
- int retry = 1, shared_mapping;
+ bool retry = true, shared_mapping;
/* SGIs are not allowed to be bound */
- if (plat_ic_is_sgi(intr_num))
+ if (plat_ic_is_sgi(intr_num) != 0)
return SDEI_EINVAL;
- shared_mapping = plat_ic_is_spi(intr_num);
+ shared_mapping = (plat_ic_is_spi(intr_num) != 0);
do {
/*
* Bail out if there is already an event for this interrupt,
* either platform-defined or dynamic.
*/
map = find_event_map_by_intr(intr_num, shared_mapping);
- if (map) {
+ if (map != NULL) {
if (is_map_dynamic(map)) {
if (is_map_bound(map)) {
/*
@@ -703,7 +708,7 @@ static int sdei_interrupt_bind(int intr_num)
* SDEI_DYN_IRQ.
*/
map = find_event_map_by_intr(SDEI_DYN_IRQ, shared_mapping);
- if (!map)
+ if (map == NULL)
return SDEI_ENOMEM;
/* The returned mapping must be dynamic */
@@ -727,7 +732,7 @@ static int sdei_interrupt_bind(int intr_num)
if (!is_map_bound(map)) {
map->intr = intr_num;
set_map_bound(map);
- retry = 0;
+ retry = false;
}
sdei_map_unlock(map);
} while (retry);
@@ -744,7 +749,7 @@ static int sdei_interrupt_release(int ev_num)
/* Check if valid event number */
map = find_event_map(ev_num);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
if (!is_map_dynamic(map))
@@ -774,7 +779,7 @@ static int sdei_interrupt_release(int ev_num)
* Deny release if the interrupt is active, which means it's
* probably being acknowledged and handled elsewhere.
*/
- if (plat_ic_get_interrupt_active(map->intr)) {
+ if (plat_ic_get_interrupt_active(map->intr) != 0U) {
ret = SDEI_EDENY;
goto finish;
}
@@ -802,7 +807,8 @@ finish:
static int sdei_private_reset(void)
{
sdei_ev_map_t *map;
- int ret = 0, final_ret = 0, i;
+ int ret = 0, final_ret = 0;
+ unsigned int i;
/* Unregister all private events */
for_each_private_map(i, map) {
@@ -824,7 +830,8 @@ static int sdei_shared_reset(void)
{
const sdei_mapping_t *mapping;
sdei_ev_map_t *map;
- int ret = 0, final_ret = 0, i, j;
+ int ret = 0, final_ret = 0;
+ unsigned int i, j;
/* Unregister all shared events */
for_each_shared_map(i, map) {
@@ -867,17 +874,17 @@ static int sdei_shared_reset(void)
}
/* Send a signal to another SDEI client PE */
-int sdei_signal(int event, uint64_t target_pe)
+static int sdei_signal(int ev_num, uint64_t target_pe)
{
sdei_ev_map_t *map;
/* Only event 0 can be signalled */
- if (event != SDEI_EVENT_0)
+ if (ev_num != SDEI_EVENT_0)
return SDEI_EINVAL;
/* Find mapping for event 0 */
map = find_event_map(SDEI_EVENT_0);
- if (!map)
+ if (map == NULL)
return SDEI_EINVAL;
/* The event must be signalable */
@@ -889,20 +896,20 @@ int sdei_signal(int event, uint64_t target_pe)
return SDEI_EINVAL;
/* Raise SGI. Platform will validate target_pe */
- plat_ic_raise_el3_sgi(map->intr, (u_register_t) target_pe);
+ plat_ic_raise_el3_sgi((int) map->intr, (u_register_t) target_pe);
return 0;
}
/* Query SDEI dispatcher features */
-uint64_t sdei_features(unsigned int feature)
+static uint64_t sdei_features(unsigned int feature)
{
if (feature == SDEI_FEATURE_BIND_SLOTS) {
return FEATURE_BIND_SLOTS(num_dyn_priv_slots,
num_dyn_shrd_slots);
}
- return SDEI_EINVAL;
+ return (uint64_t) SDEI_EINVAL;
}
/* SDEI top level handler for servicing SMCs */
@@ -917,58 +924,61 @@ uint64_t sdei_smc_handler(uint32_t smc_fid,
{
uint64_t x5;
- int ss = get_interrupt_src_ss(flags);
+ unsigned int ss = (unsigned int) get_interrupt_src_ss(flags);
int64_t ret;
- unsigned int resume = 0;
+ bool resume = false;
+ cpu_context_t *ctx = handle;
+ int ev_num = (int) x1;
if (ss != NON_SECURE)
- SMC_RET1(handle, SMC_UNK);
+ SMC_RET1(ctx, SMC_UNK);
/* Verify the caller EL */
if (GET_EL(read_spsr_el3()) != sdei_client_el())
- SMC_RET1(handle, SMC_UNK);
+ SMC_RET1(ctx, SMC_UNK);
switch (smc_fid) {
case SDEI_VERSION:
SDEI_LOG("> VER\n");
- ret = sdei_version();
- SDEI_LOG("< VER:%lx\n", ret);
- SMC_RET1(handle, ret);
+ ret = (int64_t) sdei_version();
+ SDEI_LOG("< VER:%llx\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_REGISTER:
- x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
- SDEI_LOG("> REG(n:%d e:%lx a:%lx f:%x m:%lx)\n", (int) x1,
+ x5 = SMC_GET_GP(ctx, CTX_GPREG_X5);
+ SDEI_LOG("> REG(n:%d e:%llx a:%llx f:%x m:%llx)\n", ev_num,
x2, x3, (int) x4, x5);
- ret = sdei_event_register(x1, x2, x3, x4, x5);
- SDEI_LOG("< REG:%ld\n", ret);
- SMC_RET1(handle, ret);
+ ret = sdei_event_register(ev_num, x2, x3, x4, x5);
+ SDEI_LOG("< REG:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_ENABLE:
SDEI_LOG("> ENABLE(n:%d)\n", (int) x1);
- ret = sdei_event_enable(x1);
- SDEI_LOG("< ENABLE:%ld\n", ret);
- SMC_RET1(handle, ret);
+ ret = sdei_event_enable(ev_num);
+ SDEI_LOG("< ENABLE:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_DISABLE:
- SDEI_LOG("> DISABLE(n:%d)\n", (int) x1);
- ret = sdei_event_disable(x1);
- SDEI_LOG("< DISABLE:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> DISABLE(n:%d)\n", ev_num);
+ ret = sdei_event_disable(ev_num);
+ SDEI_LOG("< DISABLE:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_CONTEXT:
SDEI_LOG("> CTX(p:%d):%lx\n", (int) x1, read_mpidr_el1());
- ret = sdei_event_context(handle, x1);
- SDEI_LOG("< CTX:%ld\n", ret);
- SMC_RET1(handle, ret);
+ ret = sdei_event_context(ctx, (unsigned int) x1);
+ SDEI_LOG("< CTX:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_COMPLETE_AND_RESUME:
- resume = 1;
+ resume = true;
+ /* Fallthrough */
case SDEI_EVENT_COMPLETE:
- SDEI_LOG("> COMPLETE(r:%d sta/ep:%lx):%lx\n", resume, x1,
- read_mpidr_el1());
+ SDEI_LOG("> COMPLETE(r:%u sta/ep:%llx):%lx\n",
+ (unsigned int) resume, x1, read_mpidr_el1());
ret = sdei_event_complete(resume, x1);
- SDEI_LOG("< COMPLETE:%lx\n", ret);
+ SDEI_LOG("< COMPLETE:%llx\n", ret);
/*
* Set error code only if the call failed. If the call
@@ -977,82 +987,82 @@ uint64_t sdei_smc_handler(uint32_t smc_fid,
* shouldn't be modified. We don't return to the caller in this
* case anyway.
*/
- if (ret)
- SMC_RET1(handle, ret);
+ if (ret != 0)
+ SMC_RET1(ctx, ret);
- SMC_RET0(handle);
+ SMC_RET0(ctx);
case SDEI_EVENT_STATUS:
- SDEI_LOG("> STAT(n:%d)\n", (int) x1);
- ret = sdei_event_status(x1);
- SDEI_LOG("< STAT:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> STAT(n:%d)\n", ev_num);
+ ret = sdei_event_status(ev_num);
+ SDEI_LOG("< STAT:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_GET_INFO:
- SDEI_LOG("> INFO(n:%d, %d)\n", (int) x1, (int) x2);
- ret = sdei_event_get_info(x1, x2);
- SDEI_LOG("< INFO:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> INFO(n:%d, %d)\n", ev_num, (int) x2);
+ ret = sdei_event_get_info(ev_num, (int) x2);
+ SDEI_LOG("< INFO:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_UNREGISTER:
- SDEI_LOG("> UNREG(n:%d)\n", (int) x1);
- ret = sdei_event_unregister(x1);
- SDEI_LOG("< UNREG:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> UNREG(n:%d)\n", ev_num);
+ ret = sdei_event_unregister(ev_num);
+ SDEI_LOG("< UNREG:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_PE_UNMASK:
SDEI_LOG("> UNMASK:%lx\n", read_mpidr_el1());
sdei_pe_unmask();
SDEI_LOG("< UNMASK:%d\n", 0);
- SMC_RET1(handle, 0);
+ SMC_RET1(ctx, 0);
case SDEI_PE_MASK:
SDEI_LOG("> MASK:%lx\n", read_mpidr_el1());
ret = sdei_pe_mask();
- SDEI_LOG("< MASK:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("< MASK:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_INTERRUPT_BIND:
SDEI_LOG("> BIND(%d)\n", (int) x1);
- ret = sdei_interrupt_bind(x1);
- SDEI_LOG("< BIND:%ld\n", ret);
- SMC_RET1(handle, ret);
+ ret = sdei_interrupt_bind((unsigned int) x1);
+ SDEI_LOG("< BIND:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_INTERRUPT_RELEASE:
- SDEI_LOG("> REL(%d)\n", (int) x1);
- ret = sdei_interrupt_release(x1);
- SDEI_LOG("< REL:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> REL(%d)\n", ev_num);
+ ret = sdei_interrupt_release(ev_num);
+ SDEI_LOG("< REL:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_SHARED_RESET:
SDEI_LOG("> S_RESET():%lx\n", read_mpidr_el1());
ret = sdei_shared_reset();
- SDEI_LOG("< S_RESET:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("< S_RESET:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_PRIVATE_RESET:
SDEI_LOG("> P_RESET():%lx\n", read_mpidr_el1());
ret = sdei_private_reset();
- SDEI_LOG("< P_RESET:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("< P_RESET:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_ROUTING_SET:
- SDEI_LOG("> ROUTE_SET(n:%d f:%lx aff:%lx)\n", (int) x1, x2, x3);
- ret = sdei_event_routing_set(x1, x2, x3);
- SDEI_LOG("< ROUTE_SET:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> ROUTE_SET(n:%d f:%llx aff:%llx)\n", ev_num, x2, x3);
+ ret = sdei_event_routing_set(ev_num, x2, x3);
+ SDEI_LOG("< ROUTE_SET:%lld\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_FEATURES:
- SDEI_LOG("> FTRS(f:%lx)\n", x1);
- ret = sdei_features(x1);
- SDEI_LOG("< FTRS:%lx\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> FTRS(f:%llx)\n", x1);
+ ret = (int64_t) sdei_features((unsigned int) x1);
+ SDEI_LOG("< FTRS:%llx\n", ret);
+ SMC_RET1(ctx, ret);
case SDEI_EVENT_SIGNAL:
- SDEI_LOG("> SIGNAL(e:%lx t:%lx)\n", x1, x2);
- ret = sdei_signal(x1, x2);
- SDEI_LOG("< SIGNAL:%ld\n", ret);
- SMC_RET1(handle, ret);
+ SDEI_LOG("> SIGNAL(e:%d t:%llx)\n", ev_num, x2);
+ ret = sdei_signal(ev_num, x2);
+ SDEI_LOG("< SIGNAL:%lld\n", ret);
+ SMC_RET1(ctx, ret);
default:
/* Do nothing in default case */
@@ -1060,7 +1070,7 @@ uint64_t sdei_smc_handler(uint32_t smc_fid,
}
WARN("Unimplemented SDEI Call: 0x%x\n", smc_fid);
- SMC_RET1(handle, SMC_UNK);
+ SMC_RET1(ctx, SMC_UNK);
}
/* Subscribe to PSCI CPU on to initialize per-CPU SDEI configuration */
diff --git a/services/std_svc/sdei/sdei_private.h b/services/std_svc/sdei/sdei_private.h
index 874fc22db..f5197c616 100644
--- a/services/std_svc/sdei/sdei_private.h
+++ b/services/std_svc/sdei/sdei_private.h
@@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SDEI_PRIVATE_H__
-#define __SDEI_PRIVATE_H__
+#ifndef SDEI_PRIVATE_H
+#define SDEI_PRIVATE_H
#include <arch_helpers.h>
#include <context_mgmt.h>
@@ -17,7 +17,7 @@
#include <setjmp.h>
#include <spinlock.h>
#include <stdbool.h>
-#include <types.h>
+#include <stdint.h>
#include <utils_def.h>
#ifdef AARCH32
@@ -36,12 +36,12 @@
#define SDEI_LOG(...) VERBOSE("SDEI: " __VA_ARGS__)
/* SDEI handler unregistered state. This is the default state. */
-#define SDEI_STATE_UNREGISTERED 0
+#define SDEI_STATE_UNREGISTERED 0U
/* SDE event status values in bit position */
-#define SDEI_STATF_REGISTERED 0
-#define SDEI_STATF_ENABLED 1
-#define SDEI_STATF_RUNNING 2
+#define SDEI_STATF_REGISTERED 0U
+#define SDEI_STATF_ENABLED 1U
+#define SDEI_STATF_RUNNING 2U
/* SDEI SMC error codes */
#define SDEI_EINVAL (-2)
@@ -62,18 +62,18 @@
#define SDEI_INFO_EV_ROUTING_MODE 3
#define SDEI_INFO_EV_ROUTING_AFF 4
-#define SDEI_PRIVATE_MAPPING() (&sdei_global_mappings[_SDEI_MAP_IDX_PRIV])
-#define SDEI_SHARED_MAPPING() (&sdei_global_mappings[_SDEI_MAP_IDX_SHRD])
+#define SDEI_PRIVATE_MAPPING() (&sdei_global_mappings[SDEI_MAP_IDX_PRIV_])
+#define SDEI_SHARED_MAPPING() (&sdei_global_mappings[SDEI_MAP_IDX_SHRD_])
#define for_each_mapping_type(_i, _mapping) \
- for (_i = 0, _mapping = &sdei_global_mappings[i]; \
- _i < _SDEI_MAP_IDX_MAX; \
- _i++, _mapping = &sdei_global_mappings[i])
+ for ((_i) = 0, (_mapping) = &sdei_global_mappings[(_i)]; \
+ (_i) < SDEI_MAP_IDX_MAX_; \
+ (_i)++, (_mapping) = &sdei_global_mappings[(_i)])
#define iterate_mapping(_mapping, _i, _map) \
- for (_map = (_mapping)->map, _i = 0; \
- _i < (_mapping)->num_maps; \
- _i++, _map++)
+ for ((_map) = (_mapping)->map, (_i) = 0; \
+ (_i) < (_mapping)->num_maps; \
+ (_i)++, (_map)++)
#define for_each_private_map(_i, _map) \
iterate_mapping(SDEI_PRIVATE_MAPPING(), _i, _map)
@@ -82,45 +82,45 @@
iterate_mapping(SDEI_SHARED_MAPPING(), _i, _map)
/* SDEI_FEATURES */
-#define SDEI_FEATURE_BIND_SLOTS 0
-#define BIND_SLOTS_MASK 0xffff
-#define FEATURES_SHARED_SLOTS_SHIFT 16
-#define FEATURES_PRIVATE_SLOTS_SHIFT 0
+#define SDEI_FEATURE_BIND_SLOTS 0U
+#define BIND_SLOTS_MASK 0xffffU
+#define FEATURES_SHARED_SLOTS_SHIFT 16U
+#define FEATURES_PRIVATE_SLOTS_SHIFT 0U
#define FEATURE_BIND_SLOTS(_priv, _shrd) \
- ((((_priv) & BIND_SLOTS_MASK) << FEATURES_PRIVATE_SLOTS_SHIFT) | \
- (((_shrd) & BIND_SLOTS_MASK) << FEATURES_SHARED_SLOTS_SHIFT))
+ (((((uint64_t) (_priv)) & BIND_SLOTS_MASK) << FEATURES_PRIVATE_SLOTS_SHIFT) | \
+ ((((uint64_t) (_shrd)) & BIND_SLOTS_MASK) << FEATURES_SHARED_SLOTS_SHIFT))
#define GET_EV_STATE(_e, _s) get_ev_state_bit(_e, SDEI_STATF_##_s)
#define SET_EV_STATE(_e, _s) clr_ev_state_bit(_e->state, SDEI_STATF_##_s)
-static inline int is_event_private(sdei_ev_map_t *map)
+static inline bool is_event_private(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_PRIVATE_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_PRIVATE_SHIFT_)) != 0U);
}
-static inline int is_event_shared(sdei_ev_map_t *map)
+static inline bool is_event_shared(sdei_ev_map_t *map)
{
return !is_event_private(map);
}
-static inline int is_event_critical(sdei_ev_map_t *map)
+static inline bool is_event_critical(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_CRITICAL_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_CRITICAL_SHIFT_)) != 0U);
}
-static inline int is_event_normal(sdei_ev_map_t *map)
+static inline bool is_event_normal(sdei_ev_map_t *map)
{
return !is_event_critical(map);
}
-static inline int is_event_signalable(sdei_ev_map_t *map)
+static inline bool is_event_signalable(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_SIGNALABLE_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_SIGNALABLE_SHIFT_)) != 0U);
}
-static inline int is_map_dynamic(sdei_ev_map_t *map)
+static inline bool is_map_dynamic(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_DYNAMIC_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_DYNAMIC_SHIFT_)) != 0U);
}
/*
@@ -129,29 +129,29 @@ static inline int is_map_dynamic(sdei_ev_map_t *map)
* called on them. This can be used on both static or dynamic events to check
* for an associated interrupt.
*/
-static inline int is_map_bound(sdei_ev_map_t *map)
+static inline bool is_map_bound(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_BOUND_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_BOUND_SHIFT_)) != 0U);
}
static inline void set_map_bound(sdei_ev_map_t *map)
{
- map->map_flags |= BIT(_SDEI_MAPF_BOUND_SHIFT);
+ map->map_flags |= BIT_32(SDEI_MAPF_BOUND_SHIFT_);
}
-static inline int is_map_explicit(sdei_ev_map_t *map)
+static inline bool is_map_explicit(sdei_ev_map_t *map)
{
- return ((map->map_flags & BIT(_SDEI_MAPF_EXPLICIT_SHIFT)) != 0);
+ return ((map->map_flags & BIT_32(SDEI_MAPF_EXPLICIT_SHIFT_)) != 0U);
}
static inline void clr_map_bound(sdei_ev_map_t *map)
{
- map->map_flags &= ~(BIT(_SDEI_MAPF_BOUND_SHIFT));
+ map->map_flags &= ~BIT_32(SDEI_MAPF_BOUND_SHIFT_);
}
-static inline int is_secure_sgi(unsigned int intr)
+static inline bool is_secure_sgi(unsigned int intr)
{
- return (plat_ic_is_sgi(intr) &&
+ return ((plat_ic_is_sgi(intr) != 0) &&
(plat_ic_get_interrupt_type(intr) == INTR_TYPE_EL3));
}
@@ -164,24 +164,24 @@ static inline unsigned int sdei_client_el(void)
cpu_context_t *ns_ctx = cm_get_context(NON_SECURE);
el3_state_t *el3_ctx = get_el3state_ctx(ns_ctx);
- return read_ctx_reg(el3_ctx, CTX_SCR_EL3) & SCR_HCE_BIT ? MODE_EL2 :
- MODE_EL1;
+ return ((read_ctx_reg(el3_ctx, CTX_SCR_EL3) & SCR_HCE_BIT) != 0U) ?
+ MODE_EL2 : MODE_EL1;
}
static inline unsigned int sdei_event_priority(sdei_ev_map_t *map)
{
- return is_event_critical(map) ? PLAT_SDEI_CRITICAL_PRI :
- PLAT_SDEI_NORMAL_PRI;
+ return (unsigned int) (is_event_critical(map) ? PLAT_SDEI_CRITICAL_PRI :
+ PLAT_SDEI_NORMAL_PRI);
}
-static inline int get_ev_state_bit(sdei_entry_t *se, unsigned int bit_no)
+static inline bool get_ev_state_bit(sdei_entry_t *se, unsigned int bit_no)
{
- return ((se->state & BIT(bit_no)) != 0);
+ return ((se->state & BIT_32(bit_no)) != 0U);
}
static inline void clr_ev_state_bit(sdei_entry_t *se, unsigned int bit_no)
{
- se->state &= ~BIT(bit_no);
+ se->state &= ~BIT_32(bit_no);
}
/* SDEI actions for state transition */
@@ -228,19 +228,19 @@ extern sdei_entry_t sdei_shared_event_table[];
void init_sdei_state(void);
-sdei_ev_map_t *find_event_map_by_intr(int intr_num, int shared);
+sdei_ev_map_t *find_event_map_by_intr(unsigned int intr_num, bool shared);
sdei_ev_map_t *find_event_map(int ev_num);
sdei_entry_t *get_event_entry(sdei_ev_map_t *map);
-int sdei_event_context(void *handle, unsigned int param);
-int sdei_event_complete(int resume, uint64_t arg);
+int64_t sdei_event_context(void *handle, unsigned int param);
+int sdei_event_complete(bool resume, uint64_t pc);
void sdei_pe_unmask(void);
-unsigned int sdei_pe_mask(void);
+int64_t sdei_pe_mask(void);
-int sdei_intr_handler(uint32_t intr, uint32_t flags, void *handle,
+int sdei_intr_handler(uint32_t intr_raw, uint32_t flags, void *handle,
void *cookie);
bool can_sdei_state_trans(sdei_entry_t *se, sdei_action_t act);
void begin_sdei_synchronous_dispatch(struct jmpbuf *buffer);
-#endif /* __SDEI_PRIVATE_H__ */
+#endif /* SDEI_PRIVATE_H */
diff --git a/services/std_svc/sdei/sdei_state.c b/services/std_svc/sdei/sdei_state.c
index c1f099fa8..66657862d 100644
--- a/services/std_svc/sdei/sdei_state.c
+++ b/services/std_svc/sdei/sdei_state.c
@@ -10,13 +10,13 @@
#include "sdei_private.h"
/* Aliases for SDEI handler states: 'R'unning, 'E'nabled, and re'G'istered */
-#define r_ 0
+#define r_ 0U
#define R_ (1u << SDEI_STATF_RUNNING)
-#define e_ 0
+#define e_ 0U
#define E_ (1u << SDEI_STATF_ENABLED)
-#define g_ 0
+#define g_ 0U
#define G_ (1u << SDEI_STATF_REGISTERED)
/* All possible composite handler states */
@@ -29,7 +29,7 @@
#define REg_ (R_ | E_ | g_)
#define REG_ (R_ | E_ | G_)
-#define MAX_STATES (REG_ + 1)
+#define MAX_STATES (REG_ + 1u)
/* Invalid state */
#define SDEI_STATE_INVALID ((sdei_state_t) (-1))
diff --git a/services/std_svc/spm/sp_setup.c b/services/std_svc/spm/sp_setup.c
index b9b67f722..0d61306fa 100644
--- a/services/std_svc/spm/sp_setup.c
+++ b/services/std_svc/spm/sp_setup.c
@@ -107,38 +107,22 @@ void spm_sp_setup(sp_context_t *sp_ctx)
* MMU-related registers
* ---------------------
*/
+ xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
- /* Set attributes in the right indices of the MAIR */
- u_register_t mair_el1 =
- MAIR_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX) |
- MAIR_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, ATTR_IWBWA_OWBWA_NTR_INDEX) |
- MAIR_ATTR_SET(ATTR_NON_CACHEABLE, ATTR_NON_CACHEABLE_INDEX);
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1, mair_el1);
-
- /* Setup TCR_EL1. */
- u_register_t tcr_ps_bits = tcr_physical_addr_size_bits(PLAT_PHY_ADDR_SPACE_SIZE);
-
- u_register_t tcr_el1 =
- /* Size of region addressed by TTBR0_EL1 = 2^(64-T0SZ) bytes. */
- (64 - __builtin_ctzl(PLAT_VIRT_ADDR_SPACE_SIZE)) |
- /* Inner and outer WBWA, shareable. */
- TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WBA | TCR_RGN_INNER_WBA |
- /* Set the granularity to 4KB. */
- TCR_TG0_4K |
- /* Limit Intermediate Physical Address Size. */
- tcr_ps_bits << TCR_EL1_IPS_SHIFT |
- /* Disable translations using TBBR1_EL1. */
- TCR_EPD1_BIT
- /* The remaining fields related to TBBR1_EL1 are left as zero. */
- ;
+ uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
- tcr_el1 &= ~(
- /* Enable translations using TBBR0_EL1 */
- TCR_EPD0_BIT
- );
+ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table,
+ xlat_ctx->pa_max_address, xlat_ctx->va_max_address,
+ EL1_EL0_REGIME);
+
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1,
+ mmu_cfg_params[MMU_CFG_MAIR]);
+
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
+ mmu_cfg_params[MMU_CFG_TCR]);
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1, tcr_el1);
+ write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
+ mmu_cfg_params[MMU_CFG_TTBR0]);
/* Setup SCTLR_EL1 */
u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
@@ -174,13 +158,6 @@ void spm_sp_setup(sp_context_t *sp_ctx)
write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
- uint64_t *xlat_base =
- ((xlat_ctx_t *)sp_ctx->xlat_ctx_handle)->base_table;
-
- /* Point TTBR0_EL1 at the tables of the context created for the SP. */
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
- (u_register_t)xlat_base);
-
/*
* Setup other system registers
* ----------------------------
diff --git a/services/std_svc/spm/sp_xlat.c b/services/std_svc/spm/sp_xlat.c
index 2aa2fa135..352713860 100644
--- a/services/std_svc/spm/sp_xlat.c
+++ b/services/std_svc/spm/sp_xlat.c
@@ -44,7 +44,7 @@ xlat_ctx_t *spm_get_sp_xlat_context(void)
* converts an attributes value from the SMC format to the mmap_attr_t format by
* setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER.
* The other fields are left as 0 because they are ignored by the function
- * change_mem_attributes().
+ * xlat_change_mem_attributes_ctx().
*/
static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
{
@@ -112,12 +112,12 @@ int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
spin_lock(&mem_attr_smc_lock);
- int rc = get_mem_attributes(sp_ctx->xlat_ctx_handle,
+ int rc = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
base_va, &attributes);
spin_unlock(&mem_attr_smc_lock);
- /* Convert error codes of get_mem_attributes() into SPM ones. */
+ /* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
assert((rc == 0) || (rc == -EINVAL));
if (rc == 0) {
@@ -142,13 +142,13 @@ int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
spin_lock(&mem_attr_smc_lock);
- int ret = change_mem_attributes(sp_ctx->xlat_ctx_handle,
+ int ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
base_va, size,
smc_attr_to_mmap_attr(attributes));
spin_unlock(&mem_attr_smc_lock);
- /* Convert error codes of change_mem_attributes() into SPM ones. */
+ /* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
assert((ret == 0) || (ret == -EINVAL));
return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
diff --git a/services/std_svc/spm/spm_shim_private.h b/services/std_svc/spm/spm_shim_private.h
index 8408d1e04..e65ac44d7 100644
--- a/services/std_svc/spm/spm_shim_private.h
+++ b/services/std_svc/spm/spm_shim_private.h
@@ -7,7 +7,7 @@
#ifndef __SPM_SHIM_PRIVATE__
#define __SPM_SHIM_PRIVATE__
-#include <types.h>
+#include <stdint.h>
#include <utils_def.h>
/* Assembly source */
diff --git a/tools/doimage/Makefile b/tools/doimage/Makefile
new file mode 100644
index 000000000..bc74369ff
--- /dev/null
+++ b/tools/doimage/Makefile
@@ -0,0 +1,48 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+
+PROJECT = doimage
+OBJECTS = doimage.o
+
+CFLAGS = -Wall -Werror
+ifeq (${DEBUG},1)
+ CFLAGS += -g -O0 -DDEBUG
+else
+ CFLAGS += -O2
+endif
+
+ifeq (${MARVELL_SECURE_BOOT},1)
+DOIMAGE_CC_FLAGS := -DCONFIG_MVEBU_SECURE_BOOT
+DOIMAGE_LD_FLAGS := -lconfig -lmbedtls -lmbedcrypto -lmbedx509
+endif
+
+CFLAGS += ${DOIMAGE_CC_FLAGS}
+
+# Make soft links and include from local directory otherwise wrong headers
+# could get pulled in from firmware tree.
+INCLUDE_PATHS = -I.
+
+CC := gcc
+RM := rm -rf
+
+.PHONY: all clean
+
+all: ${PROJECT}
+
+${PROJECT}: ${OBJECTS} Makefile
+ @echo " LD $@"
+ ${Q}${CC} ${OBJECTS} ${DOIMAGE_LD_FLAGS} -o $@
+ @echo
+ @echo "Built $@ successfully"
+ @echo
+
+%.o: %.c %.h Makefile
+ @echo " CC $<"
+ ${Q}${CC} -c ${CFLAGS} ${INCLUDE_PATHS} $< -o $@
+
+clean:
+ ${Q}${RM} ${PROJECT}
+ ${Q}${RM} ${OBJECTS}
diff --git a/tools/doimage/doimage.c b/tools/doimage/doimage.c
new file mode 100644
index 000000000..56dabbad4
--- /dev/null
+++ b/tools/doimage/doimage.c
@@ -0,0 +1,1755 @@
+/*
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+#include <libconfig.h> /* for parsing config file */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+/* mbedTLS stuff */
+#if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ENTROPY_C) && \
+ defined(MBEDTLS_SHA256_C) && \
+ defined(MBEDTLS_PK_PARSE_C) && defined(MBEDTLS_FS_IO) && \
+ defined(MBEDTLS_CTR_DRBG_C)
+#include <mbedtls/error.h>
+#include <mbedtls/entropy.h>
+#include <mbedtls/ctr_drbg.h>
+#include <mbedtls/md.h>
+#include <mbedtls/pk.h>
+#include <mbedtls/sha256.h>
+#include <mbedtls/x509.h>
+#else
+#error "Bad mbedTLS configuration!"
+#endif
+#endif /* CONFIG_MVEBU_SECURE_BOOT */
+
+#define MAX_FILENAME 256
+#define CSK_ARR_SZ 16
+#define CSK_ARR_EMPTY_FILE "*"
+#define AES_KEY_BIT_LEN 256
+#define AES_KEY_BYTE_LEN (AES_KEY_BIT_LEN >> 3)
+#define AES_BLOCK_SZ 16
+#define RSA_SIGN_BYTE_LEN 256
+#define MAX_RSA_DER_BYTE_LEN 524
+/* Number of address pairs in control array */
+#define CP_CTRL_EL_ARRAY_SZ 32
+
+#define VERSION_STRING "Marvell(C) doimage utility version 3.2"
+
+/* A8K definitions */
+
+/* Extension header types */
+#define EXT_TYPE_SECURITY 0x1
+#define EXT_TYPE_BINARY 0x2
+
+#define MAIN_HDR_MAGIC 0xB105B002
+
+/* PROLOG alignment considerations:
+ * 128B: To allow supporting XMODEM protocol.
+ * 8KB: To align the boot image to the largest NAND page size, and simplify
+ * the read operations from NAND.
+ * We choose the largest page size, in order to use a single image for all
+ * NAND page sizes.
+ */
+#define PROLOG_ALIGNMENT (8 << 10)
+
+/* UART argument bitfield */
+#define UART_MODE_UNMODIFIED 0x0
+#define UART_MODE_DISABLE 0x1
+#define UART_MODE_UPDATE 0x2
+
+typedef struct _main_header {
+ uint32_t magic; /* 0-3 */
+ uint32_t prolog_size; /* 4-7 */
+ uint32_t prolog_checksum; /* 8-11 */
+ uint32_t boot_image_size; /* 12-15 */
+ uint32_t boot_image_checksum; /* 16-19 */
+ uint32_t rsrvd0; /* 20-23 */
+ uint32_t load_addr; /* 24-27 */
+ uint32_t exec_addr; /* 28-31 */
+ uint8_t uart_cfg; /* 32 */
+ uint8_t baudrate; /* 33 */
+ uint8_t ext_count; /* 34 */
+ uint8_t aux_flags; /* 35 */
+ uint32_t io_arg_0; /* 36-39 */
+ uint32_t io_arg_1; /* 40-43 */
+ uint32_t io_arg_2; /* 43-47 */
+ uint32_t io_arg_3; /* 48-51 */
+ uint32_t rsrvd1; /* 52-55 */
+ uint32_t rsrvd2; /* 56-59 */
+ uint32_t rsrvd3; /* 60-63 */
+} header_t;
+
+typedef struct _ext_header {
+ uint8_t type;
+ uint8_t offset;
+ uint16_t reserved;
+ uint32_t size;
+} ext_header_t;
+
+typedef struct _sec_entry {
+ uint8_t kak_key[MAX_RSA_DER_BYTE_LEN];
+ uint32_t jtag_delay;
+ uint32_t box_id;
+ uint32_t flash_id;
+ uint32_t jtag_en;
+ uint32_t encrypt_en;
+ uint32_t efuse_dis;
+ uint8_t header_sign[RSA_SIGN_BYTE_LEN];
+ uint8_t image_sign[RSA_SIGN_BYTE_LEN];
+ uint8_t csk_keys[CSK_ARR_SZ][MAX_RSA_DER_BYTE_LEN];
+ uint8_t csk_sign[RSA_SIGN_BYTE_LEN];
+ uint32_t cp_ctrl_arr[CP_CTRL_EL_ARRAY_SZ];
+ uint32_t cp_efuse_arr[CP_CTRL_EL_ARRAY_SZ];
+} sec_entry_t;
+
+/* A8K definitions end */
+
+/* UART argument bitfield */
+#define UART_MODE_UNMODIFIED 0x0
+#define UART_MODE_DISABLE 0x1
+#define UART_MODE_UPDATE 0x2
+
+#define uart_set_mode(arg, mode) (arg |= (mode & 0x3))
+
+typedef struct _sec_options {
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ char aes_key_file[MAX_FILENAME+1];
+ char kak_key_file[MAX_FILENAME+1];
+ char csk_key_file[CSK_ARR_SZ][MAX_FILENAME+1];
+ uint32_t box_id;
+ uint32_t flash_id;
+ uint32_t jtag_delay;
+ uint8_t csk_index;
+ uint8_t jtag_enable;
+ uint8_t efuse_disable;
+ uint32_t cp_ctrl_arr[CP_CTRL_EL_ARRAY_SZ];
+ uint32_t cp_efuse_arr[CP_CTRL_EL_ARRAY_SZ];
+ mbedtls_pk_context kak_pk;
+ mbedtls_pk_context csk_pk[CSK_ARR_SZ];
+ uint8_t aes_key[AES_KEY_BYTE_LEN];
+ uint8_t *encrypted_image;
+ uint32_t enc_image_sz;
+#endif
+} sec_options;
+
+typedef struct _options {
+ char bin_ext_file[MAX_FILENAME+1];
+ char sec_cfg_file[MAX_FILENAME+1];
+ sec_options *sec_opts;
+ uint32_t load_addr;
+ uint32_t exec_addr;
+ uint32_t baudrate;
+ uint8_t disable_print;
+ int8_t key_index; /* For header signatures verification only */
+ uint32_t nfc_io_args;
+} options_t;
+
+void usage_err(char *msg)
+{
+ fprintf(stderr, "Error: %s\n", msg);
+ fprintf(stderr, "run 'doimage -h' to get usage information\n");
+ exit(-1);
+}
+
+void usage(void)
+{
+ printf("\n\n%s\n\n", VERSION_STRING);
+ printf("Usage: doimage [options] <input_file> [output_file]\n");
+ printf("create bootrom image from u-boot and boot extensions\n\n");
+
+ printf("Arguments\n");
+ printf(" input_file name of boot image file.\n");
+ printf(" if -p is used, name of the bootrom image file");
+ printf(" to parse.\n");
+ printf(" output_file name of output bootrom image file\n");
+
+ printf("\nOptions\n");
+ printf(" -s target SOC name. supports a8020,a7020\n");
+ printf(" different SOCs may have different boot image\n");
+ printf(" format so it's mandatory to know the target SOC\n");
+ printf(" -i boot I/F name. supports nand, spi, nor\n");
+ printf(" This affects certain parameters coded in the\n");
+ printf(" image header\n");
+ printf(" -l boot image load address. default is 0x0\n");
+ printf(" -e boot image entry address. default is 0x0\n");
+ printf(" -b binary extension image file.\n");
+ printf(" This image is executed before the boot image.\n");
+ printf(" This is typically used to initialize the memory ");
+ printf(" controller.\n");
+ printf(" Currently supports only a single file.\n");
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ printf(" -c Make trusted boot image using parameters\n");
+ printf(" from the configuration file.\n");
+#endif
+ printf(" -p Parse and display a pre-built boot image\n");
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ printf(" -k Key index for RSA signatures verification\n");
+ printf(" when parsing the boot image\n");
+#endif
+ printf(" -m Disable prints of bootrom and binary extension\n");
+ printf(" -u UART baudrate used for bootrom prints.\n");
+ printf(" Must be multiple of 1200\n");
+ printf(" -h Show this help message\n");
+ printf(" IO-ROM NFC-NAND boot parameters:\n");
+ printf(" -n NAND device block size in KB [Default is 64KB].\n");
+ printf(" -t NAND cell technology (SLC [Default] or MLC)\n");
+
+ exit(-1);
+}
+
+/* globals */
+options_t opts = {
+ .bin_ext_file = "NA",
+ .sec_cfg_file = "NA",
+ .sec_opts = 0,
+ .load_addr = 0x0,
+ .exec_addr = 0x0,
+ .disable_print = 0,
+ .baudrate = 0,
+ .key_index = -1,
+};
+
+int get_file_size(char *filename)
+{
+ struct stat st;
+
+ if (stat(filename, &st) == 0)
+ return st.st_size;
+
+ return -1;
+}
+
+uint32_t checksum32(uint32_t *start, int len)
+{
+ uint32_t sum = 0;
+ uint32_t *startp = start;
+
+ do {
+ sum += *startp;
+ startp++;
+ len -= 4;
+ } while (len > 0);
+
+ return sum;
+}
+
+/*******************************************************************************
+ * create_rsa_signature (memory buffer content)
+ * Create RSASSA-PSS/SHA-256 signature for memory buffer
+ * using RSA Private Key
+ * INPUT:
+ * pk_ctx Private Key context
+ * input memory buffer
+ * ilen buffer length
+ * pers personalization string for seeding the RNG.
+ * For instance a private key file name.
+ * OUTPUT:
+ * signature RSA-2048 signature
+ * RETURN:
+ * 0 on success
+ */
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+int create_rsa_signature(mbedtls_pk_context *pk_ctx,
+ const unsigned char *input,
+ size_t ilen,
+ const char *pers,
+ uint8_t *signature)
+{
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ unsigned char hash[32];
+ unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
+ int rval;
+
+ /* Not sure this is required,
+ * but it's safer to start with empty buffers
+ */
+ memset(hash, 0, sizeof(hash));
+ memset(buf, 0, sizeof(buf));
+
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_entropy_init(&entropy);
+
+ /* Seed the random number generator */
+ rval = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *)pers, strlen(pers));
+ if (rval != 0) {
+ fprintf(stderr, " Failed in ctr_drbg_init call (%d)!\n", rval);
+ goto sign_exit;
+ }
+
+ /* The PK context should be already initialized.
+ * Set the padding type for this PK context
+ */
+ mbedtls_rsa_set_padding(mbedtls_pk_rsa(*pk_ctx),
+ MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256);
+
+ /* First compute the SHA256 hash for the input blob */
+ mbedtls_sha256(input, ilen, hash, 0);
+
+ /* Then calculate the hash signature */
+ rval = mbedtls_rsa_rsassa_pss_sign(mbedtls_pk_rsa(*pk_ctx),
+ mbedtls_ctr_drbg_random,
+ &ctr_drbg,
+ MBEDTLS_RSA_PRIVATE,
+ MBEDTLS_MD_SHA256, 0, hash, buf);
+ if (rval != 0) {
+ fprintf(stderr,
+ "Failed to create RSA signature for %s. Error %d\n",
+ pers, rval);
+ goto sign_exit;
+ }
+ memcpy(signature, buf, 256);
+
+sign_exit:
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+
+ return rval;
+} /* end of create_rsa_signature */
+
+/*******************************************************************************
+ * verify_rsa_signature (memory buffer content)
+ * Verify RSASSA-PSS/SHA-256 signature for memory buffer
+ * using RSA Public Key
+ * INPUT:
+ * pub_key Public Key buffer
+ * ilen Public Key buffer length
+ * input memory buffer
+ * ilen buffer length
+ * pers personalization string for seeding the RNG.
+ * signature RSA-2048 signature
+ * OUTPUT:
+ * none
+ * RETURN:
+ * 0 on success
+ */
+int verify_rsa_signature(const unsigned char *pub_key,
+ size_t klen,
+ const unsigned char *input,
+ size_t ilen,
+ const char *pers,
+ uint8_t *signature)
+{
+ mbedtls_entropy_context entropy;
+ mbedtls_ctr_drbg_context ctr_drbg;
+ mbedtls_pk_context pk_ctx;
+ unsigned char hash[32];
+ int rval;
+
+ /* Not sure this is required,
+ * but it's safer to start with empty buffer
+ */
+ memset(hash, 0, sizeof(hash));
+
+ mbedtls_pk_init(&pk_ctx);
+ mbedtls_ctr_drbg_init(&ctr_drbg);
+ mbedtls_entropy_init(&entropy);
+
+ /* Seed the random number generator */
+ rval = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
+ (const unsigned char *)pers, strlen(pers));
+ if (rval != 0) {
+ fprintf(stderr, " Failed in ctr_drbg_init call (%d)!\n", rval);
+ goto verify_exit;
+ }
+
+ /* Check ability to read the public key */
+ rval = mbedtls_pk_parse_public_key(&pk_ctx, pub_key,
+ MAX_RSA_DER_BYTE_LEN);
+ if (rval != 0) {
+ fprintf(stderr, " Failed in pk_parse_public_key (%#x)!\n",
+ rval);
+ goto verify_exit;
+ }
+
+ /* Set the padding type for the new PK context */
+ mbedtls_rsa_set_padding(mbedtls_pk_rsa(pk_ctx),
+ MBEDTLS_RSA_PKCS_V21,
+ MBEDTLS_MD_SHA256);
+
+ /* Compute the SHA256 hash for the input buffer */
+ mbedtls_sha256(input, ilen, hash, 0);
+
+ rval = mbedtls_rsa_rsassa_pss_verify(mbedtls_pk_rsa(pk_ctx),
+ mbedtls_ctr_drbg_random,
+ &ctr_drbg,
+ MBEDTLS_RSA_PUBLIC,
+ MBEDTLS_MD_SHA256, 0,
+ hash, signature);
+ if (rval != 0)
+ fprintf(stderr, "Failed to verify signature (%d)!\n", rval);
+
+verify_exit:
+
+ mbedtls_pk_free(&pk_ctx);
+ mbedtls_ctr_drbg_free(&ctr_drbg);
+ mbedtls_entropy_free(&entropy);
+ return rval;
+} /* end of verify_rsa_signature */
+
+/*******************************************************************************
+ * image_encrypt
+ * Encrypt image buffer using AES-256-CBC scheme.
+ * The resulting image is saved into opts.sec_opts->encrypted_image
+ * and the adjusted image size into opts.sec_opts->enc_image_sz
+ * First AES_BLOCK_SZ bytes of the output image contain IV
+ * INPUT:
+ * buf Source buffer to encrypt
+ * blen Source buffer length
+ * OUTPUT:
+ * none
+ * RETURN:
+ * 0 on success
+ */
+int image_encrypt(uint8_t *buf, uint32_t blen)
+{
+ struct timeval tv;
+ char *ptmp = (char *)&tv;
+ unsigned char digest[32];
+ unsigned char IV[AES_BLOCK_SZ];
+ int i, k;
+ mbedtls_aes_context aes_ctx;
+ int rval = -1;
+ uint8_t *test_img = 0;
+
+ if (AES_BLOCK_SZ > 32) {
+ fprintf(stderr, "Unsupported AES block size %d\n",
+ AES_BLOCK_SZ);
+ return rval;
+ }
+
+ mbedtls_aes_init(&aes_ctx);
+ memset(IV, 0, AES_BLOCK_SZ);
+ memset(digest, 0, 32);
+
+ /* Generate initialization vector and init the AES engine
+ * Use file name XOR current time and finally SHA-256
+ * [0...AES_BLOCK_SZ-1]
+ */
+ k = strlen(opts.sec_opts->aes_key_file);
+ if (k > AES_BLOCK_SZ)
+ k = AES_BLOCK_SZ;
+ memcpy(IV, opts.sec_opts->aes_key_file, k);
+ gettimeofday(&tv, 0);
+
+ for (i = 0, k = 0; i < AES_BLOCK_SZ; i++,
+ k = (k+1) % sizeof(struct timeval))
+ IV[i] ^= ptmp[k];
+
+ /* compute SHA-256 digest of the results
+ * and use it as the init vector (IV)
+ */
+ mbedtls_sha256(IV, AES_BLOCK_SZ, digest, 0);
+ memcpy(IV, digest, AES_BLOCK_SZ);
+ mbedtls_aes_setkey_enc(&aes_ctx, opts.sec_opts->aes_key,
+ AES_KEY_BIT_LEN);
+
+ /* The output image has to include extra space for IV
+ * and to be aligned to the AES block size.
+ * The input image buffer has to be already aligned to AES_BLOCK_SZ
+ * and padded with zeroes
+ */
+ opts.sec_opts->enc_image_sz = (blen + 2 * AES_BLOCK_SZ - 1) &
+ ~(AES_BLOCK_SZ - 1);
+ opts.sec_opts->encrypted_image = calloc(opts.sec_opts->enc_image_sz, 1);
+ if (opts.sec_opts->encrypted_image == 0) {
+ fprintf(stderr, "Failed to allocate encrypted image!\n");
+ goto encrypt_exit;
+ }
+
+ /* Put IV into the output buffer next to the encrypted image
+ * Since the IV is modified by the encryption function,
+ * this should be done now
+ */
+ memcpy(opts.sec_opts->encrypted_image +
+ opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
+ IV, AES_BLOCK_SZ);
+ rval = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT,
+ opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
+ IV, buf, opts.sec_opts->encrypted_image);
+ if (rval != 0) {
+ fprintf(stderr, "Failed to encrypt the image! Error %d\n",
+ rval);
+ goto encrypt_exit;
+ }
+
+ mbedtls_aes_free(&aes_ctx);
+
+ /* Try to decrypt the image and compare it with the original data */
+ mbedtls_aes_init(&aes_ctx);
+ mbedtls_aes_setkey_dec(&aes_ctx, opts.sec_opts->aes_key,
+ AES_KEY_BIT_LEN);
+
+ test_img = calloc(opts.sec_opts->enc_image_sz - AES_BLOCK_SZ, 1);
+ if (test_img == 0) {
+ fprintf(stderr, "Failed to allocate test image!d\n");
+ rval = -1;
+ goto encrypt_exit;
+ }
+
+ memcpy(IV, opts.sec_opts->encrypted_image +
+ opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
+ AES_BLOCK_SZ);
+ rval = mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT,
+ opts.sec_opts->enc_image_sz - AES_BLOCK_SZ,
+ IV, opts.sec_opts->encrypted_image, test_img);
+ if (rval != 0) {
+ fprintf(stderr, "Failed to decrypt the image! Error %d\n",
+ rval);
+ goto encrypt_exit;
+ }
+
+ for (i = 0; i < blen; i++) {
+ if (buf[i] != test_img[i]) {
+ fprintf(stderr, "Failed to compare the image after");
+ fprintf(stderr, " decryption! Byte count is %d\n", i);
+ rval = -1;
+ goto encrypt_exit;
+ }
+ }
+
+encrypt_exit:
+
+ mbedtls_aes_free(&aes_ctx);
+ if (test_img)
+ free(test_img);
+
+ return rval;
+} /* end of image_encrypt */
+
+/*******************************************************************************
+ * verify_secure_header_signatures
+ * Verify CSK array, header and image signatures and print results
+ * INPUT:
+ * main_hdr Main header
+ * sec_ext Secure extension
+ * OUTPUT:
+ * none
+ * RETURN:
+ * 0 on success
+ */
+int verify_secure_header_signatures(header_t *main_hdr, sec_entry_t *sec_ext)
+{
+ uint8_t *image = (uint8_t *)main_hdr + main_hdr->prolog_size;
+ uint8_t signature[RSA_SIGN_BYTE_LEN];
+ int rval = -1;
+
+ /* Save headers signature and reset it in the secure header */
+ memcpy(signature, sec_ext->header_sign, RSA_SIGN_BYTE_LEN);
+ memset(sec_ext->header_sign, 0, RSA_SIGN_BYTE_LEN);
+
+ fprintf(stdout, "\nCheck RSA Signatures\n");
+ fprintf(stdout, "#########################\n");
+ fprintf(stdout, "CSK Block Signature: ");
+ if (verify_rsa_signature(sec_ext->kak_key,
+ MAX_RSA_DER_BYTE_LEN,
+ &sec_ext->csk_keys[0][0],
+ sizeof(sec_ext->csk_keys),
+ "CSK Block Signature: ",
+ sec_ext->csk_sign) != 0) {
+ fprintf(stdout, "ERROR\n");
+ goto ver_error;
+ }
+ fprintf(stdout, "OK\n");
+
+ if (opts.key_index != -1) {
+ fprintf(stdout, "Image Signature: ");
+ if (verify_rsa_signature(sec_ext->csk_keys[opts.key_index],
+ MAX_RSA_DER_BYTE_LEN,
+ image, main_hdr->boot_image_size,
+ "Image Signature: ",
+ sec_ext->image_sign) != 0) {
+ fprintf(stdout, "ERROR\n");
+ goto ver_error;
+ }
+ fprintf(stdout, "OK\n");
+
+ fprintf(stdout, "Header Signature: ");
+ if (verify_rsa_signature(sec_ext->csk_keys[opts.key_index],
+ MAX_RSA_DER_BYTE_LEN,
+ (uint8_t *)main_hdr,
+ main_hdr->prolog_size,
+ "Header Signature: ",
+ signature) != 0) {
+ fprintf(stdout, "ERROR\n");
+ goto ver_error;
+ }
+ fprintf(stdout, "OK\n");
+ } else {
+ fprintf(stdout, "SKIP Image and Header Signatures");
+ fprintf(stdout, " check (undefined key index)\n");
+ }
+
+ rval = 0;
+
+ver_error:
+ memcpy(sec_ext->header_sign, signature, RSA_SIGN_BYTE_LEN);
+ return rval;
+}
+
+/*******************************************************************************
+ * verify_and_copy_file_name_entry
+ * INPUT:
+ * element_name
+ * element
+ * OUTPUT:
+ * copy_to
+ * RETURN:
+ * 0 on success
+ */
+int verify_and_copy_file_name_entry(const char *element_name,
+ const char *element, char *copy_to)
+{
+ int element_length = strlen(element);
+
+ if (element_length >= MAX_FILENAME) {
+ fprintf(stderr, "The file name %s for %s is too long (%d). ",
+ element, element_name, element_length);
+ fprintf(stderr, "Maximum allowed %d characters!\n",
+ MAX_FILENAME);
+ return -1;
+ } else if (element_length == 0) {
+ fprintf(stderr, "The file name for %s is empty!\n",
+ element_name);
+ return -1;
+ }
+ memcpy(copy_to, element, element_length);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * parse_sec_config_file
+ * Read the secure boot configuration from a file
+ * into internal structures
+ * INPUT:
+ * filename File name
+ * OUTPUT:
+ * none
+ * RETURN:
+ * 0 on success
+ */
+int parse_sec_config_file(char *filename)
+{
+ config_t sec_cfg;
+ int array_sz, element, rval = -1;
+ const char *cfg_string;
+ int32_t cfg_int32;
+ const config_setting_t *csk_array, *control_array;
+ sec_options *sec_opt = 0;
+
+ config_init(&sec_cfg);
+
+ if (config_read_file(&sec_cfg, filename) != CONFIG_TRUE) {
+ fprintf(stderr, "Failed to read data from config file ");
+ fprintf(stderr, "%s\n\t%s at line %d\n",
+ filename, config_error_text(&sec_cfg),
+ config_error_line(&sec_cfg));
+ goto exit_parse;
+ }
+
+ sec_opt = (sec_options *)calloc(sizeof(sec_options), 1);
+ if (sec_opt == 0) {
+ fprintf(stderr,
+ "Cannot allocate memory for secure boot options!\n");
+ goto exit_parse;
+ }
+
+ /* KAK file name */
+ if (config_lookup_string(&sec_cfg, "kak_key_file",
+ &cfg_string) != CONFIG_TRUE) {
+ fprintf(stderr, "The \"kak_key_file\" undefined!\n");
+ goto exit_parse;
+ }
+ if (verify_and_copy_file_name_entry("kak_key_file",
+ cfg_string, sec_opt->kak_key_file))
+ goto exit_parse;
+
+
+ /* AES file name - can be empty/undefined */
+ if (config_lookup_string(&sec_cfg, "aes_key_file",
+ &cfg_string) == CONFIG_TRUE) {
+ if (verify_and_copy_file_name_entry("aes_key_file",
+ cfg_string,
+ sec_opt->aes_key_file))
+ goto exit_parse;
+ }
+
+ /* CSK file names array */
+ csk_array = config_lookup(&sec_cfg, "csk_key_file");
+ if (csk_array == NULL) {
+ fprintf(stderr, "The \"csk_key_file\" undefined!\n");
+ goto exit_parse;
+ }
+ array_sz = config_setting_length(csk_array);
+ if (array_sz > CSK_ARR_SZ) {
+ fprintf(stderr, "The \"csk_key_file\" array is too big! ");
+ fprintf(stderr, "Only first %d elements will be used\n",
+ CSK_ARR_SZ);
+ array_sz = CSK_ARR_SZ;
+ } else if (array_sz == 0) {
+ fprintf(stderr, "The \"csk_key_file\" array is empty!\n");
+ goto exit_parse;
+ }
+
+ for (element = 0; element < array_sz; element++) {
+ cfg_string = config_setting_get_string_elem(csk_array, element);
+ if (verify_and_copy_file_name_entry(
+ "csk_key_file", cfg_string,
+ sec_opt->csk_key_file[element])) {
+ fprintf(stderr, "Bad csk_key_file[%d] entry!\n",
+ element);
+ goto exit_parse;
+ }
+ }
+
+ /* JTAG options */
+ if (config_lookup_bool(&sec_cfg, "jtag.enable",
+ &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"jtag.enable\" element. ");
+ fprintf(stderr, "Using default - FALSE\n");
+ cfg_int32 = 0;
+ }
+ sec_opt->jtag_enable = cfg_int32;
+
+ if (config_lookup_int(&sec_cfg, "jtag.delay",
+ &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"jtag.delay\" element. ");
+ fprintf(stderr, "Using default - 0us\n");
+ cfg_int32 = 0;
+ }
+ sec_opt->jtag_delay = cfg_int32;
+
+ /* eFUSE option */
+ if (config_lookup_bool(&sec_cfg, "efuse_disable",
+ &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"efuse_disable\" element. ");
+ fprintf(stderr, "Using default - TRUE\n");
+ cfg_int32 = 1;
+ }
+ sec_opt->efuse_disable = cfg_int32;
+
+ /* Box ID option */
+ if (config_lookup_int(&sec_cfg, "box_id", &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"box_id\" element. ");
+ fprintf(stderr, "Using default - 0x0\n");
+ cfg_int32 = 0;
+ }
+ sec_opt->box_id = cfg_int32;
+
+ /* Flash ID option */
+ if (config_lookup_int(&sec_cfg, "flash_id",
+ &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"flash_id\" element. ");
+ fprintf(stderr, "Using default - 0x0\n");
+ cfg_int32 = 0;
+ }
+ sec_opt->flash_id = cfg_int32;
+
+ /* CSK index option */
+ if (config_lookup_int(&sec_cfg, "csk_key_index",
+ &cfg_int32) != CONFIG_TRUE) {
+ fprintf(stderr, "Error obtaining \"flash_id\" element. "
+ fprintf(stderr, "Using default - 0x0\n");
+ cfg_int32 = 0;
+ }
+ sec_opt->csk_index = cfg_int32;
+
+ /* Secure boot control array */
+ control_array = config_lookup(&sec_cfg, "control");
+ if (control_array != NULL) {
+ array_sz = config_setting_length(control_array);
+ if (array_sz == 0)
+ fprintf(stderr, "The \"control\" array is empty!\n");
+ } else {
+ fprintf(stderr, "The \"control\" is undefined!\n");
+ array_sz = 0;
+ }
+
+ for (element = 0; element < CP_CTRL_EL_ARRAY_SZ; element++) {
+ sec_opt->cp_ctrl_arr[element] =
+ config_setting_get_int_elem(control_array, element * 2);
+ sec_opt->cp_efuse_arr[element] =
+ config_setting_get_int_elem(control_array,
+ element * 2 + 1);
+ }
+
+ opts.sec_opts = sec_opt;
+ rval = 0;
+
+exit_parse:
+ config_destroy(&sec_cfg);
+ if (sec_opt && (rval != 0))
+ free(sec_opt);
+ return rval;
+} /* end of parse_sec_config_file */
+
+int format_sec_ext(char *filename, FILE *out_fd)
+{
+ ext_header_t header;
+ sec_entry_t sec_ext;
+ int index;
+ int written;
+
+#define DER_BUF_SZ 1600
+
+ /* First, parse the configuration file */
+ if (parse_sec_config_file(filename)) {
+ fprintf(stderr,
+ "failed parsing configuration file %s\n", filename);
+ return 1;
+ }
+
+ /* Everything except signatures can be created at this stage */
+ header.type = EXT_TYPE_SECURITY;
+ header.offset = 0;
+ header.size = sizeof(sec_entry_t);
+ header.reserved = 0;
+
+ /* Bring up RSA context and read private keys from their files */
+ for (index = 0; index < (CSK_ARR_SZ + 1); index++) {
+ /* for every private key file */
+ mbedtls_pk_context *pk_ctx = (index == CSK_ARR_SZ) ?
+ &opts.sec_opts->kak_pk :
+ &opts.sec_opts->csk_pk[index];
+ char *fname = (index == CSK_ARR_SZ) ?
+ opts.sec_opts->kak_key_file :
+ opts.sec_opts->csk_key_file[index];
+ uint8_t *out_der_key = (index == CSK_ARR_SZ) ?
+ sec_ext.kak_key :
+ sec_ext.csk_keys[index];
+ size_t output_len;
+ unsigned char output_buf[DER_BUF_SZ];
+ unsigned char *der_buf_start;
+
+ /* Handle invalid/reserved file names */
+ if (strncmp(CSK_ARR_EMPTY_FILE, fname,
+ strlen(CSK_ARR_EMPTY_FILE)) == 0) {
+ if (opts.sec_opts->csk_index == index) {
+ fprintf(stderr,
+ "CSK file with index %d cannot be %s\n",
+ index, CSK_ARR_EMPTY_FILE);
+ return 1;
+ } else if (index == CSK_ARR_SZ) {
+ fprintf(stderr, "KAK file name cannot be %s\n",
+ CSK_ARR_EMPTY_FILE);
+ return 1;
+ }
+ /* this key will be empty in CSK array */
+ continue;
+ }
+
+ mbedtls_pk_init(pk_ctx);
+ /* Read the private RSA key into the context
+ * and verify it (no password)
+ */
+ if (mbedtls_pk_parse_keyfile(pk_ctx, fname, "") != 0) {
+ fprintf(stderr,
+ "Cannot read RSA private key file %s\n", fname);
+ return 1;
+ }
+
+ /* Create a public key out of private one
+ * and store it in DER format
+ */
+ output_len = mbedtls_pk_write_pubkey_der(pk_ctx,
+ output_buf,
+ DER_BUF_SZ);
+ if (output_len < 0) {
+ fprintf(stderr,
+ "Failed to create DER coded PUB key (%s)\n",
+ fname);
+ return 1;
+ }
+ /* Data in the output buffer is aligned to the buffer end */
+ der_buf_start = output_buf + sizeof(output_buf) - output_len;
+ /* In the header DER data is aligned
+ * to the start of appropriate field
+ */
+ memcpy(out_der_key, der_buf_start, output_len);
+
+ } /* for every private key file */
+
+ /* The CSK block signature can be created here */
+ if (create_rsa_signature(&opts.sec_opts->kak_pk,
+ &sec_ext.csk_keys[0][0],
+ sizeof(sec_ext.csk_keys),
+ opts.sec_opts->csk_key_file[
+ opts.sec_opts->csk_index],
+ sec_ext.csk_sign) != 0) {
+ fprintf(stderr, "Failed to sign CSK keys block!\n");
+ return 1;
+ }
+ /* Check that everything is correct */
+ if (verify_rsa_signature(sec_ext.kak_key, MAX_RSA_DER_BYTE_LEN,
+ &sec_ext.csk_keys[0][0],
+ sizeof(sec_ext.csk_keys),
+ opts.sec_opts->kak_key_file,
+ sec_ext.csk_sign) != 0) {
+ fprintf(stderr, "Failed to verify CSK keys block signature!\n");
+ return 1;
+ }
+
+ /* AES encryption stuff */
+ if (strlen(opts.sec_opts->aes_key_file) != 0) {
+ FILE *in_fd;
+
+ in_fd = fopen(opts.sec_opts->aes_key_file, "rb");
+ if (in_fd == NULL) {
+ fprintf(stderr, "Failed to open AES key file %s\n",
+ opts.sec_opts->aes_key_file);
+ return 1;
+ }
+
+ /* Read the AES key in ASCII format byte by byte */
+ for (index = 0; index < AES_KEY_BYTE_LEN; index++) {
+ if (fscanf(in_fd, "%02hhx",
+ opts.sec_opts->aes_key + index) != 1) {
+ fprintf(stderr,
+ "Failed to read AES key byte %d ",
+ index);
+ fprintf(stderr,
+ "from file %s\n",
+ opts.sec_opts->aes_key_file);
+ fclose(in_fd);
+ return 1;
+ }
+ }
+ fclose(in_fd);
+ sec_ext.encrypt_en = 1;
+ } else {
+ sec_ext.encrypt_en = 0;
+ }
+
+ /* Fill the rest of the trusted boot extension fields */
+ sec_ext.box_id = opts.sec_opts->box_id;
+ sec_ext.flash_id = opts.sec_opts->flash_id;
+ sec_ext.efuse_dis = opts.sec_opts->efuse_disable;
+ sec_ext.jtag_delay = opts.sec_opts->jtag_delay;
+ sec_ext.jtag_en = opts.sec_opts->jtag_enable;
+
+ memcpy(sec_ext.cp_ctrl_arr,
+ opts.sec_opts->cp_ctrl_arr,
+ sizeof(uint32_t) * CP_CTRL_EL_ARRAY_SZ);
+ memcpy(sec_ext.cp_efuse_arr,
+ opts.sec_opts->cp_efuse_arr,
+ sizeof(uint32_t) * CP_CTRL_EL_ARRAY_SZ);
+
+ /* Write the resulting extension to file
+ * (image and header signature fields are still empty)
+ */
+
+ /* Write extension header */
+ written = fwrite(&header, sizeof(ext_header_t), 1, out_fd);
+ if (written != 1) {
+ fprintf(stderr,
+ "Failed to write SEC extension header to the file\n");
+ return 1;
+ }
+ /* Write extension body */
+ written = fwrite(&sec_ext, sizeof(sec_entry_t), 1, out_fd);
+ if (written != 1) {
+ fprintf(stderr,
+ "Failed to write SEC extension body to the file\n");
+ return 1;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * finalize_secure_ext
+ * Make final changes to secure extension - calculate image and header
+ * signatures and encrypt the image if needed.
+ * The main header checksum and image size fields updated accordingly
+ * INPUT:
+ * header Main header
+ * prolog_buf the entire prolog buffer
+ * prolog_size prolog buffer length
+ * image_buf buffer containing the input binary image
+ * image_size image buffer size.
+ * OUTPUT:
+ * none
+ * RETURN:
+ * 0 on success
+ */
+int finalize_secure_ext(header_t *header,
+ uint8_t *prolog_buf, uint32_t prolog_size,
+ uint8_t *image_buf, int image_size)
+{
+ int cur_ext, offset;
+ uint8_t *final_image = image_buf;
+ uint32_t final_image_sz = image_size;
+ uint8_t hdr_sign[RSA_SIGN_BYTE_LEN];
+ sec_entry_t *sec_ext = 0;
+
+ /* Find the Trusted Boot Header between available extensions */
+ for (cur_ext = 0, offset = sizeof(header_t);
+ cur_ext < header->ext_count; cur_ext++) {
+ ext_header_t *ext_hdr = (ext_header_t *)(prolog_buf + offset);
+
+ if (ext_hdr->type == EXT_TYPE_SECURITY) {
+ sec_ext = (sec_entry_t *)(prolog_buf + offset +
+ sizeof(ext_header_t) + ext_hdr->offset);
+ break;
+ }
+
+ offset += sizeof(ext_header_t);
+ /* If offset is Zero, the extension follows its header */
+ if (ext_hdr->offset == 0)
+ offset += ext_hdr->size;
+ }
+
+ if (sec_ext == 0) {
+ fprintf(stderr, "Error: No Trusted Boot extension found!\n");
+ return -1;
+ }
+
+ if (sec_ext->encrypt_en) {
+ /* Encrypt the image if needed */
+ fprintf(stdout, "Encrypting the image...\n");
+
+ if (image_encrypt(image_buf, image_size) != 0) {
+ fprintf(stderr, "Failed to encrypt the image!\n");
+ return -1;
+ }
+
+ /* Image size and checksum should be updated after encryption.
+ * This way the image could be verified by the BootROM
+ * before decryption.
+ */
+ final_image = opts.sec_opts->encrypted_image;
+ final_image_sz = opts.sec_opts->enc_image_sz;
+
+ header->boot_image_size = final_image_sz;
+ header->boot_image_checksum =
+ checksum32((uint32_t *)final_image, final_image_sz);
+ } /* AES encryption */
+
+ /* Create the image signature first, since it will be later
+ * signed along with the header signature
+ */
+ if (create_rsa_signature(&opts.sec_opts->csk_pk[
+ opts.sec_opts->csk_index],
+ final_image, final_image_sz,
+ opts.sec_opts->csk_key_file[
+ opts.sec_opts->csk_index],
+ sec_ext->image_sign) != 0) {
+ fprintf(stderr, "Failed to sign image!\n");
+ return -1;
+ }
+ /* Check that the image signature is correct */
+ if (verify_rsa_signature(sec_ext->csk_keys[opts.sec_opts->csk_index],
+ MAX_RSA_DER_BYTE_LEN,
+ final_image, final_image_sz,
+ opts.sec_opts->csk_key_file[
+ opts.sec_opts->csk_index],
+ sec_ext->image_sign) != 0) {
+ fprintf(stderr, "Failed to verify image signature!\n");
+ return -1;
+ }
+
+ /* Sign the headers and all the extensions block
+ * when the header signature field is empty
+ */
+ if (create_rsa_signature(&opts.sec_opts->csk_pk[
+ opts.sec_opts->csk_index],
+ prolog_buf, prolog_size,
+ opts.sec_opts->csk_key_file[
+ opts.sec_opts->csk_index],
+ hdr_sign) != 0) {
+ fprintf(stderr, "Failed to sign header!\n");
+ return -1;
+ }
+ /* Check that the header signature is correct */
+ if (verify_rsa_signature(sec_ext->csk_keys[opts.sec_opts->csk_index],
+ MAX_RSA_DER_BYTE_LEN,
+ prolog_buf, prolog_size,
+ opts.sec_opts->csk_key_file[
+ opts.sec_opts->csk_index],
+ hdr_sign) != 0) {
+ fprintf(stderr, "Failed to verify header signature!\n");
+ return -1;
+ }
+
+ /* Finally, copy the header signature into the trusted boot extension */
+ memcpy(sec_ext->header_sign, hdr_sign, RSA_SIGN_BYTE_LEN);
+
+ return 0;
+}
+
+#endif /* CONFIG_MVEBU_SECURE_BOOT */
+
+
+#define FMT_HEX 0
+#define FMT_DEC 1
+#define FMT_BIN 2
+#define FMT_NONE 3
+
+void do_print_field(unsigned int value, char *name,
+ int start, int size, int format)
+{
+ fprintf(stdout, "[0x%05x : 0x%05x] %-26s",
+ start, start + size - 1, name);
+
+ switch (format) {
+ case FMT_HEX:
+ printf("0x%x\n", value);
+ break;
+ case FMT_DEC:
+ printf("%d\n", value);
+ break;
+ default:
+ printf("\n");
+ break;
+ }
+}
+
+#define print_field(st, type, field, hex, base) \
+ do_print_field((int)st->field, #field, \
+ base + offsetof(type, field), sizeof(st->field), hex)
+
+int print_header(uint8_t *buf, int base)
+{
+ header_t *main_hdr;
+
+ main_hdr = (header_t *)buf;
+
+ fprintf(stdout, "########### Header ##############\n");
+ print_field(main_hdr, header_t, magic, FMT_HEX, base);
+ print_field(main_hdr, header_t, prolog_size, FMT_DEC, base);
+ print_field(main_hdr, header_t, prolog_checksum, FMT_HEX, base);
+ print_field(main_hdr, header_t, boot_image_size, FMT_DEC, base);
+ print_field(main_hdr, header_t, boot_image_checksum, FMT_HEX, base);
+ print_field(main_hdr, header_t, rsrvd0, FMT_HEX, base);
+ print_field(main_hdr, header_t, load_addr, FMT_HEX, base);
+ print_field(main_hdr, header_t, exec_addr, FMT_HEX, base);
+ print_field(main_hdr, header_t, uart_cfg, FMT_HEX, base);
+ print_field(main_hdr, header_t, baudrate, FMT_HEX, base);
+ print_field(main_hdr, header_t, ext_count, FMT_DEC, base);
+ print_field(main_hdr, header_t, aux_flags, FMT_HEX, base);
+ print_field(main_hdr, header_t, io_arg_0, FMT_HEX, base);
+ print_field(main_hdr, header_t, io_arg_1, FMT_HEX, base);
+ print_field(main_hdr, header_t, io_arg_2, FMT_HEX, base);
+ print_field(main_hdr, header_t, io_arg_3, FMT_HEX, base);
+ print_field(main_hdr, header_t, rsrvd1, FMT_HEX, base);
+ print_field(main_hdr, header_t, rsrvd2, FMT_HEX, base);
+ print_field(main_hdr, header_t, rsrvd3, FMT_HEX, base);
+
+ return sizeof(header_t);
+}
+
+int print_ext_hdr(ext_header_t *ext_hdr, int base)
+{
+ print_field(ext_hdr, ext_header_t, type, FMT_HEX, base);
+ print_field(ext_hdr, ext_header_t, offset, FMT_HEX, base);
+ print_field(ext_hdr, ext_header_t, reserved, FMT_HEX, base);
+ print_field(ext_hdr, ext_header_t, size, FMT_DEC, base);
+
+ return base + sizeof(ext_header_t);
+}
+
+void print_sec_ext(ext_header_t *ext_hdr, int base)
+{
+ sec_entry_t *sec_entry;
+ uint32_t new_base;
+
+ fprintf(stdout, "\n########### Secure extension ###########\n");
+
+ new_base = print_ext_hdr(ext_hdr, base);
+
+ sec_entry = (sec_entry_t *)(ext_hdr + 1);
+
+ do_print_field(0, "KAK key", new_base, MAX_RSA_DER_BYTE_LEN, FMT_NONE);
+ new_base += MAX_RSA_DER_BYTE_LEN;
+ print_field(sec_entry, sec_entry_t, jtag_delay, FMT_DEC, base);
+ print_field(sec_entry, sec_entry_t, box_id, FMT_HEX, base);
+ print_field(sec_entry, sec_entry_t, flash_id, FMT_HEX, base);
+ print_field(sec_entry, sec_entry_t, encrypt_en, FMT_DEC, base);
+ print_field(sec_entry, sec_entry_t, efuse_dis, FMT_DEC, base);
+ new_base += 6 * sizeof(uint32_t);
+ do_print_field(0, "header signature",
+ new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
+ new_base += RSA_SIGN_BYTE_LEN;
+ do_print_field(0, "image signature",
+ new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
+ new_base += RSA_SIGN_BYTE_LEN;
+ do_print_field(0, "CSK keys", new_base,
+ CSK_ARR_SZ * MAX_RSA_DER_BYTE_LEN, FMT_NONE);
+ new_base += CSK_ARR_SZ * MAX_RSA_DER_BYTE_LEN;
+ do_print_field(0, "CSK block signature",
+ new_base, RSA_SIGN_BYTE_LEN, FMT_NONE);
+ new_base += RSA_SIGN_BYTE_LEN;
+ do_print_field(0, "control", new_base,
+ CP_CTRL_EL_ARRAY_SZ * 2, FMT_NONE);
+
+}
+
+void print_bin_ext(ext_header_t *ext_hdr, int base)
+{
+ fprintf(stdout, "\n########### Binary extension ###########\n");
+ base = print_ext_hdr(ext_hdr, base);
+ do_print_field(0, "binary image", base, ext_hdr->size, FMT_NONE);
+}
+
+int print_extension(void *buf, int base, int count, int ext_size)
+{
+ ext_header_t *ext_hdr = buf;
+ int pad = ext_size;
+ int curr_size;
+
+ while (count--) {
+ if (ext_hdr->type == EXT_TYPE_BINARY)
+ print_bin_ext(ext_hdr, base);
+ else if (ext_hdr->type == EXT_TYPE_SECURITY)
+ print_sec_ext(ext_hdr, base);
+
+ curr_size = sizeof(ext_header_t) + ext_hdr->size;
+ base += curr_size;
+ pad -= curr_size;
+ ext_hdr = (ext_header_t *)((uintptr_t)ext_hdr + curr_size);
+ }
+
+ if (pad)
+ do_print_field(0, "padding", base, pad, FMT_NONE);
+
+ return ext_size;
+}
+
+int parse_image(uint8_t *buf, int size)
+{
+ int base = 0;
+ int ret = 1;
+ header_t *main_hdr;
+ uint32_t checksum, prolog_checksum;
+
+
+ fprintf(stdout,
+ "################### Prolog Start ######################\n\n");
+ main_hdr = (header_t *)buf;
+ base += print_header(buf, base);
+
+ if (main_hdr->ext_count)
+ base += print_extension(buf + base, base,
+ main_hdr->ext_count,
+ main_hdr->prolog_size -
+ sizeof(header_t));
+
+ if (base < main_hdr->prolog_size) {
+ fprintf(stdout, "\n########### Padding ##############\n");
+ do_print_field(0, "prolog padding",
+ base, main_hdr->prolog_size - base, FMT_HEX);
+ base = main_hdr->prolog_size;
+ }
+ fprintf(stdout,
+ "\n################### Prolog End ######################\n");
+
+ fprintf(stdout,
+ "\n################### Boot image ######################\n");
+
+ do_print_field(0, "boot image", base, size - base - 4, FMT_NONE);
+
+ fprintf(stdout,
+ "################### Image end ########################\n");
+
+ /* Check sanity for certain values */
+ printf("\nChecking values:\n");
+
+ if (main_hdr->magic == MAIN_HDR_MAGIC) {
+ fprintf(stdout, "Headers magic: OK!\n");
+ } else {
+ fprintf(stderr,
+ "\n****** ERROR: HEADER MAGIC 0x%08x != 0x%08x\n",
+ main_hdr->magic, MAIN_HDR_MAGIC);
+ goto error;
+ }
+
+ /* headers checksum */
+ /* clear the checksum field in header to calculate checksum */
+ prolog_checksum = main_hdr->prolog_checksum;
+ main_hdr->prolog_checksum = 0;
+ checksum = checksum32((uint32_t *)buf, main_hdr->prolog_size);
+
+ if (checksum == prolog_checksum) {
+ fprintf(stdout, "Headers checksum: OK!\n");
+ } else {
+ fprintf(stderr,
+ "\n***** ERROR: BAD HEADER CHECKSUM 0x%08x != 0x%08x\n",
+ checksum, prolog_checksum);
+ goto error;
+ }
+
+ /* boot image checksum */
+ checksum = checksum32((uint32_t *)(buf + main_hdr->prolog_size),
+ main_hdr->boot_image_size);
+ if (checksum == main_hdr->boot_image_checksum) {
+ fprintf(stdout, "Image checksum: OK!\n");
+ } else {
+ fprintf(stderr,
+ "\n****** ERROR: BAD IMAGE CHECKSUM 0x%08x != 0x%08x\n",
+ checksum, main_hdr->boot_image_checksum);
+ goto error;
+ }
+
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ /* RSA signatures */
+ if (main_hdr->ext_count) {
+ uint8_t ext_num = main_hdr->ext_count;
+ ext_header_t *ext_hdr = (ext_header_t *)(main_hdr + 1);
+ unsigned char hash[32];
+ int i;
+
+ while (ext_num--) {
+ if (ext_hdr->type == EXT_TYPE_SECURITY) {
+ sec_entry_t *sec_entry =
+ (sec_entry_t *)(ext_hdr + 1);
+
+ ret = verify_secure_header_signatures(
+ main_hdr, sec_entry);
+ if (ret != 0) {
+ fprintf(stderr,
+ "\n****** FAILED TO VERIFY ");
+ fprintf(stderr,
+ "RSA SIGNATURES ********\n");
+ goto error;
+ }
+
+ mbedtls_sha256(sec_entry->kak_key,
+ MAX_RSA_DER_BYTE_LEN, hash, 0);
+ fprintf(stdout,
+ ">>>>>>>>>> KAK KEY HASH >>>>>>>>>>\n");
+ fprintf(stdout, "SHA256: ");
+ for (i = 0; i < 32; i++)
+ fprintf(stdout, "%02X", hash[i]);
+
+ fprintf(stdout,
+ "\n<<<<<<<<< KAK KEY HASH <<<<<<<<<\n");
+
+ break;
+ }
+ ext_hdr =
+ (ext_header_t *)((uint8_t *)(ext_hdr + 1) +
+ ext_hdr->size);
+ }
+ }
+#endif
+
+ ret = 0;
+error:
+ return ret;
+}
+
+int format_bin_ext(char *filename, FILE *out_fd)
+{
+ ext_header_t header;
+ FILE *in_fd;
+ int size, written;
+ int aligned_size, pad_bytes;
+ char c;
+
+ in_fd = fopen(filename, "rb");
+ if (in_fd == NULL) {
+ fprintf(stderr, "failed to open bin extension file %s\n",
+ filename);
+ return 1;
+ }
+
+ size = get_file_size(filename);
+ if (size <= 0) {
+ fprintf(stderr, "bin extension file size is bad\n");
+ return 1;
+ }
+
+ /* Align extension size to 8 bytes */
+ aligned_size = (size + 7) & (~7);
+ pad_bytes = aligned_size - size;
+
+ header.type = EXT_TYPE_BINARY;
+ header.offset = 0;
+ header.size = aligned_size;
+ header.reserved = 0;
+
+ /* Write header */
+ written = fwrite(&header, sizeof(ext_header_t), 1, out_fd);
+ if (written != 1) {
+ fprintf(stderr, "failed writing header to extension file\n");
+ return 1;
+ }
+
+ /* Write image */
+ while (size--) {
+ c = getc(in_fd);
+ fputc(c, out_fd);
+ }
+
+ while (pad_bytes--)
+ fputc(0, out_fd);
+
+ fclose(in_fd);
+
+ return 0;
+}
+
+/* ****************************************
+ *
+ * Write all extensions (binary, secure
+ * extensions) to file
+ *
+ * ****************************************/
+
+int format_extensions(char *ext_filename)
+{
+ FILE *out_fd;
+ int ret = 0;
+
+ out_fd = fopen(ext_filename, "wb");
+ if (out_fd == NULL) {
+ fprintf(stderr, "failed to open extension output file %s",
+ ext_filename);
+ return 1;
+ }
+
+ if (strncmp(opts.bin_ext_file, "NA", MAX_FILENAME)) {
+ if (format_bin_ext(opts.bin_ext_file, out_fd)) {
+ ret = 1;
+ goto error;
+ }
+ }
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ if (strncmp(opts.sec_cfg_file, "NA", MAX_FILENAME)) {
+ if (format_sec_ext(opts.sec_cfg_file, out_fd)) {
+ ret = 1;
+ goto error;
+ }
+ }
+#endif
+
+error:
+ fflush(out_fd);
+ fclose(out_fd);
+ return ret;
+}
+
+void update_uart(header_t *header)
+{
+ header->uart_cfg = 0;
+ header->baudrate = 0;
+
+ if (opts.disable_print)
+ uart_set_mode(header->uart_cfg, UART_MODE_DISABLE);
+
+ if (opts.baudrate)
+ header->baudrate = (opts.baudrate / 1200);
+}
+
+/* ****************************************
+ *
+ * Write the image prolog, i.e.
+ * main header and extensions, to file
+ *
+ * ****************************************/
+
+int write_prolog(int ext_cnt, char *ext_filename,
+ uint8_t *image_buf, int image_size, FILE *out_fd)
+{
+ header_t *header;
+ int main_hdr_size = sizeof(header_t);
+ int prolog_size = main_hdr_size;
+ FILE *ext_fd;
+ char *buf;
+ int written, read;
+ int ret = 1;
+
+
+ if (ext_cnt)
+ prolog_size += get_file_size(ext_filename);
+
+ prolog_size = ((prolog_size + PROLOG_ALIGNMENT) &
+ (~(PROLOG_ALIGNMENT-1)));
+
+ /* Allocate a zeroed buffer to zero the padding bytes */
+ buf = calloc(prolog_size, 1);
+ if (buf == NULL) {
+ fprintf(stderr, "Error: failed allocating checksum buffer\n");
+ return 1;
+ }
+
+ header = (header_t *)buf;
+ header->magic = MAIN_HDR_MAGIC;
+ header->prolog_size = prolog_size;
+ header->load_addr = opts.load_addr;
+ header->exec_addr = opts.exec_addr;
+ header->io_arg_0 = opts.nfc_io_args;
+ header->ext_count = ext_cnt;
+ header->aux_flags = 0;
+ header->boot_image_size = (image_size + 3) & (~0x3);
+ header->boot_image_checksum = checksum32((uint32_t *)image_buf,
+ image_size);
+
+ update_uart(header);
+
+ /* Populate buffer with main header and extensions */
+ if (ext_cnt) {
+ ext_fd = fopen(ext_filename, "rb");
+ if (ext_fd == NULL) {
+ fprintf(stderr,
+ "Error: failed to open extensions file\n");
+ goto error;
+ }
+
+ read = fread(&buf[main_hdr_size],
+ get_file_size(ext_filename), 1, ext_fd);
+ if (read != 1) {
+ fprintf(stderr,
+ "Error: failed to open extensions file\n");
+ goto error;
+ }
+
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ /* Secure boot mode? */
+ if (opts.sec_opts != 0) {
+ ret = finalize_secure_ext(header, (uint8_t *)buf,
+ prolog_size, image_buf,
+ image_size);
+ if (ret != 0) {
+ fprintf(stderr, "Error: failed to handle ");
+ fprintf(stderr, "secure extension!\n");
+ goto error;
+ }
+ } /* secure boot mode */
+#endif
+ }
+
+ /* Update the total prolog checksum */
+ header->prolog_checksum = checksum32((uint32_t *)buf, prolog_size);
+
+ /* Now spill everything to output file */
+ written = fwrite(buf, prolog_size, 1, out_fd);
+ if (written != 1) {
+ fprintf(stderr,
+ "Error: failed to write prolog to output file\n");
+ goto error;
+ }
+
+ ret = 0;
+
+error:
+ free(buf);
+ return ret;
+}
+
+int write_boot_image(uint8_t *buf, uint32_t image_size, FILE *out_fd)
+{
+ int aligned_size;
+ int written;
+
+ /* Image size must be aligned to 4 bytes */
+ aligned_size = (image_size + 3) & (~0x3);
+
+ written = fwrite(buf, aligned_size, 1, out_fd);
+ if (written != 1) {
+ fprintf(stderr, "Error: Failed to write boot image\n");
+ goto error;
+ }
+
+ return 0;
+error:
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ char in_file[MAX_FILENAME+1];
+ char out_file[MAX_FILENAME+1];
+ char ext_file[MAX_FILENAME+1];
+ FILE *in_fd = NULL;
+ FILE *out_fd = NULL;
+ int parse = 0;
+ int ext_cnt = 0;
+ int opt;
+ int ret = 0;
+ int image_size;
+ uint8_t *image_buf = NULL;
+ int read;
+ uint32_t nand_block_size_kb, mlc_nand;
+
+ /* Create temporary file for building extensions
+ * Use process ID for allowing multiple parallel runs
+ */
+ snprintf(ext_file, MAX_FILENAME, "/tmp/ext_file-%x", getpid());
+
+ while ((opt = getopt(argc, argv, "hpms:i:l:e:a:b:u:n:t:c:k:")) != -1) {
+ switch (opt) {
+ case 'h':
+ usage();
+ break;
+ case 'l':
+ opts.load_addr = strtoul(optarg, NULL, 0);
+ break;
+ case 'e':
+ opts.exec_addr = strtoul(optarg, NULL, 0);
+ break;
+ case 'm':
+ opts.disable_print = 1;
+ break;
+ case 'u':
+ opts.baudrate = strtoul(optarg, NULL, 0);
+ break;
+ case 'b':
+ strncpy(opts.bin_ext_file, optarg, MAX_FILENAME);
+ ext_cnt++;
+ break;
+ case 'p':
+ parse = 1;
+ break;
+ case 'n':
+ nand_block_size_kb = strtoul(optarg, NULL, 0);
+ opts.nfc_io_args |= (nand_block_size_kb / 64);
+ break;
+ case 't':
+ mlc_nand = 0;
+ if (!strncmp("MLC", optarg, 3))
+ mlc_nand = 1;
+ opts.nfc_io_args |= (mlc_nand << 8);
+ break;
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ case 'c': /* SEC extension */
+ strncpy(opts.sec_cfg_file, optarg, MAX_FILENAME);
+ ext_cnt++;
+ break;
+ case 'k':
+ opts.key_index = strtoul(optarg, NULL, 0);
+ break;
+#endif
+ default: /* '?' */
+ usage_err("Unknown argument");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ /* Check validity of inputes */
+ if (opts.load_addr % 8)
+ usage_err("Load address must be 8 bytes aligned");
+
+ if (opts.baudrate % 1200)
+ usage_err("Baudrate must be a multiple of 1200");
+
+ /* The remaining arguments are the input
+ * and potentially output file
+ */
+ /* Input file must exist so exit if not */
+ if (optind >= argc)
+ usage_err("missing input file name");
+
+ strncpy(in_file, argv[optind], MAX_FILENAME);
+ optind++;
+
+ /* Output file must exist in non parse mode */
+ if (optind < argc)
+ strncpy(out_file, argv[optind], MAX_FILENAME);
+ else if (!parse)
+ usage_err("missing output file name");
+
+ /* open the input file */
+ in_fd = fopen(in_file, "rb");
+ if (in_fd == NULL) {
+ printf("Error: Failed to open input file %s\n", in_file);
+ goto main_exit;
+ }
+
+ /* Read the input file to buffer */
+ image_size = get_file_size(in_file);
+ image_buf = calloc((image_size + AES_BLOCK_SZ - 1) &
+ ~(AES_BLOCK_SZ - 1), 1);
+ if (image_buf == NULL) {
+ fprintf(stderr, "Error: failed allocating input buffer\n");
+ return 1;
+ }
+
+ read = fread(image_buf, image_size, 1, in_fd);
+ if (read != 1) {
+ fprintf(stderr, "Error: failed to read input file\n");
+ goto main_exit;
+ }
+
+ /* Parse the input image and leave */
+ if (parse) {
+ if (opts.key_index >= CSK_ARR_SZ) {
+ fprintf(stderr,
+ "Wrong key IDX value. Valid values 0 - %d\n",
+ CSK_ARR_SZ - 1);
+ goto main_exit;
+ }
+ ret = parse_image(image_buf, image_size);
+ goto main_exit;
+ }
+
+ /* Create a blob file from all extensions */
+ if (ext_cnt) {
+ ret = format_extensions(ext_file);
+ if (ret)
+ goto main_exit;
+ }
+
+ out_fd = fopen(out_file, "wb");
+ if (out_fd == NULL) {
+ fprintf(stderr,
+ "Error: Failed to open output file %s\n", out_file);
+ goto main_exit;
+ }
+
+ ret = write_prolog(ext_cnt, ext_file, image_buf, image_size, out_fd);
+ if (ret)
+ goto main_exit;
+
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ if (opts.sec_opts && (opts.sec_opts->encrypted_image != 0) &&
+ (opts.sec_opts->enc_image_sz != 0)) {
+ ret = write_boot_image(opts.sec_opts->encrypted_image,
+ opts.sec_opts->enc_image_sz, out_fd);
+ } else
+#endif
+ ret = write_boot_image(image_buf, image_size, out_fd);
+ if (ret)
+ goto main_exit;
+
+main_exit:
+ if (in_fd)
+ fclose(in_fd);
+
+ if (out_fd)
+ fclose(out_fd);
+
+ if (image_buf)
+ free(image_buf);
+
+ unlink(ext_file);
+
+#ifdef CONFIG_MVEBU_SECURE_BOOT
+ if (opts.sec_opts) {
+ if (opts.sec_opts->encrypted_image)
+ free(opts.sec_opts->encrypted_image);
+ free(opts.sec_opts);
+ }
+#endif
+ exit(ret);
+}
diff --git a/tools/doimage/doimage.mk b/tools/doimage/doimage.mk
new file mode 100644
index 000000000..2b751d403
--- /dev/null
+++ b/tools/doimage/doimage.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (C) 2018 Marvell International Ltd.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+# https://spdx.org/licenses
+
+DOIMAGE_FLAGS ?= -l 0x4100000 -e 0x4100000
+
+
+#NAND params
+#Open and update the below when using NAND as a boot device.
+
+CONFIG_MVEBU_NAND_BLOCK_SIZE := 256
+CONFIG_MVEBU_NAND_CELL_TYPE := SLC
+NAND_DOIMAGE_FLAGS := -t $(CONFIG_MVEBU_NAND_CELL_TYPE) -n $(CONFIG_MVEBU_NAND_BLOCK_SIZE)
diff --git a/tools/stm32image/Makefile b/tools/stm32image/Makefile
new file mode 100644
index 000000000..80dfbecf0
--- /dev/null
+++ b/tools/stm32image/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+MAKE_HELPERS_DIRECTORY := ../../make_helpers/
+include ${MAKE_HELPERS_DIRECTORY}build_macros.mk
+include ${MAKE_HELPERS_DIRECTORY}build_env.mk
+
+PROJECT := stm32image${BIN_EXT}
+OBJECTS := stm32image.o
+V := 0
+
+override CPPFLAGS += -D_GNU_SOURCE
+CFLAGS := -Wall -Werror -pedantic -std=c99
+ifeq (${DEBUG},1)
+ CFLAGS += -g -O0 -DDEBUG
+else
+ CFLAGS += -O2
+endif
+
+ifeq (${V},0)
+ Q := @
+else
+ Q :=
+endif
+
+CC := gcc
+
+.PHONY: all clean distclean
+
+all: ${PROJECT}
+
+${PROJECT}: ${OBJECTS} Makefile
+ @echo " LD $@"
+ ${Q}${CC} ${OBJECTS} -o $@
+ @${ECHO_BLANK_LINE}
+ @echo "Built $@ successfully"
+ @${ECHO_BLANK_LINE}
+
+%.o: %.c %.h Makefile
+ @echo " CC $<"
+ ${Q}${CC} -c ${CFLAGS} $< -o $@
+
+clean:
+ $(call SHELL_DELETE_ALL, ${PROJECT} ${OBJECTS})
+
+distclean: clean
diff --git a/tools/stm32image/stm32image.c b/tools/stm32image/stm32image.c
new file mode 100644
index 000000000..260792844
--- /dev/null
+++ b/tools/stm32image/stm32image.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2017-2018, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm/byteorder.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Magic = 'S' 'T' 'M' 0x32 */
+#define HEADER_MAGIC __be32_to_cpu(0x53544D32)
+#define VER_MAJOR 2
+#define VER_MINOR 1
+#define VER_VARIANT 0
+#define HEADER_VERSION_V1 0x1
+#define TF_BINARY_TYPE 0x0
+
+/* Default option : bit0 => no signature */
+#define HEADER_DEFAULT_OPTION (__cpu_to_le32(0x00000001))
+
+struct stm32_header {
+ uint32_t magic_number;
+ uint8_t image_signature[64];
+ uint32_t image_checksum;
+ uint8_t header_version[4];
+ uint32_t image_length;
+ uint32_t image_entry_point;
+ uint32_t reserved1;
+ uint32_t load_address;
+ uint32_t reserved2;
+ uint32_t version_number;
+ uint32_t option_flags;
+ uint32_t ecdsa_algorithm;
+ uint8_t ecdsa_public_key[64];
+ uint8_t padding[83];
+ uint8_t binary_type;
+};
+
+static struct stm32_header stm32image_header;
+
+static void stm32image_default_header(struct stm32_header *ptr)
+{
+ if (!ptr) {
+ return;
+ }
+
+ ptr->magic_number = HEADER_MAGIC;
+ ptr->header_version[VER_MAJOR] = HEADER_VERSION_V1;
+ ptr->option_flags = HEADER_DEFAULT_OPTION;
+ ptr->ecdsa_algorithm = 1;
+ ptr->version_number = 0;
+ ptr->binary_type = TF_BINARY_TYPE;
+}
+
+static uint32_t stm32image_checksum(void *start, uint32_t len)
+{
+ uint32_t csum = 0;
+ uint32_t hdr_len = sizeof(struct stm32_header);
+ uint8_t *p;
+
+ if (len < hdr_len) {
+ return 0;
+ }
+
+ p = (unsigned char *)start + hdr_len;
+ len -= hdr_len;
+
+ while (len > 0) {
+ csum += *p;
+ p++;
+ len--;
+ }
+
+ return csum;
+}
+
+static void stm32image_print_header(const void *ptr)
+{
+ struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+
+ printf("Image Type : ST Microelectronics STM32 V%d.%d\n",
+ stm32hdr->header_version[VER_MAJOR],
+ stm32hdr->header_version[VER_MINOR]);
+ printf("Image Size : %lu bytes\n",
+ (unsigned long)__le32_to_cpu(stm32hdr->image_length));
+ printf("Image Load : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->load_address));
+ printf("Entry Point : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->image_entry_point));
+ printf("Checksum : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->image_checksum));
+ printf("Option : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->option_flags));
+ printf("Version : 0x%08x\n",
+ __le32_to_cpu(stm32hdr->version_number));
+}
+
+static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
+ uint32_t loadaddr, uint32_t ep, uint32_t ver)
+{
+ struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
+
+ stm32image_default_header(stm32hdr);
+
+ stm32hdr->load_address = __cpu_to_le32(loadaddr);
+ stm32hdr->image_entry_point = __cpu_to_le32(ep);
+ stm32hdr->image_length = __cpu_to_le32((uint32_t)sbuf->st_size -
+ sizeof(struct stm32_header));
+ stm32hdr->image_checksum = stm32image_checksum(ptr, sbuf->st_size);
+ stm32hdr->version_number = __cpu_to_le32(ver);
+}
+
+static int stm32image_create_header_file(char *srcname, char *destname,
+ uint32_t loadaddr, uint32_t entry,
+ uint32_t version)
+{
+ int src_fd, dest_fd;
+ struct stat sbuf;
+ unsigned char *ptr;
+
+ dest_fd = open(destname, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666);
+ if (dest_fd == -1) {
+ fprintf(stderr, "Can't open %s: %s\n", destname,
+ strerror(errno));
+ return -1;
+ }
+
+ src_fd = open(srcname, O_RDONLY);
+ if (src_fd == -1) {
+ fprintf(stderr, "Can't open %s: %s\n", srcname,
+ strerror(errno));
+ return -1;
+ }
+
+ if (fstat(src_fd, &sbuf) < 0) {
+ return -1;
+ }
+
+ ptr = mmap(NULL, sbuf.st_size, PROT_READ, MAP_SHARED, src_fd, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "Can't read %s\n", srcname);
+ return -1;
+ }
+
+ memset(&stm32image_header, 0, sizeof(struct stm32_header));
+
+ if (write(dest_fd, &stm32image_header, sizeof(struct stm32_header)) !=
+ sizeof(struct stm32_header)) {
+ fprintf(stderr, "Write error %s: %s\n", destname,
+ strerror(errno));
+ return -1;
+ }
+
+ if (write(dest_fd, ptr, sbuf.st_size) != sbuf.st_size) {
+ fprintf(stderr, "Write error on %s: %s\n", destname,
+ strerror(errno));
+ return -1;
+ }
+
+ munmap((void *)ptr, sbuf.st_size);
+ close(src_fd);
+
+ if (fstat(dest_fd, &sbuf) < 0) {
+ return -1;
+ }
+
+ ptr = mmap(0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ dest_fd, 0);
+
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "Can't read %s\n", srcname);
+ return -1;
+ }
+
+ stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, entry, version);
+
+ stm32image_print_header(ptr);
+
+ munmap((void *)ptr, sbuf.st_size);
+ close(dest_fd);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int opt, loadaddr = -1, entry = -1, err = 0, version = 0;
+ char *dest = NULL, *src = NULL;
+
+ while ((opt = getopt(argc, argv, ":s:d:l:e:v:")) != -1) {
+ switch (opt) {
+ case 's':
+ src = optarg;
+ break;
+ case 'd':
+ dest = optarg;
+ break;
+ case 'l':
+ loadaddr = strtol(optarg, NULL, 16);
+ break;
+ case 'e':
+ entry = strtol(optarg, NULL, 16);
+ break;
+ case 'v':
+ version = strtol(optarg, NULL, 10);
+ break;
+ default:
+ fprintf(stderr,
+ "Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point]\n",
+ argv[0]);
+ return -1;
+ }
+ }
+
+ if (!src) {
+ fprintf(stderr, "Missing -s option\n");
+ return -1;
+ }
+
+ if (!dest) {
+ fprintf(stderr, "Missing -d option\n");
+ return -1;
+ }
+
+ if (loadaddr == -1) {
+ fprintf(stderr, "Missing -l option\n");
+ return -1;
+ }
+
+ if (entry == -1) {
+ fprintf(stderr, "Missing -e option\n");
+ return -1;
+ }
+
+ err = stm32image_create_header_file(src, dest, loadaddr,
+ entry, version);
+
+ return err;
+}