aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile74
-rw-r--r--bl1/aarch64/bl1_entrypoint.S3
-rw-r--r--bl1/bl1.ld.S14
-rw-r--r--bl2/aarch64/bl2_el3_entrypoint.S3
-rw-r--r--bl2/bl2.ld.S12
-rw-r--r--bl2/bl2_el3.ld.S12
-rw-r--r--bl2u/bl2u.ld.S12
-rw-r--r--bl31/aarch64/bl31_entrypoint.S22
-rw-r--r--bl31/aarch64/ea_delegate.S13
-rw-r--r--bl31/bl31.ld.S54
-rw-r--r--bl31/bl31.mk22
-rw-r--r--bl32/sp_min/aarch32/entrypoint.S68
-rw-r--r--bl32/sp_min/sp_min.ld.S8
-rw-r--r--bl32/sp_min/sp_min_main.c7
-rw-r--r--docs/about/maintainers.rst18
-rw-r--r--docs/change-log-upcoming.rst145
-rw-r--r--docs/components/arm-sip-service.rst341
-rw-r--r--docs/components/debugfs-design.rst132
-rw-r--r--docs/components/secure-partition-manager-design.rst43
-rw-r--r--docs/design/cpu-specific-build-macros.rst6
-rw-r--r--docs/design/firmware-design.rst5
-rw-r--r--docs/getting_started/build-options.rst37
-rw-r--r--docs/getting_started/initial-build.rst8
-rw-r--r--docs/getting_started/porting-guide.rst2
-rw-r--r--docs/getting_started/prerequisites.rst2
-rw-r--r--docs/plat/arm/fvp/index.rst2
-rw-r--r--docs/plat/arm/juno/index.rst2
-rw-r--r--docs/plat/nvidia-tegra.rst20
-rw-r--r--docs/plat/rpi4.rst9
-rw-r--r--docs/plat/stm32mp1.rst23
-rw-r--r--docs/process/security-hardening.rst7
-rw-r--r--drivers/allwinner/axp/axp803.c22
-rw-r--r--drivers/allwinner/axp/axp805.c33
-rw-r--r--drivers/allwinner/axp/common.c175
-rw-r--r--drivers/arm/css/scp/css_pm_scmi.c5
-rw-r--r--drivers/arm/sbsa/sbsa.c6
-rw-r--r--drivers/arm/scu/scu.c51
-rw-r--r--drivers/auth/auth_mod.c3
-rw-r--r--drivers/auth/cryptocell/712/cryptocell_crypto.c2
-rw-r--r--drivers/auth/cryptocell/cryptocell_crypto.mk4
-rw-r--r--drivers/intel/soc/stratix10/io/s10_memmap_qspi.c18
-rw-r--r--drivers/io/io_block.c60
-rw-r--r--drivers/io/io_fip.c6
-rw-r--r--drivers/io/io_memmap.c30
-rw-r--r--drivers/io/io_mtd.c248
-rw-r--r--drivers/io/io_semihosting.c6
-rw-r--r--drivers/io/io_storage.c2
-rw-r--r--drivers/marvell/comphy/phy-comphy-3700.c73
-rw-r--r--drivers/mtd/nand/core.c118
-rw-r--r--drivers/mtd/nand/raw_nand.c446
-rw-r--r--drivers/mtd/nand/spi_nand.c320
-rw-r--r--drivers/mtd/nor/spi_nor.c387
-rw-r--r--drivers/mtd/spi-mem/spi_mem.c288
-rw-r--r--drivers/renesas/rcar/ddr/boot_init_dram.h (renamed from drivers/staging/renesas/rcar/ddr/boot_init_dram.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr.mk17
-rw-r--r--drivers/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk13
-rw-r--r--drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c (renamed from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c (renamed from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c (renamed from drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk)2
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/ddr_regdef.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/ddr_regdef.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h)0
-rw-r--r--drivers/renesas/rcar/ddr/ddr_regs.h (renamed from drivers/staging/renesas/rcar/ddr/ddr_regs.h)0
-rw-r--r--drivers/renesas/rcar/ddr/dram_sub_func.c (renamed from drivers/staging/renesas/rcar/ddr/dram_sub_func.c)0
-rw-r--r--drivers/renesas/rcar/ddr/dram_sub_func.h (renamed from drivers/staging/renesas/rcar/ddr/dram_sub_func.h)0
-rw-r--r--drivers/renesas/rcar/io/io_emmcdrv.c20
-rw-r--r--drivers/renesas/rcar/io/io_memdrv.c19
-rw-r--r--drivers/renesas/rcar/io/io_rcar.c3
-rw-r--r--drivers/st/fmc/stm32_fmc2_nand.c877
-rw-r--r--drivers/st/io/io_mmc.c10
-rw-r--r--drivers/st/spi/stm32_qspi.c500
-rw-r--r--drivers/staging/renesas/rcar/ddr/ddr.mk17
-rw-r--r--drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk13
-rw-r--r--drivers/ti/uart/aarch32/16550_console.S18
-rw-r--r--drivers/ti/uart/aarch64/16550_console.S9
-rw-r--r--fdts/a5ds.dts38
-rw-r--r--fdts/stm32mp157-pinctrl.dtsi27
-rw-r--r--fdts/stm32mp157c-ev1.dts18
-rw-r--r--include/arch/aarch64/arch.h3
-rw-r--r--include/arch/aarch64/el3_common_macros.S37
-rw-r--r--include/drivers/allwinner/axp.h48
-rw-r--r--include/drivers/arm/cryptocell/712/rsa.h16
-rw-r--r--include/drivers/arm/cryptocell/712/secureboot_gen_defs.h16
-rw-r--r--include/drivers/arm/scu.h20
-rw-r--r--include/drivers/io/io_driver.h2
-rw-r--r--include/drivers/io/io_mtd.h59
-rw-r--r--include/drivers/io/io_storage.h5
-rw-r--r--include/drivers/nand.h55
-rw-r--r--include/drivers/raw_nand.h187
-rw-r--r--include/drivers/spi_mem.h130
-rw-r--r--include/drivers/spi_nand.h49
-rw-r--r--include/drivers/spi_nor.h58
-rw-r--r--include/drivers/st/io_stm32image.h2
-rw-r--r--include/drivers/st/stm32_fmc2_nand.h12
-rw-r--r--include/drivers/st/stm32_qspi.h12
-rw-r--r--include/drivers/ti/uart/uart_16550.h5
-rw-r--r--include/export/lib/utils_def_exp.h4
-rw-r--r--include/lib/cpus/aarch64/cortex_a72.h11
-rw-r--r--include/lib/cpus/aarch64/cortex_hercules.h3
-rw-r--r--include/lib/debugfs.h83
-rw-r--r--include/lib/libc/aarch32/stddef_.h7
-rw-r--r--include/lib/libc/aarch32/stdint_.h118
-rw-r--r--include/lib/libc/aarch32/stdio_.h7
-rw-r--r--include/lib/libc/aarch32/stdlib_.h18
-rw-r--r--include/lib/libc/aarch32/string_.h15
-rw-r--r--include/lib/libc/aarch32/time_.h17
-rw-r--r--include/lib/libc/aarch64/stddef_.h7
-rw-r--r--include/lib/libc/aarch64/stdint_.h121
-rw-r--r--include/lib/libc/aarch64/stdio_.h7
-rw-r--r--include/lib/libc/aarch64/stdlib_.h18
-rw-r--r--include/lib/libc/aarch64/string_.h15
-rw-r--r--include/lib/libc/aarch64/time_.h17
-rw-r--r--include/lib/libc/stddef.h7
-rw-r--r--include/lib/libc/stdint.h126
-rw-r--r--include/lib/libc/stdio.h7
-rw-r--r--include/lib/libc/stdlib.h9
-rw-r--r--include/lib/libc/string.h9
-rw-r--r--include/lib/libc/time.h8
-rw-r--r--include/lib/pmf/aarch32/pmf_asm_macros.S28
-rw-r--r--include/lib/pmf/aarch64/pmf_asm_macros.S (renamed from include/lib/pmf/pmf_asm_macros.S)0
-rw-r--r--include/lib/pmf/pmf.h102
-rw-r--r--include/lib/pmf/pmf_helpers.h112
-rw-r--r--include/lib/psci/psci.h2
-rw-r--r--include/lib/smccc.h4
-rw-r--r--include/lib/sprt/sprt_common.h38
-rw-r--r--include/lib/sprt/sprt_host.h26
-rw-r--r--include/lib/utils.h14
-rw-r--r--include/lib/utils_def.h9
-rw-r--r--include/plat/arm/common/arm_def.h8
-rw-r--r--include/plat/arm/common/arm_reclaim_init.ld.S5
-rw-r--r--include/plat/arm/common/arm_sip_svc.h8
-rw-r--r--include/plat/arm/common/arm_spm_def.h40
-rw-r--r--include/plat/arm/common/plat_arm.h2
-rw-r--r--include/plat/common/platform.h6
-rw-r--r--include/plat/marvell/a8k/common/armada_common.h1
-rw-r--r--include/services/mm_svc.h35
-rw-r--r--include/services/sp_res_desc.h253
-rw-r--r--include/services/sp_res_desc_def.h94
-rw-r--r--include/services/spci_svc.h124
-rw-r--r--include/services/spm_mm_partition.h (renamed from include/services/secure_partition.h)22
-rw-r--r--include/services/spm_mm_svc.h114
-rw-r--r--include/services/spm_svc.h90
-rw-r--r--include/services/sprt_svc.h74
-rw-r--r--lib/compiler-rt/builtins/arm/aeabi_ldivmod.S46
-rw-r--r--lib/compiler-rt/builtins/divdi3.c29
-rw-r--r--lib/compiler-rt/builtins/divmoddi4.c25
-rw-r--r--lib/compiler-rt/builtins/popcountdi2.c36
-rw-r--r--lib/compiler-rt/builtins/popcountsi2.c33
-rw-r--r--lib/compiler-rt/compiler-rt.mk14
-rw-r--r--lib/cpus/aarch64/cortex_hercules.S65
-rw-r--r--lib/cpus/cpu-ops.mk8
-rw-r--r--lib/debugfs/blobs.h12
-rw-r--r--lib/debugfs/debugfs.mk13
-rw-r--r--lib/debugfs/debugfs_smc.c209
-rw-r--r--lib/debugfs/dev.c849
-rw-r--r--lib/debugfs/dev.h120
-rw-r--r--lib/debugfs/devc.c20
-rw-r--r--lib/debugfs/devfip.c317
-rw-r--r--lib/debugfs/devroot.c97
-rw-r--r--lib/el3_runtime/aarch64/context.S8
-rw-r--r--lib/el3_runtime/aarch64/context_mgmt.c10
-rw-r--r--lib/libc/libc.mk1
-rw-r--r--lib/libc/memrchr.c24
-rw-r--r--lib/psci/psci_common.c17
-rw-r--r--lib/psci/psci_main.c13
-rw-r--r--lib/psci/psci_off.c4
-rw-r--r--lib/psci/psci_on.c24
-rw-r--r--lib/psci/psci_private.h7
-rw-r--r--lib/psci/psci_setup.c27
-rw-r--r--lib/psci/psci_stat.c12
-rw-r--r--lib/psci/psci_suspend.c8
-rw-r--r--lib/sprt/sprt_host.c48
-rw-r--r--lib/sprt/sprt_host.mk11
-rw-r--r--lib/sprt/sprt_queue.c104
-rw-r--r--lib/sprt/sprt_queue.h47
-rw-r--r--make_helpers/build_macros.mk6
-rw-r--r--make_helpers/defaults.mk17
-rw-r--r--plat/allwinner/common/allwinner-common.mk14
-rw-r--r--plat/allwinner/common/include/platform_def.h8
-rw-r--r--plat/allwinner/common/include/sunxi_private.h7
-rw-r--r--plat/allwinner/common/sunxi_common.c20
-rw-r--r--plat/allwinner/common/sunxi_cpu_ops.c2
-rw-r--r--plat/allwinner/common/sunxi_pm.c7
-rw-r--r--plat/allwinner/sun50i_a64/platform.mk5
-rw-r--r--plat/allwinner/sun50i_a64/sunxi_power.c201
-rw-r--r--plat/allwinner/sun50i_h6/platform.mk5
-rw-r--r--plat/allwinner/sun50i_h6/sunxi_power.c88
-rw-r--r--plat/arm/board/a5ds/a5ds_common.c6
-rw-r--r--plat/arm/board/a5ds/a5ds_pm.c3
-rw-r--r--plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts4
-rw-r--r--plat/arm/board/a5ds/include/platform_def.h69
-rw-r--r--plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c5
-rw-r--r--plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk3
-rw-r--r--plat/arm/board/corstone700/include/platform_def.h6
-rw-r--r--plat/arm/board/fvp/fvp_common.c28
-rw-r--r--plat/arm/board/fvp/fvp_def.h8
-rw-r--r--plat/arm/board/fvp/include/plat.ld.S5
-rw-r--r--plat/arm/board/fvp/include/platform_def.h23
-rw-r--r--plat/arm/board/fvp/platform.mk15
-rw-r--r--plat/arm/board/fvp_ve/fvp_ve_def.h10
-rw-r--r--plat/arm/board/fvp_ve/include/platform_def.h6
-rw-r--r--plat/arm/board/juno/juno_def.h8
-rw-r--r--plat/arm/board/rde1edge/include/platform_def.h6
-rw-r--r--plat/arm/board/rdn1edge/include/platform_def.h6
-rw-r--r--plat/arm/board/sgi575/include/platform_def.h8
-rw-r--r--plat/arm/board/sgm775/include/platform_def.h6
-rw-r--r--plat/arm/common/aarch64/arm_ehf.c4
-rw-r--r--plat/arm/common/aarch64/execution_state_switch.c (renamed from plat/arm/common/execution_state_switch.c)8
-rw-r--r--plat/arm/common/arm_bl31_setup.c7
-rw-r--r--plat/arm/common/arm_common.c2
-rw-r--r--plat/arm/common/arm_common.mk19
-rw-r--r--plat/arm/common/arm_dyn_cfg.c19
-rw-r--r--plat/arm/common/arm_gicv3.c9
-rw-r--r--plat/arm/common/arm_sip_svc.c37
-rw-r--r--plat/arm/css/sgi/include/sgi_base_platform_def.h6
-rw-r--r--plat/arm/css/sgi/sgi-common.mk4
-rw-r--r--plat/arm/css/sgi/sgi_plat.c24
-rw-r--r--plat/arm/css/sgi/sgi_ras.c11
-rw-r--r--plat/arm/css/sgm/include/sgm_base_platform_def.h6
-rw-r--r--plat/common/plat_psci_common.c8
-rw-r--r--plat/common/plat_spm_rd.c316
-rw-r--r--plat/common/plat_spm_sp.c93
-rw-r--r--plat/imx/common/include/imx_caam.h3
-rw-r--r--plat/imx/common/include/imx_snvs.h3
-rw-r--r--plat/imx/common/include/sci/sci_ipc.h4
-rw-r--r--plat/imx/common/sci/ipc.c4
-rw-r--r--plat/imx/imx8m/include/imx8m_psci.h4
-rw-r--r--plat/intel/soc/agilex/bl2_plat_setup.c11
-rw-r--r--plat/intel/soc/agilex/bl31_plat_setup.c13
-rw-r--r--plat/intel/soc/agilex/include/agilex_clock_manager.h2
-rw-r--r--plat/intel/soc/agilex/include/agilex_pinmux.h2
-rw-r--r--plat/intel/soc/agilex/include/agilex_private.h34
-rw-r--r--plat/intel/soc/agilex/include/agilex_system_manager.h1
-rw-r--r--plat/intel/soc/agilex/include/socfpga_plat_def.h23
-rw-r--r--plat/intel/soc/agilex/platform.mk39
-rw-r--r--plat/intel/soc/agilex/soc/agilex_clock_manager.c2
-rw-r--r--plat/intel/soc/agilex/soc/agilex_memory_controller.c7
-rw-r--r--plat/intel/soc/common/aarch64/plat_helpers.S36
-rw-r--r--plat/intel/soc/common/aarch64/platform_common.c3
-rw-r--r--plat/intel/soc/common/drivers/ccu/ncore_ccu.c1
-rw-r--r--plat/intel/soc/common/drivers/qspi/cadence_qspi.c12
-rw-r--r--plat/intel/soc/common/drivers/wdt/watchdog.c1
-rw-r--r--plat/intel/soc/common/include/platform_def.h (renamed from plat/intel/soc/agilex/include/platform_def.h)121
-rw-r--r--plat/intel/soc/common/include/socfpga_handoff.h (renamed from plat/intel/soc/agilex/include/agilex_handoff.h)44
-rw-r--r--plat/intel/soc/common/include/socfpga_mailbox.h (renamed from plat/intel/soc/agilex/include/agilex_mailbox.h)67
-rw-r--r--plat/intel/soc/common/include/socfpga_private.h33
-rw-r--r--plat/intel/soc/common/include/socfpga_reset_manager.h18
-rw-r--r--plat/intel/soc/common/include/socfpga_sip_svc.h45
-rw-r--r--plat/intel/soc/common/soc/socfpga_handoff.c (renamed from plat/intel/soc/agilex/soc/agilex_handoff.c)5
-rw-r--r--plat/intel/soc/common/soc/socfpga_mailbox.c (renamed from plat/intel/soc/agilex/soc/agilex_mailbox.c)122
-rw-r--r--plat/intel/soc/common/socfpga_image_load.c26
-rw-r--r--plat/intel/soc/common/socfpga_psci.c (renamed from plat/intel/soc/agilex/socfpga_psci.c)54
-rw-r--r--plat/intel/soc/common/socfpga_sip_svc.c (renamed from plat/intel/soc/agilex/socfpga_sip_svc.c)306
-rw-r--r--plat/intel/soc/common/socfpga_storage.c (renamed from plat/intel/soc/agilex/socfpga_storage.c)2
-rw-r--r--plat/intel/soc/stratix10/bl2_plat_setup.c34
-rw-r--r--plat/intel/soc/stratix10/bl31_plat_setup.c51
-rw-r--r--plat/intel/soc/stratix10/include/platform_def.h198
-rw-r--r--plat/intel/soc/stratix10/include/s10_clock_manager.h2
-rw-r--r--plat/intel/soc/stratix10/include/s10_handoff.h98
-rw-r--r--plat/intel/soc/stratix10/include/s10_mailbox.h125
-rw-r--r--plat/intel/soc/stratix10/include/s10_pinmux.h2
-rw-r--r--plat/intel/soc/stratix10/include/s10_system_manager.h2
-rw-r--r--plat/intel/soc/stratix10/include/socfpga_plat_def.h22
-rw-r--r--plat/intel/soc/stratix10/include/stratix10_private.h34
-rw-r--r--plat/intel/soc/stratix10/plat_psci.c208
-rw-r--r--plat/intel/soc/stratix10/plat_sip_svc.c378
-rw-r--r--plat/intel/soc/stratix10/plat_storage.c195
-rw-r--r--plat/intel/soc/stratix10/platform.mk58
-rw-r--r--plat/intel/soc/stratix10/soc/s10_clock_manager.c2
-rw-r--r--plat/intel/soc/stratix10/soc/s10_handoff.c47
-rw-r--r--plat/intel/soc/stratix10/soc/s10_mailbox.c275
-rw-r--r--plat/intel/soc/stratix10/soc/s10_memory_controller.c13
-rw-r--r--plat/marvell/a8k/common/a8k_common.mk11
-rw-r--r--plat/marvell/a8k/common/plat_pm.c12
-rw-r--r--plat/mediatek/mt8173/drivers/spm/spm.h1
-rw-r--r--plat/mediatek/mt8183/drivers/spm/spm.c11
-rw-r--r--plat/nvidia/tegra/common/tegra_bl31_setup.c28
-rw-r--r--plat/nvidia/tegra/common/tegra_pm.c2
-rw-r--r--plat/nvidia/tegra/include/drivers/bpmp_ipc.h7
-rw-r--r--plat/nvidia/tegra/include/drivers/gpcdma.h7
-rw-r--r--plat/nvidia/tegra/include/drivers/security_engine.h4
-rw-r--r--plat/nvidia/tegra/include/drivers/tegra_gic.h7
-rw-r--r--plat/nvidia/tegra/include/lib/profiler.h7
-rw-r--r--plat/nvidia/tegra/include/t194/tegra194_private.h8
-rw-r--r--plat/nvidia/tegra/include/t194/tegra_def.h14
-rw-r--r--plat/nvidia/tegra/include/t194/tegra_mc_def.h650
-rw-r--r--plat/nvidia/tegra/include/tegra_private.h1
-rw-r--r--plat/nvidia/tegra/scat/bl31.scat2
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h9
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/include/se.h8
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c29
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se.c3
-rw-r--r--plat/nvidia/tegra/soc/t194/drivers/se/se_private.h11
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_psci_handlers.c11
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_smmu.c139
-rw-r--r--plat/nvidia/tegra/soc/t194/plat_trampoline.S2
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/se_private.h4
-rw-r--r--plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c4
-rw-r--r--plat/renesas/rcar/bl2_plat_mem_params_desc.c3
-rw-r--r--plat/renesas/rcar/bl2_plat_setup.c3
-rw-r--r--plat/renesas/rcar/platform.mk4
-rw-r--r--plat/rockchip/px30/drivers/pmu/pmu.c1
-rw-r--r--plat/rockchip/px30/drivers/secure/secure.c103
-rw-r--r--plat/rockchip/px30/drivers/secure/secure.h65
-rw-r--r--plat/rockchip/px30/drivers/soc/soc.c61
-rw-r--r--plat/rockchip/px30/drivers/soc/soc.h54
-rw-r--r--plat/rockchip/px30/include/platform_def.h4
-rw-r--r--plat/rockchip/px30/platform.mk7
-rw-r--r--plat/rockchip/px30/px30_def.h4
-rw-r--r--plat/rockchip/rk3288/drivers/secure/secure.c11
-rw-r--r--plat/rockchip/rk3328/drivers/soc/soc.c4
-rw-r--r--plat/rockchip/rk3328/drivers/soc/soc.h2
-rw-r--r--plat/rockchip/rk3328/include/platform_def.h6
-rw-r--r--plat/rockchip/rk3328/platform.mk8
-rw-r--r--plat/rockchip/rk3368/include/platform_def.h6
-rw-r--r--plat/rockchip/rk3399/drivers/dp/cdn_dp.c2
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu.c19
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu.h1
-rw-r--r--plat/rockchip/rk3399/drivers/pmu/pmu_fw.c24
-rw-r--r--plat/rockchip/rk3399/drivers/secure/secure.c7
-rw-r--r--plat/rockchip/rk3399/drivers/soc/soc.c2
-rw-r--r--plat/rockchip/rk3399/plat_sip_calls.c4
-rw-r--r--plat/rockchip/rk3399/platform.mk17
-rw-r--r--plat/rpi/rpi4/aarch64/plat_helpers.S4
-rw-r--r--plat/rpi/rpi4/include/rpi_hw.h8
-rw-r--r--plat/rpi/rpi4/rpi4_bl31_setup.c16
-rw-r--r--plat/socionext/synquacer/platform.mk4
-rw-r--r--plat/socionext/synquacer/sq_bl31_setup.c4
-rw-r--r--plat/socionext/synquacer/sq_spm.c12
-rw-r--r--plat/socionext/uniphier/platform.mk1
-rw-r--r--plat/socionext/uniphier/uniphier_image_desc.c2
-rw-r--r--plat/socionext/uniphier/uniphier_psci.c25
-rw-r--r--plat/st/common/bl2_io_storage.c242
-rw-r--r--plat/st/common/include/stm32mp_dt.h2
-rw-r--r--plat/st/common/stm32mp_dt.c92
-rw-r--r--plat/st/stm32mp1/include/boot_api.h9
-rw-r--r--plat/st/stm32mp1/include/platform_def.h1
-rw-r--r--plat/st/stm32mp1/include/stm32mp1_boot_device.h18
-rw-r--r--plat/st/stm32mp1/platform.mk53
-rw-r--r--plat/st/stm32mp1/stm32mp1_boot_device.c170
-rw-r--r--plat/st/stm32mp1/stm32mp1_def.h81
-rw-r--r--plat/xilinx/zynqmp/aarch64/zynqmp_common.c14
-rw-r--r--plat/xilinx/zynqmp/include/zynqmp_def.h3
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.c339
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_clock.h35
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.c18
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_api_sys.h3
-rw-r--r--plat/xilinx/zynqmp/pm_service/pm_svc_main.c13
-rw-r--r--services/std_svc/spm/README.rst3
-rw-r--r--services/std_svc/spm/aarch64/spm_helpers.S74
-rw-r--r--services/std_svc/spm/spci.c769
-rw-r--r--services/std_svc/spm/spm.mk30
-rw-r--r--services/std_svc/spm/spm_buffers.c112
-rw-r--r--services/std_svc/spm/spm_main.c359
-rw-r--r--services/std_svc/spm/spm_private.h119
-rw-r--r--services/std_svc/spm/spm_setup.c167
-rw-r--r--services/std_svc/spm/spm_shim_private.h34
-rw-r--r--services/std_svc/spm/spm_xlat.c381
-rw-r--r--services/std_svc/spm/sprt.c219
-rw-r--r--services/std_svc/spm_mm/aarch64/spm_mm_helpers.S (renamed from services/std_svc/spm_mm/aarch64/spm_helpers.S)4
-rw-r--r--services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S (renamed from services/std_svc/spm/aarch64/spm_shim_exceptions.S)0
-rw-r--r--services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S128
-rw-r--r--services/std_svc/spm_mm/spm_mm.mk (renamed from services/std_svc/spm_mm/spm.mk)16
-rw-r--r--services/std_svc/spm_mm/spm_mm_main.c (renamed from services/std_svc/spm_mm/spm_main.c)49
-rw-r--r--services/std_svc/spm_mm/spm_mm_private.h (renamed from services/std_svc/spm_mm/spm_private.h)8
-rw-r--r--services/std_svc/spm_mm/spm_mm_setup.c (renamed from services/std_svc/spm_mm/spm_setup.c)28
-rw-r--r--services/std_svc/spm_mm/spm_mm_shim_private.h (renamed from services/std_svc/spm_mm/spm_shim_private.h)8
-rw-r--r--services/std_svc/spm_mm/spm_mm_xlat.c (renamed from services/std_svc/spm_mm/spm_xlat.c)38
-rw-r--r--services/std_svc/std_svc_setup.c14
-rwxr-xr-xtools/memory/print_memory_map.py68
377 files changed, 11241 insertions, 7789 deletions
diff --git a/Makefile b/Makefile
index d634b336b9..42fdb73261 100644
--- a/Makefile
+++ b/Makefile
@@ -150,6 +150,15 @@ else
endif
endif
+# USE_DEBUGFS experimental feature recommended only in debug builds
+ifeq (${USE_DEBUGFS},1)
+ifeq (${DEBUG},1)
+ $(warning DEBUGFS experimental feature is enabled.)
+else
+ $(warning DEBUGFS experimental, recommended in DEBUG builds ONLY)
+endif
+endif
+
################################################################################
# Toolchain
################################################################################
@@ -204,6 +213,18 @@ LD = $(LINKER)
AS = $(CC) -c -x assembler-with-cpp $(TF_CFLAGS_$(ARCH))
CPP = $(CC) -E
PP = $(CC) -E
+else ifneq ($(findstring gcc,$(notdir $(CC))),)
+TF_CFLAGS_aarch32 = $(march32-directive)
+TF_CFLAGS_aarch64 = $(march64-directive)
+ifeq ($(ENABLE_LTO),1)
+ # Enable LTO only for aarch64
+ ifeq (${ARCH},aarch64)
+ LTO_CFLAGS = -flto
+ # Use gcc as a wrapper for the ld, recommended for LTO
+ LINKER := ${CROSS_COMPILE}gcc
+ endif
+endif
+LD = $(LINKER)
else
TF_CFLAGS_aarch32 = $(march32-directive)
TF_CFLAGS_aarch64 = $(march64-directive)
@@ -236,11 +257,9 @@ WARNINGS := -Wall -Wmissing-include-dirs -Wunused \
# Additional warnings
# Level 1
WARNING1 := -Wextra
-WARNING1 += -Wmissing-declarations
WARNING1 += -Wmissing-format-attribute
WARNING1 += -Wmissing-prototypes
WARNING1 += -Wold-style-definition
-WARNING1 += -Wunused-const-variable
# Level 2
WARNING2 := -Waggregate-return
@@ -251,7 +270,6 @@ WARNING3 := -Wbad-function-cast
WARNING3 += -Wcast-qual
WARNING3 += -Wconversion
WARNING3 += -Wpacked
-WARNING3 += -Wpadded
WARNING3 += -Wpointer-arith
WARNING3 += -Wredundant-decls
WARNING3 += -Wswitch-default
@@ -285,8 +303,9 @@ CPPFLAGS = ${DEFINES} ${INCLUDES} ${MBEDTLS_INC} -nostdinc \
ASFLAGS += $(CPPFLAGS) $(ASFLAGS_$(ARCH)) \
-ffreestanding -Wa,--fatal-warnings
TF_CFLAGS += $(CPPFLAGS) $(TF_CFLAGS_$(ARCH)) \
- -ffreestanding -fno-builtin -std=gnu99 \
- -Os -ffunction-sections -fdata-sections
+ -ffunction-sections -fdata-sections \
+ -ffreestanding -fno-builtin -fno-common \
+ -Os -std=gnu99
ifeq (${SANITIZE_UB},on)
TF_CFLAGS += -fsanitize=undefined -fno-sanitize-recover
@@ -301,11 +320,28 @@ GCC_V_OUTPUT := $(shell $(CC) -v 2>&1)
ifneq ($(findstring armlink,$(notdir $(LD))),)
TF_LDFLAGS += --diag_error=warning --lto_level=O1
TF_LDFLAGS += --remove --info=unused,unusedsymbols
+TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH))
+else ifneq ($(findstring gcc,$(notdir $(LD))),)
+# Pass ld options with Wl or Xlinker switches
+TF_LDFLAGS += -Wl,--fatal-warnings -O1
+TF_LDFLAGS += -Wl,--gc-sections
+ifeq ($(ENABLE_LTO),1)
+ ifeq (${ARCH},aarch64)
+ TF_LDFLAGS += -flto -fuse-linker-plugin
+ endif
+endif
+# GCC automatically adds fix-cortex-a53-843419 flag when used to link
+# which breaks some builds, so disable if errata fix is not explicitly enabled
+ifneq (${ERRATA_A53_843419},1)
+ TF_LDFLAGS += -mno-fix-cortex-a53-843419
+endif
+TF_LDFLAGS += -nostdlib
+TF_LDFLAGS += $(subst --,-Xlinker --,$(TF_LDFLAGS_$(ARCH)))
else
TF_LDFLAGS += --fatal-warnings -O1
TF_LDFLAGS += --gc-sections
-endif
TF_LDFLAGS += $(TF_LDFLAGS_$(ARCH))
+endif
DTC_FLAGS += -I dts -O dtb
DTC_CPPFLAGS += -nostdinc -Iinclude -undef -x assembler-with-cpp
@@ -406,7 +442,11 @@ endif
ifeq ($(ENABLE_PIE),1)
TF_CFLAGS += -fpie
- TF_LDFLAGS += -pie --no-dynamic-linker
+ ifneq ($(findstring gcc,$(notdir $(LD))),)
+ TF_LDFLAGS += -Wl,-pie -Wl,--no-dynamic-linker
+ else
+ TF_LDFLAGS += -pie --no-dynamic-linker
+ endif
else
PIE_FOUND := $(findstring --enable-default-pie,${GCC_V_OUTPUT})
ifneq ($(PIE_FOUND),)
@@ -624,6 +664,13 @@ SPTOOL ?= ${SPTOOLPATH}/sptool${BIN_EXT}
# Variables for use with ROMLIB
ROMLIBPATH ?= lib/romlib
+# Variable for use with Python
+PYTHON ?= python3
+
+# Variables for use with PRINT_MEMORY_MAP
+PRINT_MEMORY_MAP_PATH ?= tools/memory
+PRINT_MEMORY_MAP ?= ${PRINT_MEMORY_MAP_PATH}/print_memory_map.py
+
################################################################################
# Include BL specific makefiles
################################################################################
@@ -673,7 +720,6 @@ $(eval $(call assert_boolean,ENABLE_PMF))
$(eval $(call assert_boolean,ENABLE_PSCI_STAT))
$(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION))
$(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call assert_boolean,ENABLE_SPM))
$(eval $(call assert_boolean,ENABLE_SVE_FOR_NS))
$(eval $(call assert_boolean,ERROR_DEPRECATED))
$(eval $(call assert_boolean,FAULT_INJECTION_SUPPORT))
@@ -690,10 +736,12 @@ $(eval $(call assert_boolean,RAS_EXTENSION))
$(eval $(call assert_boolean,RESET_TO_BL31))
$(eval $(call assert_boolean,SAVE_KEYS))
$(eval $(call assert_boolean,SEPARATE_CODE_AND_RODATA))
+$(eval $(call assert_boolean,SEPARATE_NOBITS_REGION))
$(eval $(call assert_boolean,SPIN_ON_BL1_EXIT))
$(eval $(call assert_boolean,SPM_MM))
$(eval $(call assert_boolean,TRUSTED_BOARD_BOOT))
$(eval $(call assert_boolean,USE_COHERENT_MEM))
+$(eval $(call assert_boolean,USE_DEBUGFS))
$(eval $(call assert_boolean,USE_ROMLIB))
$(eval $(call assert_boolean,USE_TBBR_DEFS))
$(eval $(call assert_boolean,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -738,7 +786,6 @@ $(eval $(call add_define,ENABLE_PMF))
$(eval $(call add_define,ENABLE_PSCI_STAT))
$(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION))
$(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS))
-$(eval $(call add_define,ENABLE_SPM))
$(eval $(call add_define,ENABLE_SVE_FOR_NS))
$(eval $(call add_define,ERROR_DEPRECATED))
$(eval $(call add_define,FAULT_INJECTION_SUPPORT))
@@ -754,12 +801,14 @@ $(eval $(call add_define,PSCI_EXTENDED_STATE_ID))
$(eval $(call add_define,RAS_EXTENSION))
$(eval $(call add_define,RESET_TO_BL31))
$(eval $(call add_define,SEPARATE_CODE_AND_RODATA))
+$(eval $(call add_define,SEPARATE_NOBITS_REGION))
$(eval $(call add_define,RECLAIM_INIT_CODE))
$(eval $(call add_define,SPD_${SPD}))
$(eval $(call add_define,SPIN_ON_BL1_EXIT))
$(eval $(call add_define,SPM_MM))
$(eval $(call add_define,TRUSTED_BOARD_BOOT))
$(eval $(call add_define,USE_COHERENT_MEM))
+$(eval $(call add_define,USE_DEBUGFS))
$(eval $(call add_define,USE_ROMLIB))
$(eval $(call add_define,USE_TBBR_DEFS))
$(eval $(call add_define,WARMBOOT_ENABLE_DCACHE_EARLY))
@@ -796,7 +845,7 @@ endif
# Build targets
################################################################################
-.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs
+.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool sptool fip fwu_fip certtool dtbs memmap
.SUFFIXES:
all: msg_start
@@ -990,6 +1039,10 @@ ${SPTOOL}:
romlib.bin: libraries
${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all
+# Call print_memory_map tool
+memmap: all
+ ${Q}${PYTHON} $(PRINT_MEMORY_MAP) $(BUILD_PLAT)
+
cscope:
@echo " CSCOPE"
${Q}find ${CURDIR} -name "*.[chsS]" > cscope.files
@@ -1029,6 +1082,7 @@ help:
@echo " fiptool Build the Firmware Image Package (FIP) creation tool"
@echo " sptool Build the Secure Partition Package creation tool"
@echo " dtbs Build the Device Tree Blobs (if required for the platform)"
+ @echo " memmap Print the memory map of the built binaries"
@echo ""
@echo "Note: most build targets require PLAT to be set to a specific platform."
@echo ""
diff --git a/bl1/aarch64/bl1_entrypoint.S b/bl1/aarch64/bl1_entrypoint.S
index 855add347f..00f27184df 100644
--- a/bl1/aarch64/bl1_entrypoint.S
+++ b/bl1/aarch64/bl1_entrypoint.S
@@ -30,7 +30,8 @@ func bl1_entrypoint
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
_init_memory=1 \
_init_c_runtime=1 \
- _exception_vectors=bl1_exceptions
+ _exception_vectors=bl1_exceptions \
+ _pie_fixup_size=0
/* --------------------------------------------------------------------
* Perform BL1 setup
diff --git a/bl1/bl1.ld.S b/bl1/bl1.ld.S
index c4f6b99fc5..877af8e015 100644
--- a/bl1/bl1.ld.S
+++ b/bl1/bl1.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,7 @@ SECTIONS
.text . : {
__TEXT_START__ = .;
*bl1_entrypoint.o(.text*)
- *(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
__TEXT_END__ = .;
@@ -44,7 +44,7 @@ SECTIONS
.rodata . : {
__RODATA_START__ = .;
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -72,8 +72,8 @@ SECTIONS
ro . : {
__RO_START__ = .;
*bl1_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -114,7 +114,7 @@ SECTIONS
*/
.data . : ALIGN(16) {
__DATA_RAM_START__ = .;
- *(.data*)
+ *(SORT_BY_ALIGNMENT(.data*))
__DATA_RAM_END__ = .;
} >RAM AT>ROM
@@ -131,7 +131,7 @@ SECTIONS
*/
.bss : ALIGN(16) {
__BSS_START__ = .;
- *(.bss*)
+ *(SORT_BY_ALIGNMENT(.bss*))
*(COMMON)
__BSS_END__ = .;
} >RAM
diff --git a/bl2/aarch64/bl2_el3_entrypoint.S b/bl2/aarch64/bl2_el3_entrypoint.S
index 6fe2dd9233..f97121ef01 100644
--- a/bl2/aarch64/bl2_el3_entrypoint.S
+++ b/bl2/aarch64/bl2_el3_entrypoint.S
@@ -26,7 +26,8 @@ func bl2_entrypoint
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
_init_memory=1 \
_init_c_runtime=1 \
- _exception_vectors=bl2_el3_exceptions
+ _exception_vectors=bl2_el3_exceptions \
+ _pie_fixup_size=0
/* ---------------------------------------------
* Restore parameters of boot rom
diff --git a/bl2/bl2.ld.S b/bl2/bl2.ld.S
index 30cdf7d78a..6230562edb 100644
--- a/bl2/bl2.ld.S
+++ b/bl2/bl2.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,7 @@ SECTIONS
.text . : {
__TEXT_START__ = .;
*bl2_entrypoint.o(.text*)
- *(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
__TEXT_END__ = .;
@@ -44,7 +44,7 @@ SECTIONS
.rodata . : {
__RODATA_START__ = .;
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -59,8 +59,8 @@ SECTIONS
ro . : {
__RO_START__ = .;
*bl2_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -93,7 +93,7 @@ SECTIONS
*/
.data . : {
__DATA_START__ = .;
- *(.data*)
+ *(SORT_BY_ALIGNMENT(.data*))
__DATA_END__ = .;
} >RAM
diff --git a/bl2/bl2_el3.ld.S b/bl2/bl2_el3.ld.S
index 82b51a862f..dc398eb025 100644
--- a/bl2/bl2_el3.ld.S
+++ b/bl2/bl2_el3.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -44,7 +44,7 @@ SECTIONS
*bl2_el3_entrypoint.o(.text*)
*(.text.asm.*)
__TEXT_RESIDENT_END__ = .;
- *(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
__TEXT_END__ = .;
@@ -52,7 +52,7 @@ SECTIONS
.rodata . : {
__RODATA_START__ = .;
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -82,8 +82,8 @@ SECTIONS
*bl2_el3_entrypoint.o(.text*)
*(.text.asm.*)
__TEXT_RESIDENT_END__ = .;
- *(.text*)
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
/*
* Ensure 8-byte alignment for cpu_ops so that its fields are also
@@ -135,7 +135,7 @@ SECTIONS
*/
.data . : {
__DATA_RAM_START__ = .;
- *(.data*)
+ *(SORT_BY_ALIGNMENT(.data*))
__DATA_RAM_END__ = .;
} >RAM AT>ROM
diff --git a/bl2u/bl2u.ld.S b/bl2u/bl2u.ld.S
index 8d4984fbf8..8d257cee93 100644
--- a/bl2u/bl2u.ld.S
+++ b/bl2u/bl2u.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,7 +27,7 @@ SECTIONS
.text . : {
__TEXT_START__ = .;
*bl2u_entrypoint.o(.text*)
- *(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
__TEXT_END__ = .;
@@ -44,7 +44,7 @@ SECTIONS
.rodata . : {
__RODATA_START__ = .;
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.rodata*))
. = ALIGN(PAGE_SIZE);
__RODATA_END__ = .;
} >RAM
@@ -52,8 +52,8 @@ SECTIONS
ro . : {
__RO_START__ = .;
*bl2u_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
*(.vectors)
__RO_END_UNALIGNED__ = .;
@@ -80,7 +80,7 @@ SECTIONS
*/
.data . : {
__DATA_START__ = .;
- *(.data*)
+ *(SORT_BY_ALIGNMENT(.data*))
__DATA_END__ = .;
} >RAM
diff --git a/bl31/aarch64/bl31_entrypoint.S b/bl31/aarch64/bl31_entrypoint.S
index 1ad26e4fee..665a05e889 100644
--- a/bl31/aarch64/bl31_entrypoint.S
+++ b/bl31/aarch64/bl31_entrypoint.S
@@ -9,7 +9,7 @@
#include <arch.h>
#include <common/bl_common.h>
#include <el3_common_macros.S>
-#include <lib/pmf/pmf_asm_macros.S>
+#include <lib/pmf/aarch64/pmf_asm_macros.S>
#include <lib/runtime_instr.h>
#include <lib/xlat_tables/xlat_mmu_helpers.h>
@@ -32,17 +32,6 @@ func bl31_entrypoint
mov x22, x2
mov x23, x3
- /* --------------------------------------------------------------------
- * If PIE is enabled, fixup the Global descriptor Table and dynamic
- * relocations
- * --------------------------------------------------------------------
- */
-#if ENABLE_PIE
- mov_imm x0, BL31_BASE
- mov_imm x1, BL31_LIMIT
- bl fixup_gdt_reloc
-#endif /* ENABLE_PIE */
-
#if !RESET_TO_BL31
/* ---------------------------------------------------------------------
* For !RESET_TO_BL31 systems, only the primary CPU ever reaches
@@ -59,7 +48,8 @@ func bl31_entrypoint
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=1 \
- _exception_vectors=runtime_exceptions
+ _exception_vectors=runtime_exceptions \
+ _pie_fixup_size=BL31_LIMIT - BL31_BASE
#else
/* ---------------------------------------------------------------------
@@ -74,7 +64,8 @@ func bl31_entrypoint
_secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
_init_memory=1 \
_init_c_runtime=1 \
- _exception_vectors=runtime_exceptions
+ _exception_vectors=runtime_exceptions \
+ _pie_fixup_size=BL31_LIMIT - BL31_BASE
/* ---------------------------------------------------------------------
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -174,7 +165,8 @@ func bl31_warm_entrypoint
_secondary_cold_boot=0 \
_init_memory=0 \
_init_c_runtime=0 \
- _exception_vectors=runtime_exceptions
+ _exception_vectors=runtime_exceptions \
+ _pie_fixup_size=0
/*
* We're about to enable MMU and participate in PSCI state coordination.
diff --git a/bl31/aarch64/ea_delegate.S b/bl31/aarch64/ea_delegate.S
index 3cc4d56a3f..1d28d5e0fb 100644
--- a/bl31/aarch64/ea_delegate.S
+++ b/bl31/aarch64/ea_delegate.S
@@ -102,9 +102,11 @@ func enter_lower_el_sync_ea
/* 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
+ bl delegate_sync_ea
+ /* el3_exit assumes SP_EL0 on entry */
+ msr spsel, #MODE_SP_EL0
+ b el3_exit
2:
ldp x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
ldp x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
@@ -146,8 +148,11 @@ func enter_lower_el_async_ea
/* 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
+ bl delegate_async_ea
+
+ /* el3_exit assumes SP_EL0 on entry */
+ msr spsel, #MODE_SP_EL0
+ b el3_exit
endfunc enter_lower_el_async_ea
diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S
index c7d587cb0d..42227f0f38 100644
--- a/bl31/bl31.ld.S
+++ b/bl31/bl31.ld.S
@@ -15,6 +15,11 @@ ENTRY(bl31_entrypoint)
MEMORY {
RAM (rwx): ORIGIN = BL31_BASE, LENGTH = BL31_LIMIT - BL31_BASE
+#if SEPARATE_NOBITS_REGION
+ NOBITS (rw!a): ORIGIN = BL31_NOBITS_BASE, LENGTH = BL31_NOBITS_LIMIT - BL31_NOBITS_BASE
+#else
+#define NOBITS RAM
+#endif
}
#ifdef PLAT_EXTRA_LD_SCRIPT
@@ -33,7 +38,7 @@ SECTIONS
.text . : {
__TEXT_START__ = .;
*bl31_entrypoint.o(.text*)
- *(.text*)
+ *(SORT_BY_ALIGNMENT(.text*))
*(.vectors)
. = ALIGN(PAGE_SIZE);
__TEXT_END__ = .;
@@ -41,7 +46,7 @@ SECTIONS
.rodata . : {
__RODATA_START__ = .;
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -87,8 +92,8 @@ SECTIONS
ro . : {
__RO_START__ = .;
*bl31_entrypoint.o(.text*)
- *(.text*)
- *(.rodata*)
+ *(SORT_BY_ALIGNMENT(.text*))
+ *(SORT_BY_ALIGNMENT(.rodata*))
/* Ensure 8-byte alignment for descriptors and ensure inclusion */
. = ALIGN(8);
@@ -142,7 +147,7 @@ SECTIONS
ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__,
"cpu_ops not defined for this platform.")
-#if ENABLE_SPM
+#if SPM_MM
#ifndef SPM_SHIM_EXCEPTIONS_VMA
#define SPM_SHIM_EXCEPTIONS_VMA RAM
#endif
@@ -179,7 +184,7 @@ SECTIONS
*/
.data . : {
__DATA_START__ = .;
- *(.data*)
+ *(SORT_BY_ALIGNMENT(.data*))
__DATA_END__ = .;
} >RAM
@@ -198,11 +203,28 @@ SECTIONS
ASSERT(. <= BL31_PROGBITS_LIMIT, "BL31 progbits has exceeded its limit.")
#endif
+#if SEPARATE_NOBITS_REGION
+ /*
+ * Define a linker symbol to mark end of the RW memory area for this
+ * image.
+ */
+ __RW_END__ = .;
+ __BL31_END__ = .;
+
+ ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+
+ . = BL31_NOBITS_BASE;
+ ASSERT(. == ALIGN(PAGE_SIZE),
+ "BL31 NOBITS base address is not aligned on a page boundary.")
+
+ __NOBITS_START__ = .;
+#endif
+
stacks (NOLOAD) : {
__STACKS_START__ = .;
*(tzfw_normal_stacks)
__STACKS_END__ = .;
- } >RAM
+ } >NOBITS
/*
* The .bss section gets initialised to 0 at runtime.
@@ -211,7 +233,7 @@ SECTIONS
*/
.bss (NOLOAD) : ALIGN(16) {
__BSS_START__ = .;
- *(.bss*)
+ *(SORT_BY_ALIGNMENT(.bss*))
*(COMMON)
#if !USE_COHERENT_MEM
/*
@@ -262,7 +284,7 @@ SECTIONS
__PMF_TIMESTAMP_END__ = .;
#endif /* ENABLE_PMF */
__BSS_END__ = .;
- } >RAM
+ } >NOBITS
/*
* The xlat_table section is for full, aligned page tables (4K).
@@ -272,7 +294,7 @@ SECTIONS
*/
xlat_table (NOLOAD) : {
*(xlat_table)
- } >RAM
+ } >NOBITS
#if USE_COHERENT_MEM
/*
@@ -298,9 +320,18 @@ SECTIONS
*/
. = ALIGN(PAGE_SIZE);
__COHERENT_RAM_END__ = .;
- } >RAM
+ } >NOBITS
#endif
+#if SEPARATE_NOBITS_REGION
+ /*
+ * Define a linker symbol to mark end of the NOBITS memory area for this
+ * image.
+ */
+ __NOBITS_END__ = .;
+
+ ASSERT(. <= BL31_NOBITS_LIMIT, "BL31 NOBITS region has exceeded its limit.")
+#else
/*
* Define a linker symbol to mark end of the RW memory area for this
* image.
@@ -309,4 +340,5 @@ SECTIONS
__BL31_END__ = .;
ASSERT(. <= BL31_LIMIT, "BL31 image has exceeded its limit.")
+#endif
}
diff --git a/bl31/bl31.mk b/bl31/bl31.mk
index c9ba926c59..58909e84a2 100644
--- a/bl31/bl31.mk
+++ b/bl31/bl31.mk
@@ -5,22 +5,17 @@
#
################################################################################
-# Include SPM Makefile
+# Include Makefile for the SPM-MM implementation
################################################################################
-ifeq (${ENABLE_SPM},1)
- ifeq (${SPM_MM},1)
- ifeq (${EL3_EXCEPTION_HANDLING},0)
- $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support)
- endif
- $(info Including makefile of SPM based on MM)
- include services/std_svc/spm_mm/spm.mk
+ifeq (${SPM_MM},1)
+ ifeq (${EL3_EXCEPTION_HANDLING},0)
+ $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support)
else
- $(info Including SPM makefile)
- include services/std_svc/spm/spm.mk
+ $(info Including SPM Management Mode (MM) makefile)
+ include services/std_svc/spm_mm/spm_mm.mk
endif
endif
-
include lib/psci/psci_lib.mk
BL31_SOURCES += bl31/bl31_main.c \
@@ -43,6 +38,11 @@ ifeq (${ENABLE_PMF}, 1)
BL31_SOURCES += lib/pmf/pmf_main.c
endif
+include lib/debugfs/debugfs.mk
+ifeq (${USE_DEBUGFS},1)
+ BL31_SOURCES += $(DEBUGFS_SRCS)
+endif
+
ifeq (${EL3_EXCEPTION_HANDLING},1)
BL31_SOURCES += bl31/ehf.c
endif
diff --git a/bl32/sp_min/aarch32/entrypoint.S b/bl32/sp_min/aarch32/entrypoint.S
index 0a684754ce..f3a1e440b7 100644
--- a/bl32/sp_min/aarch32/entrypoint.S
+++ b/bl32/sp_min/aarch32/entrypoint.S
@@ -10,6 +10,9 @@
#include <common/runtime_svc.h>
#include <context.h>
#include <el3_common_macros.S>
+#include <lib/el3_runtime/cpu_data.h>
+#include <lib/pmf/aarch32/pmf_asm_macros.S>
+#include <lib/runtime_instr.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
#include <smccc_helpers.h>
#include <smccc_macros.S>
@@ -164,6 +167,20 @@ func sp_min_handle_smc
/* On SMC entry, `sp` points to `smc_ctx_t`. Save `lr`. */
str lr, [sp, #SMC_CTX_LR_MON]
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ /*
+ * Read the timestamp value and store it on top of the C runtime stack.
+ * The value will be saved to the per-cpu data once the C stack is
+ * available, as a valid stack is needed to call _cpu_data()
+ */
+ strd r0, r1, [sp, #SMC_CTX_GPREG_R0]
+ ldcopr16 r0, r1, CNTPCT_64
+ ldr lr, [sp, #SMC_CTX_SP_MON]
+ strd r0, r1, [lr, #-8]!
+ str lr, [sp, #SMC_CTX_SP_MON]
+ ldrd r0, r1, [sp, #SMC_CTX_GPREG_R0]
+#endif
+
smccc_save_gp_mode_regs
clrex_on_monitor_entry
@@ -175,6 +192,23 @@ func sp_min_handle_smc
mov r2, sp /* handle */
ldr sp, [r2, #SMC_CTX_SP_MON]
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ /* Save handle to a callee saved register */
+ mov r6, r2
+
+ /*
+ * Restore the timestamp value and store it in per-cpu data. The value
+ * will be extracted from per-cpu data by the C level SMC handler and
+ * saved to the PMF timestamp region.
+ */
+ ldrd r4, r5, [sp], #8
+ bl _cpu_data
+ strd r4, r5, [r0, #CPU_DATA_PMF_TS0_OFFSET]
+
+ /* Restore handle */
+ mov r2, r6
+#endif
+
ldr r0, [r2, #SMC_CTX_SCR]
and r3, r0, #SCR_NS_BIT /* flags */
@@ -239,6 +273,16 @@ endfunc sp_min_handle_fiq
* The Warm boot entrypoint for SP_MIN.
*/
func sp_min_warm_entrypoint
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ /*
+ * This timestamp update happens with cache off. The next
+ * timestamp collection will need to do cache maintenance prior
+ * to timestamp update.
+ */
+ pmf_calc_timestamp_addr rt_instr_svc, RT_INSTR_EXIT_HW_LOW_PWR
+ ldcopr16 r2, r3, CNTPCT_64
+ strd r2, r3, [r0]
+#endif
/*
* On the warm boot path, most of the EL3 initialisations performed by
* 'el3_entrypoint_common' must be skipped:
@@ -295,6 +339,30 @@ func sp_min_warm_entrypoint
bl smc_get_next_ctx
/* r0 points to `smc_ctx_t` */
/* The PSCI cpu_context registers have been copied to `smc_ctx_t` */
+
+#if ENABLE_RUNTIME_INSTRUMENTATION
+ /* Save smc_ctx_t */
+ mov r5, r0
+
+ pmf_calc_timestamp_addr rt_instr_svc, RT_INSTR_EXIT_PSCI
+ mov r4, r0
+
+ /*
+ * Invalidate before updating timestamp to ensure previous timestamp
+ * updates on the same cache line with caches disabled are properly
+ * seen by the same core. Without the cache invalidate, the core might
+ * write into a stale cache line.
+ */
+ mov r1, #PMF_TS_SIZE
+ bl inv_dcache_range
+
+ ldcopr16 r0, r1, CNTPCT_64
+ strd r0, r1, [r4]
+
+ /* Restore smc_ctx_t */
+ mov r0, r5
+#endif
+
b sp_min_exit
endfunc sp_min_warm_entrypoint
diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S
index 4559903bf8..6997a7fdbd 100644
--- a/bl32/sp_min/sp_min.ld.S
+++ b/bl32/sp_min/sp_min.ld.S
@@ -55,6 +55,14 @@ SECTIONS
KEEP(*(rt_svc_descs))
__RT_SVC_DESCS_END__ = .;
+#if ENABLE_PMF
+ /* Ensure 4-byte alignment for descriptors and ensure inclusion */
+ . = ALIGN(4);
+ __PMF_SVC_DESCS_START__ = .;
+ KEEP(*(pmf_svc_descs))
+ __PMF_SVC_DESCS_END__ = .;
+#endif /* ENABLE_PMF */
+
/*
* Ensure 4-byte alignment for cpu_ops so that its fields are also
* aligned. Also ensure cpu_ops inclusion.
diff --git a/bl32/sp_min/sp_min_main.c b/bl32/sp_min/sp_min_main.c
index f39e33b6b5..f050160f3c 100644
--- a/bl32/sp_min/sp_min_main.c
+++ b/bl32/sp_min/sp_min_main.c
@@ -19,7 +19,9 @@
#include <context.h>
#include <drivers/console.h>
#include <lib/el3_runtime/context_mgmt.h>
+#include <lib/pmf/pmf.h>
#include <lib/psci/psci.h>
+#include <lib/runtime_instr.h>
#include <lib/utils.h>
#include <plat/common/platform.h>
#include <platform_sp_min.h>
@@ -28,6 +30,11 @@
#include "sp_min_private.h"
+#if ENABLE_RUNTIME_INSTRUMENTATION
+PMF_REGISTER_SERVICE_SMC(rt_instr_svc, PMF_RT_INSTR_SVC_ID,
+ RT_INSTR_TOTAL_IDS, PMF_STORE_ENABLE)
+#endif
+
/* Pointers to per-core cpu contexts */
static void *sp_min_cpu_ctx_ptr[PLATFORM_CORE_COUNT];
diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst
index 68f84ea57c..d9d7f84fdd 100644
--- a/docs/about/maintainers.rst
+++ b/docs/about/maintainers.rst
@@ -17,10 +17,18 @@ Main maintainers
:G: `sandrine-bailleux-arm`_
:M: Alexei Fedorov <alexei.fedorov@arm.com>
:G: `AlexeiFedorov`_
-:M: Paul Beesley <paul.beesley@arm.com>
-:G: `pbeesley-arm`_
:M: György Szing <gyorgy.szing@arm.com>
:G: `gyuri-szing`_
+:M: Manish Pandey <manish.pandey2@arm.com>
+:G: `manish-pandey-arm`_
+:M: Mark Dykes <mark.dykes@arm.com>
+:G: `mardyk01`_
+:M: Olivier Deprez <olivier.deprez@arm.com>
+:G: `odeprez`_
+:M: Bipin Ravi <bipin.ravi@arm.com>
+:G: `bipinravi-arm`_
+:M: Joanna Farley <joanna.farley@arm.com>
+:G: `joannafarley-arm`_
Allwinner ARMv8 platform port
-----------------------------
@@ -300,7 +308,6 @@ Xilinx platform port
.. _mtk09422: https://github.com/mtk09422
.. _niej: https://github.com/niej
.. _npoushin: https://github.com/npoushin
-.. _pbeesley-arm: https://github.com/pbeesley-arm
.. _qoriq-open-source: https://github.com/qoriq-open-source
.. _remi-triplefault: https://github.com/repk
.. _rockchip-linux: https://github.com/rockchip-linux
@@ -314,3 +321,8 @@ Xilinx platform port
.. _TonyXie06: https://github.com/TonyXie06
.. _vwadekar: https://github.com/vwadekar
.. _Yann-lms: https://github.com/Yann-lms
+.. _manish-pandey-arm: https://github.com/manish-pandey-arm
+.. _mardyk01: https://github.com/mardyk01
+.. _odeprez: https://github.com/odeprez
+.. _bipinravi-arm: https://github.com/bipinravi-arm
+.. _joannafarley-arm: https://github.com/joannafarley-arm
diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst
new file mode 100644
index 0000000000..3d7d5094d2
--- /dev/null
+++ b/docs/change-log-upcoming.rst
@@ -0,0 +1,145 @@
+Change Log for Upcoming Release
+===============================
+
+This document contains a summary of the new features, changes, fixes and known
+issues to be included in the upcoming release of Trusted Firmware-A. The contents
+of this file will be moved to the collective change-log.rst file at the time of
+release code freeze.
+
+
+Upcoming Release Version 2.3
+----------------------------
+
+**Trusted Firmware-A Contributors,
+Please log all relevant new features, changes, fixes, and known issues for the
+upcoming release. For the CPU support, drivers, and tools sections please preface
+the log description with the relevant key word, example: "<CPU>: <CPU Support
+addition>". Use the RST format convention already used in the Change Log.**
+
+New Features
+^^^^^^^^^^^^
+
+- Arm Architecture
+ - Example: "Add support for Branch Target Identification (BTI)"
+
+- Build System
+ - Example: "Add support for default stack-protector flag"
+
+- CPU Support
+ - Example: "cortex-a55: Workaround for erratum 1221012"
+
+- Drivers
+ - Example: "console: Allow the console to register multiple times"
+
+- Libraries
+ - Example: "Introduce BTI support in Library at ROM (romlib)"
+
+- New Platforms Support
+ - Example: "qemu/qemu_sbsa: New platform support added for QEMU SBSA platform"
+
+- Platforms
+ - Example: "arm/common: Introduce wrapper functions to setup secure watchdog"
+
+- PSCI
+ - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``"
+
+- Security
+ - Example: "UBSAN support and handlers"
+
+- Tools
+ - Example: "fiptool: Add support to build fiptool on Windows."
+
+
+Changed
+^^^^^^^
+
+- Arm Architecture
+ - Example: "Refactor ARMv8.3 Pointer Authentication support code"
+
+- BL-Specific
+ - Example: "BL2: Invalidate dcache build option for BL2 entry at EL3"
+
+- Boot Flow
+ - Example: "Add helper to parse BL31 parameters (both versions)"
+
+- Drivers
+ - Example: "gicv3: Prevent pending G1S interrupt from becoming G0 interrupt"
+
+- Platforms
+ - Example: "arm/common: Shorten the Firmware Update (FWU) process"
+
+- PSCI
+ - Example: "PSCI: Lookup list of parent nodes to lock only once"
+
+- Secure Partition Manager (SPM)
+ - Example: "Move shim layer to TTBR1_EL1"
+
+- Security
+ - Example: "Refactor SPSR initialisation code"
+
+- Tools
+ - Example: "cert_create: Remove RSA PKCS#1 v1.5 support"
+
+
+Resolved Issues
+^^^^^^^^^^^^^^^
+
+- Arm Architecture
+ - Example: "Fix restoration of PAuth context"
+
+- BL-Specific
+ - Example: "Fix BL31 crash reporting on AArch64 only platforms"
+
+- Build System
+ - Example: "Remove several warnings reported with W=2 and W=1"
+
+- Code Quality
+ - Example: "Unify type of "cpu_idx" across PSCI module"
+
+- CPU Support
+ - Example: "cortex-a12: Fix MIDR mask"
+
+- Drivers
+ - Example: "scmi: Fix wrong payload length"
+
+- Library Code
+ - Example: "libc: Fix memchr implementation"
+
+- Platforms
+ - Example: "rpi: rpi3: Fix compilation error when stack protector is enabled"
+
+- Security
+ - Example: "AArch32: Disable Secure Cycle Counter"
+
+Deprecations
+^^^^^^^^^^^^
+
+- Common Code
+ - Example: "Remove MULTI_CONSOLE_API flag and references to it"
+
+- Drivers
+ - Example: "console: Remove deprecated finish_console_register"
+
+- Secure Partition Manager (SPM):
+ - Example: "Prototype SPCI-based SPM (services/std_svc/spm) will be replaced
+ with alternative methods of secure partitioning support."
+
+Known Issues
+^^^^^^^^^^^^
+
+- Build System
+ - dtb: DTB creation not supported when building on a Windows host.
+
+ This step in the build process is skipped when running on a Windows host. A
+ known issue from the 1.6 release.
+
+- Platforms
+ - arm/juno: System suspend from Linux does not function as documented in the
+ user guide
+
+ Following the instructions provided in the user guide document does not
+ result in the platform entering system suspend state as expected. A message
+ relating to the hdlcd driver failing to suspend will be emitted on the
+ Linux terminal.
+
+ - mediatek/mt6795: This platform does not build in this release
diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst
index 2d58586b99..01bc04d71c 100644
--- a/docs/components/arm-sip-service.rst
+++ b/docs/components/arm-sip-service.rst
@@ -17,6 +17,7 @@ The Arm SiP implementation offers the following services:
- Performance Measurement Framework (PMF)
- Execution State Switching service
+- DebugFS interface
Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header
file.
@@ -87,6 +88,346 @@ Instead, execution starts at the supplied entry point, with the CPU registers 0
and 1 populated with the supplied *Cookie hi* and *Cookie lo* values,
respectively.
+DebugFS interface
+-----------------
+
+The optional DebugFS interface is accessed through an SMC SiP service. Refer
+to the component documentation for details.
+
+String parameters are passed through a shared buffer using a specific union:
+
+.. code:: c
+
+ union debugfs_parms {
+ struct {
+ char fname[MAX_PATH_LEN];
+ } open;
+
+ struct mount {
+ char srv[MAX_PATH_LEN];
+ char where[MAX_PATH_LEN];
+ char spec[MAX_PATH_LEN];
+ } mount;
+
+ struct {
+ char path[MAX_PATH_LEN];
+ dir_t dir;
+ } stat;
+
+ struct {
+ char oldpath[MAX_PATH_LEN];
+ char newpath[MAX_PATH_LEN];
+ } bind;
+ };
+
+Format of the dir_t structure as such:
+
+.. code:: c
+
+ typedef struct {
+ char name[NAMELEN];
+ long length;
+ unsigned char mode;
+ unsigned char index;
+ unsigned char dev;
+ qid_t qid;
+ } dir_t;
+
+
+* Identifiers
+
+======================== =============================================
+SMC_OK 0
+SMC_UNK -1
+DEBUGFS_E_INVALID_PARAMS -2
+======================== =============================================
+
+======================== =============================================
+MOUNT 0
+CREATE 1
+OPEN 2
+CLOSE 3
+READ 4
+WRITE 5
+SEEK 6
+BIND 7
+STAT 8
+INIT 10
+VERSION 11
+======================== =============================================
+
+MOUNT
+~~~~~
+
+Description
+^^^^^^^^^^^
+This operation mounts a blob of data pointed to by path stored in `src`, at
+filesystem location pointed to by path stored in `where`, using driver pointed
+to by path in `spec`.
+
+Parameters
+^^^^^^^^^^
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``MOUNT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed
+=============== ==========================================================
+
+OPEN
+~~~~
+
+Description
+^^^^^^^^^^^
+This operation opens the file path pointed to by `fname`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``OPEN``
+uint32_t mode
+======== ============================================================
+
+mode can be one of:
+
+.. code:: c
+
+ enum mode {
+ O_READ = 1 << 0,
+ O_WRITE = 1 << 1,
+ O_RDWR = 1 << 2,
+ O_BIND = 1 << 3,
+ O_DIR = 1 << 4,
+ O_STAT = 1 << 5
+ };
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed
+
+uint32_t w1: file descriptor id on success.
+=============== ==========================================================
+
+CLOSE
+~~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation closes a file described by a file descriptor obtained by a
+previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``CLOSE``
+uint32_t File descriptor id returned by OPEN
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed
+=============== ==========================================================
+
+READ
+~~~~
+
+Description
+^^^^^^^^^^^
+
+This operation reads a number of bytes from a file descriptor obtained by
+a previous call to OPEN.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``READ``
+uint32_t File descriptor id returned by OPEN
+uint32_t Number of bytes to read
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+On success, the read data is retrieved from the shared buffer after the
+operation.
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed
+
+uint32_t w1: number of bytes read on success.
+=============== ==========================================================
+
+SEEK
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Move file pointer for file described by given `file descriptor` of given
+`offset` related to `whence`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``SEEK``
+uint32_t File descriptor id returned by OPEN
+sint32_t offset in the file relative to whence
+uint32_t whence
+======== ============================================================
+
+whence can be one of:
+
+========= ============================================================
+KSEEK_SET 0
+KSEEK_CUR 1
+KSEEK_END 2
+========= ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed
+=============== ==========================================================
+
+BIND
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Create a link from `oldpath` to `newpath`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``BIND``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed
+=============== ==========================================================
+
+STAT
+~~~~
+
+Description
+^^^^^^^^^^^
+
+Perform a stat operation on provided file `name` and returns the directory
+entry statistics into `dir`.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``STAT``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ==========================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed
+=============== ==========================================================
+
+INIT
+~~~~
+
+Description
+^^^^^^^^^^^
+Initial call to setup the shared exchange buffer. Notice if successful once,
+subsequent calls fail after a first initialization. The caller maps the same
+page frame in its virtual space and uses this buffer to exchange string
+parameters with filesystem primitives.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``INIT``
+uint64_t Physical address of the shared buffer.
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == DEBUGFS_E_INVALID_PARAMS if already initialized,
+ or internal error occurred.
+=============== ======================================================
+
+VERSION
+~~~~~~~
+
+Description
+^^^^^^^^^^^
+Returns the debugfs interface version if implemented in TF-A.
+
+Parameters
+^^^^^^^^^^
+
+======== ============================================================
+uint32_t FunctionID (0x82000030 / 0xC2000030)
+uint32_t ``VERSION``
+======== ============================================================
+
+Return values
+^^^^^^^^^^^^^
+
+=============== ======================================================
+int32_t w0 == SMC_OK on success
+
+ w0 == SMC_UNK if interface is not implemented
+
+uint32_t w1: On success, debugfs interface version, 32 bits
+ value with major version number in upper 16 bits and
+ minor version in lower 16 bits.
+=============== ======================================================
+
+* CREATE(1) and WRITE (5) command identifiers are unimplemented and
+ return `SMC_UNK`.
+
--------------
*Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.*
diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst
new file mode 100644
index 0000000000..06916f3d97
--- /dev/null
+++ b/docs/components/debugfs-design.rst
@@ -0,0 +1,132 @@
+========
+Debug FS
+========
+
+.. contents::
+
+Overview
+--------
+
+The *DebugFS* feature is primarily aimed at exposing firmware debug data to
+higher SW layers such as a non-secure component. Such component can be the
+TFTF test payload or a Linux kernel module.
+
+Virtual filesystem
+------------------
+
+The core functionality lies in a virtual file system based on a 9p file server
+interface (`Notes on the Plan 9 Kernel Source`_). The implementation permits
+exposing virtual files, firmware drivers, and file blobs.
+
+Namespace
+~~~~~~~~~
+
+Two namespaces are exposed:
+
+ - # is used as root for drivers (e.g. #t0 is the first uart)
+ - / is used as root for virtual "files" (e.g. /fip, or /dev/uart)
+
+9p interface
+~~~~~~~~~~~~
+
+The associated primitives are:
+
+- Unix-like:
+
+ - open(): create a file descriptor that acts as a handle to the file passed as
+ an argument.
+ - close(): close the file descriptor created by open().
+ - read(): read from a file to a buffer.
+ - write(): write from a buffer to a file.
+ - seek(): set the file position indicator of a file descriptor either to a
+ relative or an absolute offset.
+ - stat(): get information about a file (type, mode, size, ...).
+
+.. code:: c
+
+ int open(const char *name, int flags);
+ int close(int fd);
+ int read(int fd, void *buf, int n);
+ int write(int fd, void *buf, int n);
+ int seek(int fd, long off, int whence);
+ int stat(char *path, dir_t *dir);
+
+- Specific primitives :
+
+ - mount(): create a link between a driver and spec.
+ - create(): create a file in a specific location.
+ - bind(): expose the content of a directory to another directory.
+
+.. code:: c
+
+ int mount(char *srv, char *mnt, char *spec);
+ int create(const char *name, int flags);
+ int bind(char *path, char *where);
+
+This interface is embedded into the BL31 run-time payload when selected by build
+options. The interface multiplexes drivers or emulated "files":
+
+- Debug data can be partitioned into different virtual files e.g. expose PMF
+ measurements through a file, and internal firmware state counters through
+ another file.
+- This permits direct access to a firmware driver, mainly for test purposes
+ (e.g. a hardware device that may not be accessible to non-privileged/
+ non-secure layers, or for which no support exists in the NS side).
+
+SMC interface
+-------------
+
+The communication with the 9p layer in BL31 is made through an SMC conduit
+(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS shared
+buffer is used to pass path string parameters, or e.g. to exchange data on a
+read operation. Refer to `ARM SiP Services`_ for a description of the SMC
+interface.
+
+Security considerations
+-----------------------
+
+- Due to the nature of the exposed data, the feature is considered experimental
+ and importantly **shall only be used in debug builds**.
+- Several primitive imply string manipulations and usage of string formats.
+- Special care is taken with the shared buffer to avoid TOCTOU attacks.
+
+Limitations
+-----------
+
+- In order to setup the shared buffer, the component consuming the interface
+ needs to allocate a physical page frame and transmit its address.
+- In order to map the shared buffer, BL31 requires enabling the dynamic xlat
+ table option.
+- Data exchange is limited by the shared buffer length. A large read operation
+ might be split into multiple read operations of smaller chunks.
+- On concurrent access, a spinlock is implemented in the BL31 service to protect
+ the internal work buffer, and re-entrancy into the filesystem layers.
+- Notice, a physical device driver if exposed by the firmware may conflict with
+ the higher level OS if the latter implements its own driver for the same
+ physical device.
+
+Applications
+------------
+
+The SMC interface is accessible from an NS environment, that is:
+
+- a test payload, bootloader or hypervisor running at NS-EL2
+- a Linux kernel driver running at NS-EL1
+- a Linux userspace application through the kernel driver
+
+References
+----------
+
+.. [#] `SMC Calling Convention PDD`_
+.. [#] `Notes on the Plan 9 Kernel Source`_
+.. [#] `Linux 9p remote filesystem protocol`_
+.. [#] `ARM SiP Services`_
+
+--------------
+
+*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.*
+
+.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/
+.. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf
+.. _Linux 9p remote filesystem protocol: https://www.kernel.org/doc/Documentation/filesystems/9p.txt
+.. _ARM SiP Services: arm-sip-service.rst
diff --git a/docs/components/secure-partition-manager-design.rst b/docs/components/secure-partition-manager-design.rst
index de0792d15e..9aba954505 100644
--- a/docs/components/secure-partition-manager-design.rst
+++ b/docs/components/secure-partition-manager-design.rst
@@ -160,7 +160,7 @@ are implemented.
Partition.
- ``plat_get_secure_partition_boot_info()`` returns a
- ``secure_partition_boot_info_t`` struct that is populated by the platform
+ ``spm_mm_boot_info_t`` struct that is populated by the platform
with information about the memory map of the Secure Partition.
For an example of all the changes in context, you may refer to commit
@@ -308,8 +308,8 @@ allows the Secure Partition to:
Miscellaneous interfaces
------------------------
-``SPM_VERSION_AARCH32``
-^^^^^^^^^^^^^^^^^^^^^^^
+``SPM_MM_VERSION_AARCH32``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description
@@ -369,7 +369,7 @@ Secure Partition Initialisation
The SPM is responsible for initialising the architectural execution context to
enable initialisation of a service in S-EL0. The responsibilities of the SPM are
listed below. At the end of initialisation, the partition issues a
-``SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
+``MM_SP_EVENT_COMPLETE_AARCH64`` call (described later) to signal readiness for
handling requests for services implemented by the Secure Partition. The
initialisation event is executed as a Fast Call.
@@ -488,12 +488,12 @@ Runtime Event Delegation
The SPM receives requests for Secure Partition services through a synchronous
invocation (i.e. a SMC from the Non-secure world). These requests are delegated
to the partition by programming a return from the last
-``SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
+``MM_SP_EVENT_COMPLETE_AARCH64`` call received from the partition. The last call
was made to signal either completion of Secure Partition initialisation or
completion of a partition service request.
-``SP_EVENT_COMPLETE_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_EVENT_COMPLETE_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description
@@ -569,7 +569,7 @@ completion of a partition service request.
- Caller responsibilities
- A Secure Partition must only call ``SP_EVENT_COMPLETE_AARCH64`` to signal
+ A Secure Partition must only call ``MM_SP_EVENT_COMPLETE_AARCH64`` to signal
completion of a request that was delegated to it by the SPM.
- Callee responsibilities
@@ -613,18 +613,19 @@ data and code) will be known only when the file is loaded into memory.
In this case, the Secure Partition needs a way to change the access permissions
of its memory regions. The SPM provides this feature through the
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is available
-to the Secure Partition during a specific time window: from the first entry into
-the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that signals the
-Secure Partition has finished its initialisation. Once the initialisation is
-complete, the SPM does not allow changes to the memory attributes.
+``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64`` SVC interface. This interface is
+available to the Secure Partition during a specific time window: from the first
+entry into the Secure Partition up to the first ``SP_EVENT_COMPLETE`` call that
+signals the Secure Partition has finished its initialisation. Once the
+initialisation is complete, the SPM does not allow changes to the memory
+attributes.
This section describes the standard SVC interface that is implemented by the SPM
to determine and change permission attributes of memory regions that belong to a
Secure Partition.
-``SP_MEMORY_ATTRIBUTES_GET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description
@@ -673,7 +674,7 @@ Secure Partition.
- ``NOT_SUPPORTED`` : The SPM does not support retrieval of attributes of
any memory page that is accessible by the Secure Partition, or the
function was called from the Non-secure world. Also returned if it is
- used after ``SP_EVENT_COMPLETE_AARCH64``.
+ used after ``MM_SP_EVENT_COMPLETE_AARCH64``.
See `Error Codes`_ for integer values that are associated with each return
code.
@@ -696,8 +697,8 @@ Secure Partition.
The SPM must not return the memory access controls for a page of memory that
is not accessible from a Secure Partition.
-``SP_MEMORY_ATTRIBUTES_SET_AARCH64``
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+``MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64``
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Description
@@ -762,7 +763,7 @@ Secure Partition.
- ``NOT_SUPPORTED``: The SPM does not permit change of attributes of any
memory region that is accessible by the Secure Partition. Function was
called from the Non-secure world. Also returned if it is used after
- ``SP_EVENT_COMPLETE_AARCH64``.
+ ``MM_SP_EVENT_COMPLETE_AARCH64``.
See `Error Codes`_ for integer values that are associated with each return
code.
@@ -776,8 +777,8 @@ Secure Partition.
currently supported.
This function is only available at boot time. This interface is revoked after
- the Secure Partition sends the first ``SP_EVENT_COMPLETE_AARCH64`` to signal
- that it is initialised and ready to receive run-time requests.
+ the Secure Partition sends the first ``MM_SP_EVENT_COMPLETE_AARCH64`` to
+ signal that it is initialised and ready to receive run-time requests.
- Caller responsibilities
diff --git a/docs/design/cpu-specific-build-macros.rst b/docs/design/cpu-specific-build-macros.rst
index 891703bf01..7fa027f423 100644
--- a/docs/design/cpu-specific-build-macros.rst
+++ b/docs/design/cpu-specific-build-macros.rst
@@ -227,6 +227,12 @@ For Cortex-A76, the following errata build flags are defined :
- ``ERRATA_A76_1275112``: This applies errata 1275112 workaround to Cortex-A76
CPU. This needs to be enabled only for revision <= r3p0 of the CPU.
+For Hercules, the following errata build flags are defined :
+
+- ``ERRATA_HERCULES_1688305``: This applies errata 1688305 workaround to
+ Hercules CPU. This needs to be enabled only for revision r0p0 - r1p0 of
+ the CPU.
+
For Neoverse N1, the following errata build flags are defined :
- ``ERRATA_N1_1073348``: This applies errata 1073348 workaround to Neoverse-N1
diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst
index cae94b5d83..5fc1335b37 100644
--- a/docs/design/firmware-design.rst
+++ b/docs/design/firmware-design.rst
@@ -1500,6 +1500,11 @@ sections then the resulting binary file would contain zero bytes in place of
this NOBITS section, making the image unnecessarily bigger. Smaller images
allow faster loading from the FIP to the main memory.
+For BL31, a platform can specify an alternate location for NOBITS sections
+(other than immediately following PROGBITS sections) by setting
+``SEPARATE_NOBITS_REGION`` to 1 and defining ``BL31_NOBITS_BASE`` and
+``BL31_NOBITS_LIMIT``.
+
Linker scripts and symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index fded1e0c92..d7bb0449e4 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -196,6 +196,10 @@ Common build options
builds, but this behaviour can be overridden in each platform's Makefile or
in the build command line.
+- ``ENABLE_LTO``: Boolean option to enable Link Time Optimization (LTO)
+ support in GCC for TF-A. This option is currently only supported for
+ AArch64. Default is 0.
+
- ``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
@@ -231,10 +235,6 @@ Common build options
The default is 1 but is automatically disabled when the target architecture
is AArch32.
-- ``ENABLE_SPM`` : Boolean option to enable the Secure Partition Manager (SPM).
- Refer to :ref:`Secure Partition Manager` for more details about
- this feature. Default is 0.
-
- ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension
(SVE) for the Non-secure world only. SVE is an optional architectural feature
for AArch64. Note that when SVE is enabled for the Non-secure world, access
@@ -350,6 +350,21 @@ Common build options
compliant and is retained only for compatibility. The default value of this
flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme.
+- ``KEY_SIZE``: This build flag enables the user to select the key size for
+ the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE``
+ depend on the chosen algorithm and the cryptographic module.
+
+ +-----------+------------------------------------+
+ | KEY_ALG | Possible key sizes |
+ +===========+====================================+
+ | rsa | 1024 , 2048 (default), 3072, 4096* |
+ +-----------+------------------------------------+
+ | ecdsa | unavailable |
+ +-----------+------------------------------------+
+
+ * Only 2048 bits size is available with CryptoCell 712 SBROM release 1.
+ Only 3072 bits size is available with CryptoCell 712 SBROM release 2.
+
- ``HASH_ALG``: This build flag enables the user to select the secure hash
algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``.
The default value of this flag is ``sha256``.
@@ -476,6 +491,13 @@ Common build options
pages" section in :ref:`Firmware Design`. This flag is disabled by default and
affects all BL images.
+- ``SEPARATE_NOBITS_REGION``: Setting this option to ``1`` allows the NOBITS
+ sections of BL31 (.bss, stacks, page tables, and coherent memory) to be
+ allocated in RAM discontiguous from the loaded firmware image. When set, the
+ platform is expected to provide definitons for ``BL31_NOBITS_BASE`` and
+ ``BL31_NOBITS_LIMIT``. When the option is ``0`` (the default), NOBITS
+ sections are placed in RAM immediately following the loaded firmware image.
+
- ``SPD``: Choose a Secure Payload Dispatcher component to be built into TF-A.
This build option is only valid if ``ARCH=aarch64``. The value should be
the path to the directory containing the SPD source, relative to
@@ -488,6 +510,9 @@ Common build options
firmware images have been loaded in memory, and the MMU and caches are
turned off. Refer to the "Debugging options" section for more details.
+- ``SPM_MM`` : Boolean option to enable the Management Mode (MM)-based Secure
+ Partition Manager (SPM) implementation. The default value is ``0``.
+
- ``SP_MIN_WITH_SECURE_FIQ``: Boolean flag to indicate the SP_MIN handles
secure interrupts (caught through the FIQ line). Platforms can enable
this directive if they need to handle such interruption. When enabled,
@@ -540,6 +565,10 @@ Common build options
(Coherent memory region is included) or 0 (Coherent memory region is
excluded). Default is 1.
+- ``USE_DEBUGFS``: When set to 1 this option activates an EXPERIMENTAL feature
+ exposing a virtual filesystem interface through BL31 as a SiP SMC function.
+ Default is 0.
+
- ``USE_ROMLIB``: This flag determines whether library at ROM will be used.
This feature creates a library of functions to be placed in ROM and thus
reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default
diff --git a/docs/getting_started/initial-build.rst b/docs/getting_started/initial-build.rst
index 41cd4d1c97..893aba2457 100644
--- a/docs/getting_started/initial-build.rst
+++ b/docs/getting_started/initial-build.rst
@@ -8,13 +8,13 @@ Performing an Initial Build
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
For AArch32:
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-eabi-
+ export CROSS_COMPILE=<path-to-aarch32-gcc>/bin/arm-none-eabi-
It is possible to build TF-A using Clang or Arm Compiler 6. To do so
``CC`` needs to point to the clang or armclang binary, which will
@@ -32,7 +32,7 @@ Performing an Initial Build
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-armclang>/bin/armclang PLAT=<platform> all
Clang will be selected when the base name of the path assigned to ``CC``
@@ -43,7 +43,7 @@ Performing an Initial Build
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
make CC=<path-to-clang>/bin/clang PLAT=<platform> all
- Change to the root directory of the TF-A source tree and build.
diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst
index 17fd546624..bb14717523 100644
--- a/docs/getting_started/porting-guide.rst
+++ b/docs/getting_started/porting-guide.rst
@@ -1999,7 +1999,7 @@ Function : plat_psci_stat_get_residency() [optional]
::
- Argument : unsigned int, const psci_power_state_t *, int
+ Argument : unsigned int, const psci_power_state_t *, unsigned int
Return : u_register_t
This is an optional interface that is is invoked after resuming from a low power
diff --git a/docs/getting_started/prerequisites.rst b/docs/getting_started/prerequisites.rst
index 27ad0ed5f7..3e0c8fff29 100644
--- a/docs/getting_started/prerequisites.rst
+++ b/docs/getting_started/prerequisites.rst
@@ -26,7 +26,7 @@ Toolchain
|TF-A| can be built with any of the following *cross-compiler* toolchains that
target the Armv7-A or Armv8-A architectures:
-- GCC >= 8.3-2019.03 (from the `Arm Developer website`_)
+- GCC >= 9.2-2019.12 (from the `Arm Developer website`_)
- Clang >= 4.0
- Arm Compiler >= 6.0
diff --git a/docs/plat/arm/fvp/index.rst b/docs/plat/arm/fvp/index.rst
index b6396b97c2..37010e1a50 100644
--- a/docs/plat/arm/fvp/index.rst
+++ b/docs/plat/arm/fvp/index.rst
@@ -223,7 +223,7 @@ address ``0x82000000``, the firmware can be built like this:
.. code:: shell
- CROSS_COMPILE=aarch64-linux-gnu- \
+ CROSS_COMPILE=aarch64-none-elf- \
make PLAT=fvp DEBUG=1 \
RESET_TO_BL31=1 \
ARM_LINUX_KERNEL_AS_BL33=1 \
diff --git a/docs/plat/arm/juno/index.rst b/docs/plat/arm/juno/index.rst
index 6429ede7a5..cf328fac92 100644
--- a/docs/plat/arm/juno/index.rst
+++ b/docs/plat/arm/juno/index.rst
@@ -136,7 +136,7 @@ a single FIP binary. It assumes that a Linaro release has been installed.
.. code:: shell
- export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-linux-gnu-
+ export CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf-
- The following parameters should be used to build BL1 and BL2 in AArch64
and point to the BL32 file.
diff --git a/docs/plat/nvidia-tegra.rst b/docs/plat/nvidia-tegra.rst
index bc9e35b4fa..02ff38bef1 100644
--- a/docs/plat/nvidia-tegra.rst
+++ b/docs/plat/nvidia-tegra.rst
@@ -1,6 +1,17 @@
NVIDIA Tegra
============
+- .. rubric:: T194
+ :name: t194
+
+T194 has eight NVIDIA Carmel CPU cores in a coherent multi-processor
+configuration. The Carmel cores support the ARM Architecture version 8.2,
+executing both 64-bit AArch64 code, and 32-bit AArch32 code. The Carmel
+processors are organized as four dual-core clusters, where each cluster has
+a dedicated 2 MiB Level-2 unified cache. A high speed coherency fabric connects
+these processor complexes and allows heterogeneous multi-processing with all
+eight cores if required.
+
- .. rubric:: T186
:name: t186
@@ -78,9 +89,10 @@ their dispatchers in the image without changing any makefiles.
These are the supported Trusted OS' by Tegra platforms.
-Tegra132: TLK
-Tegra210: TLK and Trusty
-Tegra186: Trusty
+- Tegra132: TLK
+- Tegra210: TLK and Trusty
+- Tegra186: Trusty
+- Tegra194: Trusty
Scatter files
-------------
@@ -98,7 +110,7 @@ Preparing the BL31 image to run on Tegra SoCs
.. code:: shell
CROSS_COMPILE=<path-to-aarch64-gcc>/bin/aarch64-none-elf- make PLAT=tegra \
- TARGET_SOC=<target-soc e.g. t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
+ TARGET_SOC=<target-soc e.g. t194|t186|t210|t132> SPD=<dispatcher e.g. trusty|tlkd>
bl31
Platforms wanting to use different TZDRAM\_BASE, can add ``TZDRAM_BASE=<value>``
diff --git a/docs/plat/rpi4.rst b/docs/plat/rpi4.rst
index 0f529c1032..beb0227c2e 100644
--- a/docs/plat/rpi4.rst
+++ b/docs/plat/rpi4.rst
@@ -24,11 +24,10 @@ one universal binary (bl31.bin), which can be built with:
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi4 DEBUG=1
-Copy the generated build/rpi4/debug/bl31.bin to the SD card, either
-renaming it to ``armstub8.bin`` or adding an entry starting with ``armstub=``,
-then followed by the respective file name to ``config.txt``.
-You should have AArch64 code in the file loaded as the "kernel", as BL31
-will drop into AArch64/EL2 to the respective load address.
+Copy the generated build/rpi4/debug/bl31.bin to the SD card, adding an entry
+starting with ``armstub=``, then followed by the respective file name to
+``config.txt``. You should have AArch64 code in the file loaded as the
+"kernel", as BL31 will drop into AArch64/EL2 to the respective load address.
arm64 Linux kernels are known to work this way.
Other options that should be set in ``config.txt`` to properly boot 64-bit
diff --git a/docs/plat/stm32mp1.rst b/docs/plat/stm32mp1.rst
index 88251d6afb..2c372a6a38 100644
--- a/docs/plat/stm32mp1.rst
+++ b/docs/plat/stm32mp1.rst
@@ -76,21 +76,34 @@ ROM code -> BL2 (compiled with BL2_AT_EL3) -> OP-TEE -> BL33 (U-Boot)
Build Instructions
------------------
+Boot media(s) supported by BL2 must be specified in the build command.
+Available storage medias are:
+- ``STM32MP_SDMMC``
+- ``STM32MP_EMMC``
+- ``STM32MP_RAW_NAND``
+- ``STM32MP_SPI_NAND``
+- ``STM32MP_SPI_NOR``
-To build with SP_min:
+To build with SP_min and support for all bootable devices:
.. code:: bash
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min DTB_FILE_NAME=stm32mp157c-ev1.dtb
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=sp_min STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1
+ STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
cd <u-boot_directory>
make stm32mp15_trusted_defconfig
make DEVICE_TREE=stm32mp157c-ev1 all
-To build TF-A with with Op-TEE support:
-
+To build TF-A with OP-TEE support for all bootable devices:
.. code:: bash
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee
+ make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=stm32mp1 ARCH=aarch32 ARM_ARCH_MAJOR=7 AARCH32_SP=optee STM32MP_SDMMC=1 STM32MP_EMMC=1 STM32MP_RAW_NAND=1 STM32MP_SPI_NAND=1 STM32MP_SPI_NOR=1 DTB_FILE_NAME=stm32mp157c-ev1.dtb
+ cd <optee_directory>
+ make CROSS_COMPILE=arm-linux-gnueabihf- ARCH=arm PLATFORM=stm32mp1 CFG_EMBED_DTB_SOURCE_FILE=stm32mp157c-ev1.dts
+ cd <u-boot_directory>
+ make stm32mp15_optee_defconfig
+ make DEVICE_TREE=stm32mp157c-ev1 all
+
The following build options are supported:
diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst
index 49678719f0..a18a792038 100644
--- a/docs/process/security-hardening.rst
+++ b/docs/process/security-hardening.rst
@@ -30,9 +30,8 @@ Several build options can be used to check for security issues. Refer to the
- W=1
- Adds ``Wextra``, ``Wmissing-declarations``, ``Wmissing-format-attribute``,
- ``Wmissing-prototypes``, ``Wold-style-definition`` and
- ``Wunused-const-variable``.
+ Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
+ ``Wold-style-definition`` and ``Wunused-const-variable``.
- W=2
@@ -42,7 +41,7 @@ Several build options can be used to check for security issues. Refer to the
- W=3
Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
- ``Wpadded``, ``Wpointer-arith``, ``Wredundant-decls`` and
+ ``Wpointer-arith``, ``Wredundant-decls`` and
``Wswitch-default``.
Refer to the GCC or Clang documentation for more information on the individual
diff --git a/drivers/allwinner/axp/axp803.c b/drivers/allwinner/axp/axp803.c
new file mode 100644
index 0000000000..53b11c11ac
--- /dev/null
+++ b/drivers/allwinner/axp/axp803.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/allwinner/axp.h>
+
+const uint8_t axp_chip_id = AXP803_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp803";
+
+const struct axp_regulator axp_regulators[] = {
+ {"dcdc1", 1600, 3400, 100, NA, 0x20, 0x10, 0},
+ {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4},
+ {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5},
+ {"dldo1", 700, 3300, 100, NA, 0x15, 0x12, 3},
+ {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
+ {"dldo3", 700, 3300, 100, NA, 0x17, 0x12, 5},
+ {"dldo4", 700, 3300, 100, NA, 0x18, 0x12, 6},
+ {"fldo1", 700, 1450, 50, NA, 0x1c, 0x13, 2},
+ {}
+};
diff --git a/drivers/allwinner/axp/axp805.c b/drivers/allwinner/axp/axp805.c
new file mode 100644
index 0000000000..8d029c0bdf
--- /dev/null
+++ b/drivers/allwinner/axp/axp805.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/allwinner/axp.h>
+
+const uint8_t axp_chip_id = AXP805_CHIP_ID;
+const char *const axp_compatible = "x-powers,axp805";
+
+/*
+ * The "dcdcd" split changes the step size by a factor of 5, not 2;
+ * disallow values above the split to maintain accuracy.
+ */
+const struct axp_regulator axp_regulators[] = {
+ {"dcdca", 600, 1520, 10, 50, 0x12, 0x10, 0},
+ {"dcdcb", 1000, 2550, 50, NA, 0x13, 0x10, 1},
+ {"dcdcc", 600, 1520, 10, 50, 0x14, 0x10, 2},
+ {"dcdcd", 600, 1500, 20, NA, 0x15, 0x10, 3},
+ {"dcdce", 1100, 3400, 100, NA, 0x16, 0x10, 4},
+ {"aldo1", 700, 3300, 100, NA, 0x17, 0x10, 5},
+ {"aldo2", 700, 3300, 100, NA, 0x18, 0x10, 6},
+ {"aldo3", 700, 3300, 100, NA, 0x19, 0x10, 7},
+ {"bldo1", 700, 1900, 100, NA, 0x20, 0x11, 0},
+ {"bldo2", 700, 1900, 100, NA, 0x21, 0x11, 1},
+ {"bldo3", 700, 1900, 100, NA, 0x22, 0x11, 2},
+ {"bldo4", 700, 1900, 100, NA, 0x23, 0x11, 3},
+ {"cldo1", 700, 3300, 100, NA, 0x24, 0x11, 4},
+ {"cldo2", 700, 4200, 100, 27, 0x25, 0x11, 5},
+ {"cldo3", 700, 3300, 100, NA, 0x26, 0x11, 6},
+ {}
+};
diff --git a/drivers/allwinner/axp/common.c b/drivers/allwinner/axp/common.c
new file mode 100644
index 0000000000..13437fec81
--- /dev/null
+++ b/drivers/allwinner/axp/common.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <libfdt.h>
+
+#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
+
+int axp_check_id(void)
+{
+ int ret;
+
+ ret = axp_read(0x03);
+ if (ret < 0)
+ return ret;
+
+ ret &= 0xcf;
+ if (ret != axp_chip_id) {
+ ERROR("PMIC: Found unknown PMIC %02x\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
+{
+ uint8_t val;
+ int ret;
+
+ ret = axp_read(reg);
+ if (ret < 0)
+ return ret;
+
+ val = (ret & ~clr_mask) | set_mask;
+
+ return axp_write(reg, val);
+}
+
+void axp_power_off(void)
+{
+ /* Set "power disable control" bit */
+ axp_setbits(0x32, BIT(7));
+}
+
+/*
+ * Retrieve the voltage from a given regulator DTB node.
+ * Both the regulator-{min,max}-microvolt properties must be present and
+ * have the same value. Return that value in millivolts.
+ */
+static int fdt_get_regulator_millivolt(const void *fdt, int node)
+{
+ const fdt32_t *prop;
+ uint32_t min_volt;
+
+ prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+ min_volt = fdt32_to_cpu(*prop);
+
+ prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
+ if (prop == NULL)
+ return -EINVAL;
+
+ if (fdt32_to_cpu(*prop) != min_volt)
+ return -EINVAL;
+
+ return min_volt / 1000;
+}
+
+static int setup_regulator(const void *fdt, int node,
+ const struct axp_regulator *reg)
+{
+ uint8_t val;
+ int mvolt;
+
+ mvolt = fdt_get_regulator_millivolt(fdt, node);
+ if (mvolt < reg->min_volt || mvolt > reg->max_volt)
+ return -EINVAL;
+
+ val = (mvolt / reg->step) - (reg->min_volt / reg->step);
+ if (val > reg->split)
+ val = ((val - reg->split) / 2) + reg->split;
+
+ axp_write(reg->volt_reg, val);
+ axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
+
+ INFO("PMIC: %s voltage: %d.%03dV\n", reg->dt_name,
+ mvolt / 1000, mvolt % 1000);
+
+ return 0;
+}
+
+static bool should_enable_regulator(const void *fdt, int node)
+{
+ if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
+ return true;
+ if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
+ return true;
+ return false;
+}
+
+void axp_setup_regulators(const void *fdt)
+{
+ int node;
+ bool sw = false;
+
+ if (fdt == NULL)
+ return;
+
+ /* locate the PMIC DT node, bail out if not found */
+ node = fdt_node_offset_by_compatible(fdt, -1, axp_compatible);
+ if (node < 0) {
+ WARN("PMIC: No PMIC DT node, skipping setup\n");
+ return;
+ }
+
+ /* This applies to AXP803 only. */
+ if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
+ axp_clrbits(0x8f, BIT(4));
+ axp_setbits(0x30, BIT(2));
+ INFO("PMIC: Enabling DRIVEVBUS\n");
+ }
+
+ /* descend into the "regulators" subnode */
+ node = fdt_subnode_offset(fdt, node, "regulators");
+ if (node < 0) {
+ WARN("PMIC: No regulators DT node, skipping setup\n");
+ return;
+ }
+
+ /* iterate over all regulators to find used ones */
+ fdt_for_each_subnode(node, fdt, node) {
+ const struct axp_regulator *reg;
+ const char *name;
+ int length;
+
+ /* We only care if it's always on or referenced. */
+ if (!should_enable_regulator(fdt, node))
+ continue;
+
+ name = fdt_get_name(fdt, node, &length);
+
+ /* Enable the switch last to avoid overheating. */
+ if (!strncmp(name, "dc1sw", length) ||
+ !strncmp(name, "sw", length)) {
+ sw = true;
+ continue;
+ }
+
+ for (reg = axp_regulators; reg->dt_name; reg++) {
+ if (!strncmp(name, reg->dt_name, length)) {
+ setup_regulator(fdt, node, reg);
+ break;
+ }
+ }
+ }
+
+ /*
+ * On the AXP803, if DLDO2 is enabled after DC1SW, the PMIC overheats
+ * and shuts down. So always enable DC1SW as the very last regulator.
+ */
+ if (sw) {
+ INFO("PMIC: Enabling DC SW\n");
+ if (axp_chip_id == AXP803_CHIP_ID)
+ axp_setbits(0x12, BIT(7));
+ if (axp_chip_id == AXP805_CHIP_ID)
+ axp_setbits(0x11, BIT(7));
+ }
+}
diff --git a/drivers/arm/css/scp/css_pm_scmi.c b/drivers/arm/css/scp/css_pm_scmi.c
index 8dbefa16bb..b945cda788 100644
--- a/drivers/arm/css/scp/css_pm_scmi.c
+++ b/drivers/arm/css/scp/css_pm_scmi.c
@@ -186,7 +186,7 @@ void css_scp_off(const struct psci_power_state *target_state)
void css_scp_on(u_register_t mpidr)
{
unsigned int lvl = 0;
- int ret, core_pos;
+ int core_pos, ret;
uint32_t scmi_pwr_state = 0;
for (; lvl <= PLAT_MAX_PWR_LVL; lvl++)
@@ -196,7 +196,8 @@ void css_scp_on(u_register_t mpidr)
SCMI_SET_PWR_STATE_MAX_PWR_LVL(scmi_pwr_state, lvl - 1);
core_pos = plat_core_pos_by_mpidr(mpidr);
- assert(core_pos >= 0 && core_pos < PLATFORM_CORE_COUNT);
+ assert((core_pos >= 0) &&
+ (((unsigned int)core_pos) < PLATFORM_CORE_COUNT));
ret = scmi_pwr_state_set(scmi_handle,
plat_css_core_pos_to_scmi_dmn_id_map[core_pos],
diff --git a/drivers/arm/sbsa/sbsa.c b/drivers/arm/sbsa/sbsa.c
index 6f00a60195..79c6f26208 100644
--- a/drivers/arm/sbsa/sbsa.c
+++ b/drivers/arm/sbsa/sbsa.c
@@ -4,11 +4,11 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <plat/common/platform.h>
+#include <assert.h>
+#include <stdint.h>
#include <drivers/arm/sbsa.h>
#include <lib/mmio.h>
-#include <stdint_.h>
-#include <assert.h>
+#include <plat/common/platform.h>
void sbsa_watchdog_offset_reg_write(uintptr_t base, uint64_t value)
{
diff --git a/drivers/arm/scu/scu.c b/drivers/arm/scu/scu.c
new file mode 100644
index 0000000000..aceac92fa2
--- /dev/null
+++ b/drivers/arm/scu/scu.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <drivers/arm/scu.h>
+#include <lib/mmio.h>
+#include <plat/common/platform.h>
+#include <stdint.h>
+
+/*******************************************************************************
+ * Turn ON snoop control unit. This is needed to synchronize the data between
+ * CPU's.
+ ******************************************************************************/
+void enable_snoop_ctrl_unit(uintptr_t base)
+{
+ uint32_t scu_ctrl;
+
+ INFO("[SCU]: enabling snoop control unit ... \n");
+
+ assert(base != 0U);
+ scu_ctrl = mmio_read_32(base + SCU_CTRL_REG);
+
+ /* already enabled? */
+ if ((scu_ctrl & SCU_ENABLE_BIT) != 0) {
+ return;
+ }
+
+ scu_ctrl |= SCU_ENABLE_BIT;
+ mmio_write_32(base + SCU_CTRL_REG, scu_ctrl);
+}
+
+/*******************************************************************************
+ * Snoop Control Unit configuration register. This is read-only register and
+ * contains information such as
+ * - number of CPUs present
+ * - is a particular CPU operating in SMP mode or AMP mode
+ * - data cache size of a particular CPU
+ * - does SCU has ACP port
+ * - is L2CPRESENT
+ * NOTE: user of this API should interpert the bits in this register according
+ * to the TRM
+ ******************************************************************************/
+uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base)
+{
+ assert(base != 0U);
+
+ return mmio_read_32(base + SCU_CFG_REG);
+}
diff --git a/drivers/auth/auth_mod.c b/drivers/auth/auth_mod.c
index a6538c4e5c..3fb2d1a48c 100644
--- a/drivers/auth/auth_mod.c
+++ b/drivers/auth/auth_mod.c
@@ -30,9 +30,6 @@
#pragma weak plat_set_nv_ctr2
-/* Pointer to CoT */
-extern const auth_img_desc_t *const *const cot_desc_ptr;
-extern unsigned int auth_img_flags[MAX_NUMBER_IDS];
static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
const auth_param_type_desc_t *b)
diff --git a/drivers/auth/cryptocell/712/cryptocell_crypto.c b/drivers/auth/cryptocell/712/cryptocell_crypto.c
index 395c550859..25eb6bcb6d 100644
--- a/drivers/auth/cryptocell/712/cryptocell_crypto.c
+++ b/drivers/auth/cryptocell/712/cryptocell_crypto.c
@@ -225,7 +225,7 @@ static int verify_signature(void *data_ptr, unsigned int data_len,
/* Verify the signature */
error = CCSbVerifySignature((uintptr_t)PLAT_CRYPTOCELL_BASE,
(uint32_t *)data_ptr, &pk, &signature,
- data_len, RSA_PSS_2048);
+ data_len, RSA_PSS);
if (error != CC_OK)
return CRYPTO_ERR_SIGNATURE;
diff --git a/drivers/auth/cryptocell/cryptocell_crypto.mk b/drivers/auth/cryptocell/cryptocell_crypto.mk
index d42a2e7e12..2fc4ddb11b 100644
--- a/drivers/auth/cryptocell/cryptocell_crypto.mk
+++ b/drivers/auth/cryptocell/cryptocell_crypto.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -12,6 +12,8 @@ TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
# Needs to be set to drive mbed TLS configuration correctly
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
+$(eval $(call add_define,KEY_SIZE))
+
# CCSBROM_LIB_PATH must be set to the Cryptocell SBROM library path
ifeq (${CCSBROM_LIB_PATH},)
$(error Error: CCSBROM_LIB_PATH not set)
diff --git a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
index a0fc034d88..dcd1991484 100644
--- a/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
+++ b/drivers/intel/soc/stratix10/io/s10_memmap_qspi.c
@@ -26,9 +26,9 @@ typedef struct {
* valid.
*/
int in_use;
- uintptr_t base;
- size_t file_pos;
- size_t size;
+ uintptr_t base;
+ unsigned long long file_pos;
+ unsigned long long size;
} file_state_t;
static file_state_t current_file = {0};
@@ -44,7 +44,7 @@ static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
static int memmap_block_seek(io_entity_t *entity, int mode,
- ssize_t offset);
+ signed long long offset);
static int memmap_block_len(io_entity_t *entity, size_t *length);
static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read);
@@ -131,7 +131,8 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
/* Seek to a particular file offset on the memmap device */
-static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int memmap_block_seek(io_entity_t *entity, int mode,
+ signed long long offset)
{
int result = -ENOENT;
file_state_t *fp;
@@ -143,7 +144,8 @@ static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
fp = (file_state_t *) entity->info;
/* Assert that new file position is valid */
- assert((offset >= 0) && (offset < fp->size));
+ assert((offset >= 0) &&
+ ((unsigned long long)offset < fp->size));
/* Reset file position */
fp->file_pos = offset;
@@ -171,7 +173,7 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
file_state_t *fp;
- size_t pos_after;
+ unsigned long long pos_after;
assert(entity != NULL);
assert(length_read != NULL);
@@ -198,7 +200,7 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
size_t length, size_t *length_written)
{
file_state_t *fp;
- size_t pos_after;
+ unsigned long long pos_after;
assert(entity != NULL);
assert(length_written != NULL);
diff --git a/drivers/io/io_block.c b/drivers/io/io_block.c
index f190a4307b..5d45c2f176 100644
--- a/drivers/io/io_block.c
+++ b/drivers/io/io_block.c
@@ -19,17 +19,17 @@
typedef struct {
io_block_dev_spec_t *dev_spec;
uintptr_t base;
- size_t file_pos;
- size_t size;
+ unsigned long long file_pos;
+ unsigned long long size;
} block_dev_state_t;
-#define is_power_of_2(x) ((x != 0) && ((x & (x - 1)) == 0))
+#define is_power_of_2(x) (((x) != 0U) && (((x) & ((x) - 1U)) == 0U))
io_type_t device_type_block(void);
static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
-static int block_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int block_seek(io_entity_t *entity, int mode, signed long long offset);
static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
size_t *length_read);
static int block_write(io_entity_t *entity, const uintptr_t buffer,
@@ -148,21 +148,21 @@ static int block_open(io_dev_info_t *dev_info, const uintptr_t spec,
}
/* parameter offset is relative address at here */
-static int block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int block_seek(io_entity_t *entity, int mode, signed long long offset)
{
block_dev_state_t *cur;
assert(entity->info != (uintptr_t)NULL);
cur = (block_dev_state_t *)entity->info;
- assert((offset >= 0) && (offset < cur->size));
+ assert((offset >= 0) && ((unsigned long long)offset < cur->size));
switch (mode) {
case IO_SEEK_SET:
- cur->file_pos = offset;
+ cur->file_pos = (unsigned long long)offset;
break;
case IO_SEEK_CUR:
- cur->file_pos += offset;
+ cur->file_pos += (unsigned long long)offset;
break;
default:
return -EINVAL;
@@ -270,7 +270,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
buf = &(cur->dev_spec->buffer);
block_size = cur->dev_spec->block_size;
assert((length <= cur->size) &&
- (length > 0) &&
+ (length > 0U) &&
(ops->read != 0));
/*
@@ -279,7 +279,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
* on the low level driver.
*/
count = 0;
- for (left = length; left > 0; left -= nbytes) {
+ for (left = length; left > 0U; left -= nbytes) {
/*
* We must only request operations aligned to the block
* size. Therefore if file_pos is not block-aligned,
@@ -288,7 +288,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
* similarly, the number of bytes requested must be a
* block size multiple
*/
- skip = cur->file_pos & (block_size - 1);
+ skip = cur->file_pos & (block_size - 1U);
/*
* Calculate the block number containing file_pos
@@ -296,7 +296,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
*/
lba = (cur->file_pos + cur->base) / block_size;
- if (skip + left > buf->length) {
+ if ((skip + left) > buf->length) {
/*
* The underlying read buffer is too small to
* read all the required data - limit to just
@@ -311,7 +311,8 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
* block size.
*/
request = skip + left;
- request = (request + (block_size - 1)) & ~(block_size - 1);
+ request = (request + (block_size - 1U)) &
+ ~(block_size - 1U);
}
request = ops->read(lba, buf->offset, request);
@@ -330,7 +331,7 @@ static int block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
* the read data when copying to the user buffer.
*/
nbytes = request - skip;
- padding = (nbytes > left) ? nbytes - left : 0;
+ padding = (nbytes > left) ? nbytes - left : 0U;
nbytes -= padding;
memcpy((void *)(buffer + count),
@@ -381,7 +382,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
buf = &(cur->dev_spec->buffer);
block_size = cur->dev_spec->block_size;
assert((length <= cur->size) &&
- (length > 0) &&
+ (length > 0U) &&
(ops->read != 0) &&
(ops->write != 0));
@@ -391,7 +392,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* on the low level driver.
*/
count = 0;
- for (left = length; left > 0; left -= nbytes) {
+ for (left = length; left > 0U; left -= nbytes) {
/*
* We must only request operations aligned to the block
* size. Therefore if file_pos is not block-aligned,
@@ -400,7 +401,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* similarly, the number of bytes requested must be a
* block size multiple
*/
- skip = cur->file_pos & (block_size - 1);
+ skip = cur->file_pos & (block_size - 1U);
/*
* Calculate the block number containing file_pos
@@ -408,7 +409,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
*/
lba = (cur->file_pos + cur->base) / block_size;
- if (skip + left > buf->length) {
+ if ((skip + left) > buf->length) {
/*
* The underlying read buffer is too small to
* read all the required data - limit to just
@@ -423,7 +424,8 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* block size.
*/
request = skip + left;
- request = (request + (block_size - 1)) & ~(block_size - 1);
+ request = (request + (block_size - 1U)) &
+ ~(block_size - 1U);
}
/*
@@ -432,7 +434,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* of the current request.
*/
nbytes = request - skip;
- padding = (nbytes > left) ? nbytes - left : 0;
+ padding = (nbytes > left) ? nbytes - left : 0U;
nbytes -= padding;
/*
@@ -440,14 +442,14 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* some content and it means that we have to read before
* writing
*/
- if (skip > 0 || padding > 0) {
+ if ((skip > 0U) || (padding > 0U)) {
request = ops->read(lba, buf->offset, request);
/*
* The read may return size less than
* requested. Round down to the nearest block
* boundary
*/
- request &= ~(block_size-1);
+ request &= ~(block_size - 1U);
if (request <= skip) {
/*
* We couldn't read enough bytes to jump over
@@ -458,7 +460,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
return -EIO;
}
nbytes = request - skip;
- padding = (nbytes > left) ? nbytes - left : 0;
+ padding = (nbytes > left) ? nbytes - left : 0U;
nbytes -= padding;
}
@@ -477,7 +479,7 @@ static int block_write(io_entity_t *entity, const uintptr_t buffer,
* buffer
*/
nbytes = request - skip;
- padding = (nbytes > left) ? nbytes - left : 0;
+ padding = (nbytes > left) ? nbytes - left : 0U;
nbytes -= padding;
cur->file_pos += nbytes;
@@ -505,7 +507,7 @@ static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
assert(dev_info != NULL);
result = allocate_dev_info(&info);
- if (result)
+ if (result != 0)
return -ENOENT;
cur = (block_dev_state_t *)info->info;
@@ -513,10 +515,10 @@ static int block_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
cur->dev_spec = (io_block_dev_spec_t *)dev_spec;
buffer = &(cur->dev_spec->buffer);
block_size = cur->dev_spec->block_size;
- assert((block_size > 0) &&
- (is_power_of_2(block_size) != 0) &&
- ((buffer->offset % block_size) == 0) &&
- ((buffer->length % block_size) == 0));
+ assert((block_size > 0U) &&
+ (is_power_of_2(block_size) != 0U) &&
+ ((buffer->offset % block_size) == 0U) &&
+ ((buffer->length % block_size) == 0U));
*dev_info = info; /* cast away const */
(void)block_size;
diff --git a/drivers/io/io_fip.c b/drivers/io/io_fip.c
index 544b37dbea..5d49fffaa3 100644
--- a/drivers/io/io_fip.c
+++ b/drivers/io/io_fip.c
@@ -304,7 +304,8 @@ static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
}
/* Seek past the FIP header into the Table of Contents */
- result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t));
+ result = io_seek(backend_handle, IO_SEEK_SET,
+ (signed long long)sizeof(fip_toc_header_t));
if (result != 0) {
WARN("fip_file_open: failed to seek\n");
result = -ENOENT;
@@ -389,7 +390,8 @@ static int fip_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
/* Seek to the position in the FIP where the payload lives */
file_offset = fp->entry.offset_address + fp->file_pos;
- result = io_seek(backend_handle, IO_SEEK_SET, file_offset);
+ result = io_seek(backend_handle, IO_SEEK_SET,
+ (signed long long)file_offset);
if (result != 0) {
WARN("fip_file_read: failed to seek\n");
result = -ENOENT;
diff --git a/drivers/io/io_memmap.c b/drivers/io/io_memmap.c
index 96590b6c03..eed50cc086 100644
--- a/drivers/io/io_memmap.c
+++ b/drivers/io/io_memmap.c
@@ -23,10 +23,10 @@ typedef struct {
/* Use the 'in_use' flag as any value for base and file_pos could be
* valid.
*/
- int in_use;
- uintptr_t base;
- size_t file_pos;
- size_t size;
+ int in_use;
+ uintptr_t base;
+ unsigned long long file_pos;
+ unsigned long long size;
} file_state_t;
static file_state_t current_file = {0};
@@ -42,7 +42,7 @@ static int memmap_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
static int memmap_block_seek(io_entity_t *entity, int mode,
- ssize_t offset);
+ signed long long offset);
static int memmap_block_len(io_entity_t *entity, size_t *length);
static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read);
@@ -129,7 +129,8 @@ static int memmap_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
/* Seek to a particular file offset on the memmap device */
-static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int memmap_block_seek(io_entity_t *entity, int mode,
+ signed long long offset)
{
int result = -ENOENT;
file_state_t *fp;
@@ -141,10 +142,11 @@ static int memmap_block_seek(io_entity_t *entity, int mode, ssize_t offset)
fp = (file_state_t *) entity->info;
/* Assert that new file position is valid */
- assert((offset >= 0) && (offset < fp->size));
+ assert((offset >= 0) &&
+ ((unsigned long long)offset < fp->size));
/* Reset file position */
- fp->file_pos = offset;
+ fp->file_pos = (unsigned long long)offset;
result = 0;
}
@@ -158,7 +160,7 @@ static int memmap_block_len(io_entity_t *entity, size_t *length)
assert(entity != NULL);
assert(length != NULL);
- *length = ((file_state_t *)entity->info)->size;
+ *length = (size_t)((file_state_t *)entity->info)->size;
return 0;
}
@@ -169,7 +171,7 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
size_t length, size_t *length_read)
{
file_state_t *fp;
- size_t pos_after;
+ unsigned long long pos_after;
assert(entity != NULL);
assert(length_read != NULL);
@@ -180,7 +182,8 @@ static int memmap_block_read(io_entity_t *entity, uintptr_t buffer,
pos_after = fp->file_pos + length;
assert((pos_after >= fp->file_pos) && (pos_after <= fp->size));
- memcpy((void *)buffer, (void *)(fp->base + fp->file_pos), length);
+ memcpy((void *)buffer,
+ (void *)((uintptr_t)(fp->base + fp->file_pos)), length);
*length_read = length;
@@ -196,7 +199,7 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
size_t length, size_t *length_written)
{
file_state_t *fp;
- size_t pos_after;
+ unsigned long long pos_after;
assert(entity != NULL);
assert(length_written != NULL);
@@ -207,7 +210,8 @@ static int memmap_block_write(io_entity_t *entity, const uintptr_t buffer,
pos_after = fp->file_pos + length;
assert((pos_after >= fp->file_pos) && (pos_after <= fp->size));
- memcpy((void *)(fp->base + fp->file_pos), (void *)buffer, length);
+ memcpy((void *)((uintptr_t)(fp->base + fp->file_pos)),
+ (void *)buffer, length);
*length_written = length;
diff --git a/drivers/io/io_mtd.c b/drivers/io/io_mtd.c
new file mode 100644
index 0000000000..7575fa2503
--- /dev/null
+++ b/drivers/io/io_mtd.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/io/io_driver.h>
+#include <drivers/io/io_mtd.h>
+#include <lib/utils.h>
+
+typedef struct {
+ io_mtd_dev_spec_t *dev_spec;
+ uintptr_t base;
+ unsigned long long offset; /* Offset in bytes */
+ unsigned long long size; /* Size of device in bytes */
+} mtd_dev_state_t;
+
+io_type_t device_type_mtd(void);
+
+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec,
+ io_entity_t *entity);
+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset);
+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+ size_t *length_read);
+static int mtd_close(io_entity_t *entity);
+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
+static int mtd_dev_close(io_dev_info_t *dev_info);
+
+static const io_dev_connector_t mtd_dev_connector = {
+ .dev_open = mtd_dev_open
+};
+
+static const io_dev_funcs_t mtd_dev_funcs = {
+ .type = device_type_mtd,
+ .open = mtd_open,
+ .seek = mtd_seek,
+ .read = mtd_read,
+ .close = mtd_close,
+ .dev_close = mtd_dev_close,
+};
+
+static mtd_dev_state_t state_pool[MAX_IO_MTD_DEVICES];
+static io_dev_info_t dev_info_pool[MAX_IO_MTD_DEVICES];
+
+io_type_t device_type_mtd(void)
+{
+ return IO_TYPE_MTD;
+}
+
+/* Locate a MTD state in the pool, specified by address */
+static int find_first_mtd_state(const io_mtd_dev_spec_t *dev_spec,
+ unsigned int *index_out)
+{
+ unsigned int index;
+ int result = -ENOENT;
+
+ for (index = 0U; index < MAX_IO_MTD_DEVICES; index++) {
+ /* dev_spec is used as identifier since it's unique */
+ if (state_pool[index].dev_spec == dev_spec) {
+ result = 0;
+ *index_out = index;
+ break;
+ }
+ }
+
+ return result;
+}
+
+/* Allocate a device info from the pool */
+static int allocate_dev_info(io_dev_info_t **dev_info)
+{
+ unsigned int index = 0U;
+ int result;
+
+ result = find_first_mtd_state(NULL, &index);
+ if (result != 0) {
+ return -ENOMEM;
+ }
+
+ dev_info_pool[index].funcs = &mtd_dev_funcs;
+ dev_info_pool[index].info = (uintptr_t)&state_pool[index];
+ *dev_info = &dev_info_pool[index];
+
+ return 0;
+}
+
+/* Release a device info from the pool */
+static int free_dev_info(io_dev_info_t *dev_info)
+{
+ int result;
+ unsigned int index = 0U;
+ mtd_dev_state_t *state;
+
+ state = (mtd_dev_state_t *)dev_info->info;
+ result = find_first_mtd_state(state->dev_spec, &index);
+ if (result != 0) {
+ return result;
+ }
+
+ zeromem(state, sizeof(mtd_dev_state_t));
+ zeromem(dev_info, sizeof(io_dev_info_t));
+
+ return 0;
+}
+
+static int mtd_open(io_dev_info_t *dev_info, const uintptr_t spec,
+ io_entity_t *entity)
+{
+ mtd_dev_state_t *cur;
+
+ assert((dev_info->info != 0UL) && (entity->info == 0UL));
+
+ cur = (mtd_dev_state_t *)dev_info->info;
+ entity->info = (uintptr_t)cur;
+ cur->offset = 0U;
+
+ return 0;
+}
+
+/* Seek to a specific position using offset */
+static int mtd_seek(io_entity_t *entity, int mode, signed long long offset)
+{
+ mtd_dev_state_t *cur;
+
+ assert((entity->info != (uintptr_t)NULL) && (offset >= 0));
+
+ cur = (mtd_dev_state_t *)entity->info;
+
+ switch (mode) {
+ case IO_SEEK_SET:
+ if ((offset >= 0) &&
+ ((unsigned long long)offset >= cur->size)) {
+ return -EINVAL;
+ }
+
+ cur->offset = offset;
+ break;
+ case IO_SEEK_CUR:
+ if (((cur->offset + (unsigned long long)offset) >=
+ cur->size) ||
+ ((cur->offset + (unsigned long long)offset) <
+ cur->offset)) {
+ return -EINVAL;
+ }
+
+ cur->offset += (unsigned long long)offset;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtd_read(io_entity_t *entity, uintptr_t buffer, size_t length,
+ size_t *out_length)
+{
+ mtd_dev_state_t *cur;
+ io_mtd_ops_t *ops;
+ int ret;
+
+ assert(entity->info != (uintptr_t)NULL);
+ assert((length > 0U) && (buffer != (uintptr_t)NULL));
+
+ cur = (mtd_dev_state_t *)entity->info;
+ ops = &cur->dev_spec->ops;
+ assert(ops->read != NULL);
+
+ VERBOSE("Read at %llx into %lx, length %zi\n",
+ cur->offset, buffer, length);
+ if ((cur->offset + length) > cur->dev_spec->device_size) {
+ return -EINVAL;
+ }
+
+ ret = ops->read(cur->offset, buffer, length, out_length);
+ if (ret < 0) {
+ return ret;
+ }
+
+ assert(*out_length == length);
+ cur->offset += *out_length;
+
+ return 0;
+}
+
+static int mtd_close(io_entity_t *entity)
+{
+ entity->info = (uintptr_t)NULL;
+
+ return 0;
+}
+
+static int mtd_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info)
+{
+ mtd_dev_state_t *cur;
+ io_dev_info_t *info;
+ io_mtd_ops_t *ops;
+ int result;
+
+ result = allocate_dev_info(&info);
+ if (result != 0) {
+ return -ENOENT;
+ }
+
+ cur = (mtd_dev_state_t *)info->info;
+ cur->dev_spec = (io_mtd_dev_spec_t *)dev_spec;
+ *dev_info = info;
+ ops = &(cur->dev_spec->ops);
+ if (ops->init != NULL) {
+ result = ops->init(&cur->dev_spec->device_size,
+ &cur->dev_spec->erase_size);
+ }
+
+ if (result == 0) {
+ cur->size = cur->dev_spec->device_size;
+ } else {
+ cur->size = 0ULL;
+ }
+
+ return result;
+}
+
+static int mtd_dev_close(io_dev_info_t *dev_info)
+{
+ return free_dev_info(dev_info);
+}
+
+/* Exported functions */
+
+/* Register the MTD driver in the IO abstraction */
+int register_io_dev_mtd(const io_dev_connector_t **dev_con)
+{
+ int result;
+
+ result = io_register_device(&dev_info_pool[0]);
+ if (result == 0) {
+ *dev_con = &mtd_dev_connector;
+ }
+
+ return result;
+}
diff --git a/drivers/io/io_semihosting.c b/drivers/io/io_semihosting.c
index 23d09c1188..4ceddc6cc0 100644
--- a/drivers/io/io_semihosting.c
+++ b/drivers/io/io_semihosting.c
@@ -25,7 +25,7 @@ static io_type_t device_type_sh(void)
static int sh_dev_open(const uintptr_t dev_spec, io_dev_info_t **dev_info);
static int sh_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
-static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset);
static int sh_file_len(io_entity_t *entity, size_t *length);
static int sh_file_read(io_entity_t *entity, uintptr_t buffer, size_t length,
size_t *length_read);
@@ -90,7 +90,7 @@ static int sh_file_open(io_dev_info_t *dev_info __unused,
/* Seek to a particular file offset on the semi-hosting device */
-static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int sh_file_seek(io_entity_t *entity, int mode, signed long long offset)
{
long file_handle, sh_result;
@@ -98,7 +98,7 @@ static int sh_file_seek(io_entity_t *entity, int mode, ssize_t offset)
file_handle = (long)entity->info;
- sh_result = semihosting_file_seek(file_handle, offset);
+ sh_result = semihosting_file_seek(file_handle, (ssize_t)offset);
return (sh_result == 0) ? 0 : -ENOENT;
}
diff --git a/drivers/io/io_storage.c b/drivers/io/io_storage.c
index e444f87f72..b8c1d6479f 100644
--- a/drivers/io/io_storage.c
+++ b/drivers/io/io_storage.c
@@ -237,7 +237,7 @@ int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle)
/* Seek to a specific position in an IO entity */
-int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset)
+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset)
{
int result = -ENODEV;
assert(is_valid_entity(handle) && is_valid_seek_mode(mode));
diff --git a/drivers/marvell/comphy/phy-comphy-3700.c b/drivers/marvell/comphy/phy-comphy-3700.c
index 2e8c4128e7..f6a40a587f 100644
--- a/drivers/marvell/comphy/phy-comphy-3700.c
+++ b/drivers/marvell/comphy/phy-comphy-3700.c
@@ -195,6 +195,45 @@ error:
ERROR("COMPHY[%d] mode[%d] is invalid\n", comphy_index, mode);
}
+/*
+ * This is something like the inverse of the previous function: for given
+ * lane it returns COMPHY_*_MODE.
+ *
+ * It is useful when powering the phy off.
+ *
+ * This function returns COMPHY_USB3_MODE even if the phy was configured
+ * with COMPHY_USB3D_MODE or COMPHY_USB3H_MODE. (The usb3 phy initialization
+ * code does not differentiate between these modes.)
+ * Also it returns COMPHY_SGMII_MODE even if the phy was configures with
+ * COMPHY_HS_SGMII_MODE. (The sgmii phy initialization code does differentiate
+ * between these modes, but it is irrelevant when powering the phy off.)
+ */
+static int mvebu_a3700_comphy_get_mode(uint8_t comphy_index)
+{
+ uint32_t reg;
+
+ reg = mmio_read_32(MVEBU_COMPHY_REG_BASE + COMPHY_SELECTOR_PHY_REG);
+ switch (comphy_index) {
+ case COMPHY_LANE0:
+ if ((reg & COMPHY_SELECTOR_USB3_GBE1_SEL_BIT) != 0)
+ return COMPHY_USB3_MODE;
+ else
+ return COMPHY_SGMII_MODE;
+ case COMPHY_LANE1:
+ if ((reg & COMPHY_SELECTOR_PCIE_GBE0_SEL_BIT) != 0)
+ return COMPHY_PCIE_MODE;
+ else
+ return COMPHY_SGMII_MODE;
+ case COMPHY_LANE2:
+ if ((reg & COMPHY_SELECTOR_USB3_PHY_SEL_BIT) != 0)
+ return COMPHY_USB3_MODE;
+ else
+ return COMPHY_SATA_MODE;
+ }
+
+ return COMPHY_UNUSED;
+}
+
/* It is only used for SATA and USB3 on comphy lane2. */
static void comphy_set_indirect(uintptr_t addr, uint32_t offset, uint16_t data,
uint16_t mask, int mode)
@@ -547,6 +586,23 @@ static int mvebu_a3700_comphy_sgmii_power_on(uint8_t comphy_index,
return ret;
}
+static int mvebu_a3700_comphy_sgmii_power_off(uint8_t comphy_index)
+{
+ int ret = 0;
+ uint32_t mask, data, offset;
+
+ debug_enter();
+
+ data = PIN_RESET_CORE_BIT | PIN_RESET_COMPHY_BIT;
+ mask = 0;
+ offset = MVEBU_COMPHY_REG_BASE + COMPHY_PHY_CFG1_OFFSET(comphy_index);
+ reg_set(offset, data, mask);
+
+ debug_exit();
+
+ return ret;
+}
+
static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
uint32_t comphy_mode)
{
@@ -721,11 +777,11 @@ static int mvebu_a3700_comphy_usb3_power_on(uint8_t comphy_index,
udelay(PLL_SET_DELAY_US);
if (comphy_index == COMPHY_LANE2) {
- data = COMPHY_LOOPBACK_REG0 + USB3PHY_LANE2_REG_BASE_OFFSET;
+ data = COMPHY_REG_LANE_STATUS1_ADDR + USB3PHY_LANE2_REG_BASE_OFFSET;
mmio_write_32(reg_base + COMPHY_LANE2_INDIR_ADDR_OFFSET,
data);
- addr = COMPHY_LOOPBACK_REG0 + USB3PHY_LANE2_REG_BASE_OFFSET;
+ addr = reg_base + COMPHY_LANE2_INDIR_DATA_OFFSET;
ret = polling_with_timeout(addr, TXDCLK_PCLK_EN, TXDCLK_PCLK_EN,
COMPHY_PLL_TIMEOUT, REG_32BIT);
} else {
@@ -908,7 +964,20 @@ int mvebu_3700_comphy_power_off(uint8_t comphy_index, uint32_t comphy_mode)
debug_enter();
+ if (!mode) {
+ /*
+ * The user did not specify which mode should be powered off.
+ * In this case we can identify this by reading the phy selector
+ * register.
+ */
+ mode = mvebu_a3700_comphy_get_mode(comphy_index);
+ }
+
switch (mode) {
+ case(COMPHY_SGMII_MODE):
+ case(COMPHY_HS_SGMII_MODE):
+ err = mvebu_a3700_comphy_sgmii_power_off(comphy_index);
+ break;
case (COMPHY_USB3_MODE):
case (COMPHY_USB3H_MODE):
err = mvebu_a3700_comphy_usb3_power_off();
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
new file mode 100644
index 0000000000..44b001e35b
--- /dev/null
+++ b/drivers/mtd/nand/core.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/nand.h>
+#include <lib/utils.h>
+
+/*
+ * Define a single nand_device used by specific NAND frameworks.
+ */
+static struct nand_device nand_dev;
+static uint8_t scratch_buff[PLATFORM_MTD_MAX_PAGE_SIZE];
+
+int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+ size_t *length_read)
+{
+ unsigned int block = offset / nand_dev.block_size;
+ unsigned int end_block = (offset + length - 1U) / nand_dev.block_size;
+ unsigned int page_start =
+ (offset % nand_dev.block_size) / nand_dev.page_size;
+ unsigned int nb_pages = nand_dev.block_size / nand_dev.page_size;
+ unsigned int start_offset = offset % nand_dev.page_size;
+ unsigned int page;
+ unsigned int bytes_read;
+ int is_bad;
+ int ret;
+
+ VERBOSE("Block %u - %u, page_start %u, nb %u, length %zu, offset %u\n",
+ block, end_block, page_start, nb_pages, length, offset);
+
+ *length_read = 0UL;
+
+ if (((start_offset != 0U) || (length % nand_dev.page_size) != 0U) &&
+ (sizeof(scratch_buff) < nand_dev.page_size)) {
+ return -EINVAL;
+ }
+
+ while (block <= end_block) {
+ is_bad = nand_dev.mtd_block_is_bad(block);
+ if (is_bad < 0) {
+ return is_bad;
+ }
+
+ if (is_bad == 1) {
+ /* Skip the block */
+ uint32_t max_block =
+ nand_dev.size / nand_dev.block_size;
+
+ block++;
+ end_block++;
+ if ((block < max_block) && (end_block < max_block)) {
+ continue;
+ }
+
+ return -EIO;
+ }
+
+ for (page = page_start; page < nb_pages; page++) {
+ if ((start_offset != 0U) ||
+ (length < nand_dev.page_size)) {
+ ret = nand_dev.mtd_read_page(
+ &nand_dev,
+ (block * nb_pages) + page,
+ (uintptr_t)scratch_buff);
+ if (ret != 0) {
+ return ret;
+ }
+
+ bytes_read = MIN((size_t)(nand_dev.page_size -
+ start_offset),
+ length);
+
+ memcpy((uint8_t *)buffer,
+ scratch_buff + start_offset,
+ bytes_read);
+
+ start_offset = 0U;
+ } else {
+ ret = nand_dev.mtd_read_page(&nand_dev,
+ (block * nb_pages) + page,
+ buffer);
+ if (ret != 0) {
+ return ret;
+ }
+
+ bytes_read = nand_dev.page_size;
+ }
+
+ length -= bytes_read;
+ buffer += bytes_read;
+ *length_read += bytes_read;
+
+ if (length == 0U) {
+ break;
+ }
+ }
+
+ page_start = 0U;
+ block++;
+ }
+
+ return 0;
+}
+
+struct nand_device *get_nand_device(void)
+{
+ return &nand_dev;
+}
diff --git a/drivers/mtd/nand/raw_nand.c b/drivers/mtd/nand/raw_nand.c
new file mode 100644
index 0000000000..48131fcb25
--- /dev/null
+++ b/drivers/mtd/nand/raw_nand.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/raw_nand.h>
+#include <lib/utils.h>
+
+#define ONFI_SIGNATURE_ADDR 0x20U
+
+/* CRC calculation */
+#define CRC_POLYNOM 0x8005U
+#define CRC_INIT_VALUE 0x4F4EU
+
+/* Status register */
+#define NAND_STATUS_READY BIT(6)
+
+#define SZ_128M 0x08000000U
+#define SZ_512 0x200U
+
+static struct rawnand_device rawnand_dev;
+
+#pragma weak plat_get_raw_nand_data
+int plat_get_raw_nand_data(struct rawnand_device *device)
+{
+ return 0;
+}
+
+static int nand_send_cmd(uint8_t cmd, unsigned int tim)
+{
+ struct nand_req req;
+
+ zeromem(&req, sizeof(struct nand_req));
+ req.nand = rawnand_dev.nand_dev;
+ req.type = NAND_REQ_CMD | cmd;
+ req.inst_delay = tim;
+
+ return rawnand_dev.ops->exec(&req);
+}
+
+static int nand_send_addr(uint8_t addr, unsigned int tim)
+{
+ struct nand_req req;
+
+ zeromem(&req, sizeof(struct nand_req));
+ req.nand = rawnand_dev.nand_dev;
+ req.type = NAND_REQ_ADDR;
+ req.addr = &addr;
+ req.inst_delay = tim;
+
+ return rawnand_dev.ops->exec(&req);
+}
+
+static int nand_send_wait(unsigned int delay, unsigned int tim)
+{
+ struct nand_req req;
+
+ zeromem(&req, sizeof(struct nand_req));
+ req.nand = rawnand_dev.nand_dev;
+ req.type = NAND_REQ_WAIT;
+ req.inst_delay = tim;
+ req.delay_ms = delay;
+
+ return rawnand_dev.ops->exec(&req);
+}
+
+
+static int nand_read_data(uint8_t *data, unsigned int length, bool use_8bit)
+{
+ struct nand_req req;
+
+ zeromem(&req, sizeof(struct nand_req));
+ req.nand = rawnand_dev.nand_dev;
+ req.type = NAND_REQ_DATAIN | (use_8bit ? NAND_REQ_BUS_WIDTH_8 : 0U);
+ req.addr = data;
+ req.length = length;
+
+ return rawnand_dev.ops->exec(&req);
+}
+
+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer,
+ unsigned int len)
+{
+ int ret;
+ uint8_t addr[2];
+ unsigned int i;
+
+ ret = nand_send_cmd(NAND_CMD_CHANGE_1ST, 0U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) {
+ offset /= 2U;
+ }
+
+ addr[0] = offset;
+ addr[1] = offset >> 8;
+
+ for (i = 0; i < 2U; i++) {
+ ret = nand_send_addr(addr[i], 0U);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ ret = nand_send_cmd(NAND_CMD_CHANGE_2ND, NAND_TCCS_MIN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return nand_read_data((uint8_t *)buffer, len, false);
+}
+
+int nand_read_page_cmd(unsigned int page, unsigned int offset,
+ uintptr_t buffer, unsigned int len)
+{
+ uint8_t addr[5];
+ uint8_t i = 0U;
+ uint8_t j;
+ int ret;
+
+ VERBOSE(">%s page %u offset %u buffer 0x%lx\n", __func__, page, offset,
+ buffer);
+
+ if (rawnand_dev.nand_dev->buswidth == NAND_BUS_WIDTH_16) {
+ offset /= 2U;
+ }
+
+ addr[i++] = offset;
+ addr[i++] = offset >> 8;
+
+ addr[i++] = page;
+ addr[i++] = page >> 8;
+ if (rawnand_dev.nand_dev->size > SZ_128M) {
+ addr[i++] = page >> 16;
+ }
+
+ ret = nand_send_cmd(NAND_CMD_READ_1ST, 0U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ for (j = 0U; j < i; j++) {
+ ret = nand_send_addr(addr[j], 0U);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ ret = nand_send_cmd(NAND_CMD_READ_2ND, NAND_TWB_MAX);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (buffer != 0U) {
+ ret = nand_read_data((uint8_t *)buffer, len, false);
+ }
+
+ return ret;
+}
+
+static int nand_status(uint8_t *status)
+{
+ int ret;
+
+ ret = nand_send_cmd(NAND_CMD_STATUS, NAND_TWHR_MIN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (status != NULL) {
+ ret = nand_read_data(status, 1U, true);
+ }
+
+ return ret;
+}
+
+int nand_wait_ready(unsigned long delay)
+{
+ uint8_t status;
+ int ret;
+ uint64_t timeout;
+
+ /* Wait before reading status */
+ udelay(1);
+
+ ret = nand_status(NULL);
+ if (ret != 0) {
+ return ret;
+ }
+
+ timeout = timeout_init_us(delay);
+ while (!timeout_elapsed(timeout)) {
+ ret = nand_read_data(&status, 1U, true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((status & NAND_STATUS_READY) != 0U) {
+ return nand_send_cmd(NAND_CMD_READ_1ST, 0U);
+ }
+
+ udelay(10);
+ }
+
+ return -ETIMEDOUT;
+}
+
+#if NAND_ONFI_DETECT
+static uint16_t nand_check_crc(uint16_t crc, uint8_t *data_in,
+ unsigned int data_len)
+{
+ uint32_t i;
+ uint32_t j;
+ uint32_t bit;
+
+ for (i = 0U; i < data_len; i++) {
+ uint8_t cur_param = *data_in++;
+
+ for (j = BIT(7); j != 0U; j >>= 1) {
+ bit = crc & BIT(15);
+ crc <<= 1;
+
+ if ((cur_param & j) != 0U) {
+ bit ^= BIT(15);
+ }
+
+ if (bit != 0U) {
+ crc ^= CRC_POLYNOM;
+ }
+ }
+
+ crc &= GENMASK(15, 0);
+ }
+
+ return crc;
+}
+
+static int nand_read_id(uint8_t addr, uint8_t *id, unsigned int size)
+{
+ int ret;
+
+ ret = nand_send_cmd(NAND_CMD_READID, 0U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_send_addr(addr, NAND_TWHR_MIN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return nand_read_data(id, size, true);
+}
+
+static int nand_reset(void)
+{
+ int ret;
+
+ ret = nand_send_cmd(NAND_CMD_RESET, NAND_TWB_MAX);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return nand_send_wait(PSEC_TO_MSEC(NAND_TRST_MAX), 0U);
+}
+
+static int nand_read_param_page(void)
+{
+ struct nand_param_page page;
+ uint8_t addr = 0U;
+ int ret;
+
+ ret = nand_send_cmd(NAND_CMD_READ_PARAM_PAGE, 0U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_send_addr(addr, NAND_TWB_MAX);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_send_wait(PSEC_TO_MSEC(NAND_TR_MAX), NAND_TRR_MIN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_read_data((uint8_t *)&page, sizeof(page), true);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (strncmp((char *)&page.page_sig, "ONFI", 4) != 0) {
+ WARN("Error ONFI detection\n");
+ return -EINVAL;
+ }
+
+ if (nand_check_crc(CRC_INIT_VALUE, (uint8_t *)&page, 254U) !=
+ page.crc16) {
+ WARN("Error reading param\n");
+ return -EINVAL;
+ }
+
+ if ((page.features & ONFI_FEAT_BUS_WIDTH_16) != 0U) {
+ rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_16;
+ } else {
+ rawnand_dev.nand_dev->buswidth = NAND_BUS_WIDTH_8;
+ }
+
+ rawnand_dev.nand_dev->block_size = page.num_pages_per_blk *
+ page.bytes_per_page;
+ rawnand_dev.nand_dev->page_size = page.bytes_per_page;
+ rawnand_dev.nand_dev->size = page.num_pages_per_blk *
+ page.bytes_per_page *
+ page.num_blk_in_lun * page.num_lun;
+
+ if (page.nb_ecc_bits != GENMASK_32(7, 0)) {
+ rawnand_dev.nand_dev->ecc.max_bit_corr = page.nb_ecc_bits;
+ rawnand_dev.nand_dev->ecc.size = SZ_512;
+ }
+
+ VERBOSE("Page size %u, block_size %u, Size %llu, ecc %u, buswidth %u\n",
+ rawnand_dev.nand_dev->page_size,
+ rawnand_dev.nand_dev->block_size, rawnand_dev.nand_dev->size,
+ rawnand_dev.nand_dev->ecc.max_bit_corr,
+ rawnand_dev.nand_dev->buswidth);
+
+ return 0;
+}
+
+static int detect_onfi(void)
+{
+ int ret;
+ char id[4];
+
+ ret = nand_reset();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = nand_read_id(ONFI_SIGNATURE_ADDR, (uint8_t *)id, sizeof(id));
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (strncmp(id, "ONFI", sizeof(id)) != 0) {
+ WARN("NAND Non ONFI detected\n");
+ return -ENODEV;
+ }
+
+ return nand_read_param_page();
+}
+#endif
+
+static int nand_mtd_block_is_bad(unsigned int block)
+{
+ unsigned int nbpages_per_block = rawnand_dev.nand_dev->block_size /
+ rawnand_dev.nand_dev->page_size;
+ uint8_t bbm_marker[2];
+ uint8_t page;
+ int ret;
+
+ for (page = 0U; page < 2U; page++) {
+ ret = nand_read_page_cmd(block * nbpages_per_block,
+ rawnand_dev.nand_dev->page_size,
+ (uintptr_t)bbm_marker,
+ sizeof(bbm_marker));
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((bbm_marker[0] != GENMASK_32(7, 0)) ||
+ (bbm_marker[1] != GENMASK_32(7, 0))) {
+ WARN("Block %u is bad\n", block);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int nand_mtd_read_page_raw(struct nand_device *nand, unsigned int page,
+ uintptr_t buffer)
+{
+ return nand_read_page_cmd(page, 0U, buffer,
+ rawnand_dev.nand_dev->page_size);
+}
+
+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops)
+{
+ rawnand_dev.ops = ops;
+}
+
+int nand_raw_init(unsigned long long *size, unsigned int *erase_size)
+{
+ rawnand_dev.nand_dev = get_nand_device();
+ if (rawnand_dev.nand_dev == NULL) {
+ return -EINVAL;
+ }
+
+ rawnand_dev.nand_dev->mtd_block_is_bad = nand_mtd_block_is_bad;
+ rawnand_dev.nand_dev->mtd_read_page = nand_mtd_read_page_raw;
+ rawnand_dev.nand_dev->ecc.mode = NAND_ECC_NONE;
+
+ if ((rawnand_dev.ops->setup == NULL) ||
+ (rawnand_dev.ops->exec == NULL)) {
+ return -ENODEV;
+ }
+
+#if NAND_ONFI_DETECT
+ if (detect_onfi() != 0) {
+ WARN("Detect ONFI failed\n");
+ }
+#endif
+
+ if (plat_get_raw_nand_data(&rawnand_dev) != 0) {
+ return -EINVAL;
+ }
+
+ assert((rawnand_dev.nand_dev->page_size != 0U) &&
+ (rawnand_dev.nand_dev->block_size != 0U) &&
+ (rawnand_dev.nand_dev->size != 0U));
+
+ *size = rawnand_dev.nand_dev->size;
+ *erase_size = rawnand_dev.nand_dev->block_size;
+
+ rawnand_dev.ops->setup(rawnand_dev.nand_dev);
+
+ return 0;
+}
diff --git a/drivers/mtd/nand/spi_nand.c b/drivers/mtd/nand/spi_nand.c
new file mode 100644
index 0000000000..d01a11963f
--- /dev/null
+++ b/drivers/mtd/nand/spi_nand.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_nand.h>
+#include <lib/utils.h>
+
+#define SPI_NAND_MAX_ID_LEN 4U
+#define DELAY_US_400MS 400000U
+#define MACRONIX_ID 0xC2U
+
+static struct spinand_device spinand_dev;
+
+#pragma weak plat_get_spi_nand_data
+int plat_get_spi_nand_data(struct spinand_device *device)
+{
+ return 0;
+}
+
+static int spi_nand_reg(bool read_reg, uint8_t reg, uint8_t *val,
+ enum spi_mem_data_dir dir)
+{
+ struct spi_mem_op op;
+
+ zeromem(&op, sizeof(struct spi_mem_op));
+ if (read_reg) {
+ op.cmd.opcode = SPI_NAND_OP_GET_FEATURE;
+ } else {
+ op.cmd.opcode = SPI_NAND_OP_SET_FEATURE;
+ }
+
+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.addr.val = reg;
+ op.addr.nbytes = 1U;
+ op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.data.dir = dir;
+ op.data.nbytes = 1U;
+ op.data.buf = val;
+
+ return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_read_reg(uint8_t reg, uint8_t *val)
+{
+ return spi_nand_reg(true, reg, val, SPI_MEM_DATA_IN);
+}
+
+static int spi_nand_write_reg(uint8_t reg, uint8_t val)
+{
+ return spi_nand_reg(false, reg, &val, SPI_MEM_DATA_OUT);
+}
+
+static int spi_nand_update_cfg(uint8_t mask, uint8_t val)
+{
+ int ret;
+ uint8_t cfg = spinand_dev.cfg_cache;
+
+ cfg &= ~mask;
+ cfg |= val;
+
+ if (cfg == spinand_dev.cfg_cache) {
+ return 0;
+ }
+
+ ret = spi_nand_write_reg(SPI_NAND_REG_CFG, cfg);
+ if (ret == 0) {
+ spinand_dev.cfg_cache = cfg;
+ }
+
+ return ret;
+}
+
+static int spi_nand_ecc_enable(bool enable)
+{
+ return spi_nand_update_cfg(SPI_NAND_CFG_ECC_EN,
+ enable ? SPI_NAND_CFG_ECC_EN : 0U);
+}
+
+static int spi_nand_quad_enable(uint8_t manufacturer_id)
+{
+ bool enable = false;
+
+ if (manufacturer_id != MACRONIX_ID) {
+ return 0;
+ }
+
+ if (spinand_dev.spi_read_cache_op.data.buswidth ==
+ SPI_MEM_BUSWIDTH_4_LINE) {
+ enable = true;
+ }
+
+ return spi_nand_update_cfg(SPI_NAND_CFG_QE,
+ enable ? SPI_NAND_CFG_QE : 0U);
+}
+
+static int spi_nand_wait_ready(uint8_t *status)
+{
+ int ret;
+ uint64_t timeout = timeout_init_us(DELAY_US_400MS);
+
+ while (!timeout_elapsed(timeout)) {
+ ret = spi_nand_read_reg(SPI_NAND_REG_STATUS, status);
+ if (ret != 0) {
+ return ret;
+ }
+
+ VERBOSE("%s Status %x\n", __func__, *status);
+ if ((*status & SPI_NAND_STATUS_BUSY) == 0U) {
+ return 0;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int spi_nand_reset(void)
+{
+ struct spi_mem_op op;
+ uint8_t status;
+ int ret;
+
+ zeromem(&op, sizeof(struct spi_mem_op));
+ op.cmd.opcode = SPI_NAND_OP_RESET;
+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+ ret = spi_mem_exec_op(&op);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return spi_nand_wait_ready(&status);
+}
+
+static int spi_nand_read_id(uint8_t *id)
+{
+ struct spi_mem_op op;
+
+ zeromem(&op, sizeof(struct spi_mem_op));
+ op.cmd.opcode = SPI_NAND_OP_READ_ID;
+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.data.dir = SPI_MEM_DATA_IN;
+ op.data.nbytes = SPI_NAND_MAX_ID_LEN;
+ op.data.buf = id;
+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+ return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_load_page(unsigned int page)
+{
+ struct spi_mem_op op;
+ uint32_t block_nb = page / spinand_dev.nand_dev->block_size;
+ uint32_t page_nb = page - (block_nb * spinand_dev.nand_dev->page_size);
+ uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size /
+ spinand_dev.nand_dev->page_size;
+ uint32_t block_sh = __builtin_ctz(nbpages_per_block) + 1U;
+
+ zeromem(&op, sizeof(struct spi_mem_op));
+ op.cmd.opcode = SPI_NAND_OP_LOAD_PAGE;
+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.addr.val = (block_nb << block_sh) | page_nb;
+ op.addr.nbytes = 3U;
+ op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+ return spi_mem_exec_op(&op);
+}
+
+static int spi_nand_read_from_cache(unsigned int page, unsigned int offset,
+ uint8_t *buffer, unsigned int len)
+{
+ uint32_t nbpages_per_block = spinand_dev.nand_dev->block_size /
+ spinand_dev.nand_dev->page_size;
+ uint32_t block_nb = page / nbpages_per_block;
+ uint32_t page_sh = __builtin_ctz(spinand_dev.nand_dev->page_size) + 1U;
+
+ spinand_dev.spi_read_cache_op.addr.val = offset;
+
+ if ((spinand_dev.nand_dev->nb_planes > 1U) && ((block_nb % 2U) == 1U)) {
+ spinand_dev.spi_read_cache_op.addr.val |= 1U << page_sh;
+ }
+
+ spinand_dev.spi_read_cache_op.data.buf = buffer;
+ spinand_dev.spi_read_cache_op.data.nbytes = len;
+
+ return spi_mem_exec_op(&spinand_dev.spi_read_cache_op);
+}
+
+static int spi_nand_read_page(unsigned int page, unsigned int offset,
+ uint8_t *buffer, unsigned int len,
+ bool ecc_enabled)
+{
+ uint8_t status;
+ int ret;
+
+ ret = spi_nand_ecc_enable(ecc_enabled);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_load_page(page);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_wait_ready(&status);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_read_from_cache(page, offset, buffer, len);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (ecc_enabled && ((status & SPI_NAND_STATUS_ECC_UNCOR) != 0U)) {
+ return -EBADMSG;
+ }
+
+ return 0;
+}
+
+static int spi_nand_mtd_block_is_bad(unsigned int block)
+{
+ unsigned int nbpages_per_block = spinand_dev.nand_dev->block_size /
+ spinand_dev.nand_dev->page_size;
+ uint8_t bbm_marker[2];
+ int ret;
+
+ ret = spi_nand_read_page(block * nbpages_per_block,
+ spinand_dev.nand_dev->page_size,
+ bbm_marker, sizeof(bbm_marker), false);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((bbm_marker[0] != GENMASK_32(7, 0)) ||
+ (bbm_marker[1] != GENMASK_32(7, 0))) {
+ WARN("Block %i is bad\n", block);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int spi_nand_mtd_read_page(struct nand_device *nand, unsigned int page,
+ uintptr_t buffer)
+{
+ return spi_nand_read_page(page, 0, (uint8_t *)buffer,
+ spinand_dev.nand_dev->page_size, true);
+}
+
+int spi_nand_init(unsigned long long *size, unsigned int *erase_size)
+{
+ uint8_t id[SPI_NAND_MAX_ID_LEN];
+ int ret;
+
+ spinand_dev.nand_dev = get_nand_device();
+ if (spinand_dev.nand_dev == NULL) {
+ return -EINVAL;
+ }
+
+ spinand_dev.nand_dev->mtd_block_is_bad = spi_nand_mtd_block_is_bad;
+ spinand_dev.nand_dev->mtd_read_page = spi_nand_mtd_read_page;
+ spinand_dev.nand_dev->nb_planes = 1;
+
+ spinand_dev.spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE;
+ spinand_dev.spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ spinand_dev.spi_read_cache_op.addr.nbytes = 2U;
+ spinand_dev.spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ spinand_dev.spi_read_cache_op.dummy.nbytes = 1U;
+ spinand_dev.spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ spinand_dev.spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+
+ if (plat_get_spi_nand_data(&spinand_dev) != 0) {
+ return -EINVAL;
+ }
+
+ ret = spi_nand_reset();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_read_id(id);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_read_reg(SPI_NAND_REG_CFG, &spinand_dev.cfg_cache);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nand_quad_enable(id[0]);
+ if (ret != 0) {
+ return ret;
+ }
+
+ VERBOSE("SPI_NAND Detected ID 0x%x 0x%x\n", id[0], id[1]);
+
+ VERBOSE("Page size %i, Block size %i, size %lli\n",
+ spinand_dev.nand_dev->page_size,
+ spinand_dev.nand_dev->block_size,
+ spinand_dev.nand_dev->size);
+
+ *size = spinand_dev.nand_dev->size;
+ *erase_size = spinand_dev.nand_dev->block_size;
+
+ return 0;
+}
diff --git a/drivers/mtd/nor/spi_nor.c b/drivers/mtd/nor/spi_nor.c
new file mode 100644
index 0000000000..22d3ae3d9e
--- /dev/null
+++ b/drivers/mtd/nor/spi_nor.c
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <stddef.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_nor.h>
+#include <lib/utils.h>
+
+#define SR_WIP BIT(0) /* Write in progress */
+#define CR_QUAD_EN_SPAN BIT(1) /* Spansion Quad I/O */
+#define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */
+#define FSR_READY BIT(7) /* Device status, 0 = Busy, 1 = Ready */
+
+/* Defined IDs for supported memories */
+#define SPANSION_ID 0x01U
+#define MACRONIX_ID 0xC2U
+#define MICRON_ID 0x2CU
+
+#define BANK_SIZE 0x1000000U
+
+#define SPI_READY_TIMEOUT_US 40000U
+
+static struct nor_device nor_dev;
+
+#pragma weak plat_get_nor_data
+int plat_get_nor_data(struct nor_device *device)
+{
+ return 0;
+}
+
+static int spi_nor_reg(uint8_t reg, uint8_t *buf, size_t len,
+ enum spi_mem_data_dir dir)
+{
+ struct spi_mem_op op;
+
+ zeromem(&op, sizeof(struct spi_mem_op));
+ op.cmd.opcode = reg;
+ op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ op.data.dir = dir;
+ op.data.nbytes = len;
+ op.data.buf = buf;
+
+ return spi_mem_exec_op(&op);
+}
+
+static inline int spi_nor_read_id(uint8_t *id)
+{
+ return spi_nor_reg(SPI_NOR_OP_READ_ID, id, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_cr(uint8_t *cr)
+{
+ return spi_nor_reg(SPI_NOR_OP_READ_CR, cr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_sr(uint8_t *sr)
+{
+ return spi_nor_reg(SPI_NOR_OP_READ_SR, sr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_read_fsr(uint8_t *fsr)
+{
+ return spi_nor_reg(SPI_NOR_OP_READ_FSR, fsr, 1U, SPI_MEM_DATA_IN);
+}
+
+static inline int spi_nor_write_en(void)
+{
+ return spi_nor_reg(SPI_NOR_OP_WREN, NULL, 0U, SPI_MEM_DATA_OUT);
+}
+
+/*
+ * Check if device is ready.
+ *
+ * Return 0 if ready, 1 if busy or a negative error code otherwise
+ */
+static int spi_nor_ready(void)
+{
+ uint8_t sr;
+ int ret;
+
+ ret = spi_nor_read_sr(&sr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((nor_dev.flags & SPI_NOR_USE_FSR) != 0U) {
+ uint8_t fsr;
+
+ ret = spi_nor_read_fsr(&fsr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return (((fsr & FSR_READY) != 0U) && ((sr & SR_WIP) == 0U)) ?
+ 0 : 1;
+ }
+
+ return (((sr & SR_WIP) != 0U) ? 1 : 0);
+}
+
+static int spi_nor_wait_ready(void)
+{
+ int ret;
+ uint64_t timeout = timeout_init_us(SPI_READY_TIMEOUT_US);
+
+ while (!timeout_elapsed(timeout)) {
+ ret = spi_nor_ready();
+ if (ret <= 0) {
+ return ret;
+ }
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int spi_nor_macronix_quad_enable(void)
+{
+ uint8_t sr;
+ int ret;
+
+ ret = spi_nor_read_sr(&sr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((sr & SR_QUAD_EN_MX) == 0U) {
+ return 0;
+ }
+
+ ret = spi_nor_write_en();
+ if (ret != 0) {
+ return ret;
+ }
+
+ sr |= SR_QUAD_EN_MX;
+ ret = spi_nor_reg(SPI_NOR_OP_WRSR, &sr, 1, SPI_MEM_DATA_OUT);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_wait_ready();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_read_sr(&sr);
+ if ((ret != 0) || ((sr & SR_QUAD_EN_MX) == 0U)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int spi_nor_write_sr_cr(uint8_t *sr_cr)
+{
+ int ret;
+
+ ret = spi_nor_write_en();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_reg(SPI_NOR_OP_WRSR, sr_cr, 2, SPI_MEM_DATA_OUT);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+
+ ret = spi_nor_wait_ready();
+ if (ret != 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int spi_nor_quad_enable(void)
+{
+ uint8_t sr_cr[2];
+ int ret;
+
+ ret = spi_nor_read_cr(&sr_cr[1]);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((sr_cr[1] & CR_QUAD_EN_SPAN) != 0U) {
+ return 0;
+ }
+
+ sr_cr[1] |= CR_QUAD_EN_SPAN;
+ ret = spi_nor_read_sr(&sr_cr[0]);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_write_sr_cr(sr_cr);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_read_cr(&sr_cr[1]);
+ if ((ret != 0) || ((sr_cr[1] & CR_QUAD_EN_SPAN) == 0U)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int spi_nor_clean_bar(void)
+{
+ int ret;
+
+ if (nor_dev.selected_bank == 0U) {
+ return 0;
+ }
+
+ nor_dev.selected_bank = 0U;
+
+ ret = spi_nor_write_en();
+ if (ret != 0) {
+ return ret;
+ }
+
+ return spi_nor_reg(nor_dev.bank_write_cmd, &nor_dev.selected_bank,
+ 1, SPI_MEM_DATA_OUT);
+}
+
+static int spi_nor_write_bar(uint32_t offset)
+{
+ uint8_t selected_bank = offset / BANK_SIZE;
+ int ret;
+
+ if (selected_bank == nor_dev.selected_bank) {
+ return 0;
+ }
+
+ ret = spi_nor_write_en();
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = spi_nor_reg(nor_dev.bank_write_cmd, &selected_bank,
+ 1, SPI_MEM_DATA_OUT);
+ if (ret != 0) {
+ return ret;
+ }
+
+ nor_dev.selected_bank = selected_bank;
+
+ return 0;
+}
+
+static int spi_nor_read_bar(void)
+{
+ uint8_t selected_bank = 0;
+ int ret;
+
+ ret = spi_nor_reg(nor_dev.bank_read_cmd, &selected_bank,
+ 1, SPI_MEM_DATA_IN);
+ if (ret != 0) {
+ return ret;
+ }
+
+ nor_dev.selected_bank = selected_bank;
+
+ return 0;
+}
+
+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length,
+ size_t *length_read)
+{
+ size_t remain_len;
+ int ret;
+
+ *length_read = 0;
+ nor_dev.read_op.addr.val = offset;
+ nor_dev.read_op.data.buf = (void *)buffer;
+
+ VERBOSE("%s offset %i length %zu\n", __func__, offset, length);
+
+ while (length != 0U) {
+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+ ret = spi_nor_write_bar(nor_dev.read_op.addr.val);
+ if (ret != 0) {
+ return ret;
+ }
+
+ remain_len = (BANK_SIZE * (nor_dev.selected_bank + 1)) -
+ nor_dev.read_op.addr.val;
+ nor_dev.read_op.data.nbytes = MIN(length, remain_len);
+ } else {
+ nor_dev.read_op.data.nbytes = length;
+ }
+
+ ret = spi_mem_exec_op(&nor_dev.read_op);
+ if (ret != 0) {
+ spi_nor_clean_bar();
+ return ret;
+ }
+
+ length -= nor_dev.read_op.data.nbytes;
+ nor_dev.read_op.addr.val += nor_dev.read_op.data.nbytes;
+ nor_dev.read_op.data.buf += nor_dev.read_op.data.nbytes;
+ *length_read += nor_dev.read_op.data.nbytes;
+ }
+
+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+ ret = spi_nor_clean_bar();
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int spi_nor_init(unsigned long long *size, unsigned int *erase_size)
+{
+ int ret = 0;
+ uint8_t id;
+
+ /* Default read command used */
+ nor_dev.read_op.cmd.opcode = SPI_NOR_OP_READ;
+ nor_dev.read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ nor_dev.read_op.addr.nbytes = 3U;
+ nor_dev.read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ nor_dev.read_op.data.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ nor_dev.read_op.data.dir = SPI_MEM_DATA_IN;
+
+ if (plat_get_nor_data(&nor_dev) != 0) {
+ return -EINVAL;
+ }
+
+ assert(nor_dev.size != 0);
+
+ if (nor_dev.size > BANK_SIZE) {
+ nor_dev.flags |= SPI_NOR_USE_BANK;
+ }
+
+ *size = nor_dev.size;
+
+ ret = spi_nor_read_id(&id);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U) {
+ switch (id) {
+ case SPANSION_ID:
+ nor_dev.bank_read_cmd = SPINOR_OP_BRRD;
+ nor_dev.bank_write_cmd = SPINOR_OP_BRWR;
+ break;
+ default:
+ nor_dev.bank_read_cmd = SPINOR_OP_RDEAR;
+ nor_dev.bank_write_cmd = SPINOR_OP_WREAR;
+ break;
+ }
+ }
+
+ if (nor_dev.read_op.data.buswidth == 4U) {
+ switch (id) {
+ case MACRONIX_ID:
+ WARN("Enable Macronix quad support\n");
+ ret = spi_nor_macronix_quad_enable();
+ break;
+ case MICRON_ID:
+ break;
+ default:
+ ret = spi_nor_quad_enable();
+ break;
+ }
+ }
+
+ if ((ret == 0) && ((nor_dev.flags & SPI_NOR_USE_BANK) != 0U)) {
+ ret = spi_nor_read_bar();
+ }
+
+ return ret;
+}
diff --git a/drivers/mtd/spi-mem/spi_mem.c b/drivers/mtd/spi-mem/spi_mem.c
new file mode 100644
index 0000000000..63ea7699b8
--- /dev/null
+++ b/drivers/mtd/spi-mem/spi_mem.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <libfdt.h>
+
+#include <drivers/spi_mem.h>
+#include <lib/utils_def.h>
+
+#define SPI_MEM_DEFAULT_SPEED_HZ 100000U
+
+/*
+ * struct spi_slave - Representation of a SPI slave.
+ *
+ * @max_hz: Maximum speed for this slave in Hertz.
+ * @cs: ID of the chip select connected to the slave.
+ * @mode: SPI mode to use for this slave (see SPI mode flags).
+ * @ops: Ops defined by the bus.
+ */
+struct spi_slave {
+ unsigned int max_hz;
+ unsigned int cs;
+ unsigned int mode;
+ const struct spi_bus_ops *ops;
+};
+
+static struct spi_slave spi_slave;
+
+static bool spi_mem_check_buswidth_req(uint8_t buswidth, bool tx)
+{
+ switch (buswidth) {
+ case 1U:
+ return true;
+
+ case 2U:
+ if ((tx && (spi_slave.mode & (SPI_TX_DUAL | SPI_TX_QUAD)) !=
+ 0U) ||
+ (!tx && (spi_slave.mode & (SPI_RX_DUAL | SPI_RX_QUAD)) !=
+ 0U)) {
+ return true;
+ }
+ break;
+
+ case 4U:
+ if ((tx && (spi_slave.mode & SPI_TX_QUAD) != 0U) ||
+ (!tx && (spi_slave.mode & SPI_RX_QUAD) != 0U)) {
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static bool spi_mem_supports_op(const struct spi_mem_op *op)
+{
+ if (!spi_mem_check_buswidth_req(op->cmd.buswidth, true)) {
+ return false;
+ }
+
+ if ((op->addr.nbytes != 0U) &&
+ !spi_mem_check_buswidth_req(op->addr.buswidth, true)) {
+ return false;
+ }
+
+ if ((op->dummy.nbytes != 0U) &&
+ !spi_mem_check_buswidth_req(op->dummy.buswidth, true)) {
+ return false;
+ }
+
+ if ((op->data.nbytes != 0U) &&
+ !spi_mem_check_buswidth_req(op->data.buswidth,
+ op->data.dir == SPI_MEM_DATA_OUT)) {
+ return false;
+ }
+
+ return true;
+}
+
+static int spi_mem_set_speed_mode(void)
+{
+ const struct spi_bus_ops *ops = spi_slave.ops;
+ int ret;
+
+ ret = ops->set_speed(spi_slave.max_hz);
+ if (ret != 0) {
+ VERBOSE("Cannot set speed (err=%d)\n", ret);
+ return ret;
+ }
+
+ ret = ops->set_mode(spi_slave.mode);
+ if (ret != 0) {
+ VERBOSE("Cannot set mode (err=%d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int spi_mem_check_bus_ops(const struct spi_bus_ops *ops)
+{
+ bool error = false;
+
+ if (ops->claim_bus == NULL) {
+ VERBOSE("Ops claim bus is not defined\n");
+ error = true;
+ }
+
+ if (ops->release_bus == NULL) {
+ VERBOSE("Ops release bus is not defined\n");
+ error = true;
+ }
+
+ if (ops->exec_op == NULL) {
+ VERBOSE("Ops exec op is not defined\n");
+ error = true;
+ }
+
+ if (ops->set_speed == NULL) {
+ VERBOSE("Ops set speed is not defined\n");
+ error = true;
+ }
+
+ if (ops->set_mode == NULL) {
+ VERBOSE("Ops set mode is not defined\n");
+ error = true;
+ }
+
+ return error ? -EINVAL : 0;
+}
+
+/*
+ * spi_mem_exec_op() - Execute a memory operation.
+ * @op: The memory operation to execute.
+ *
+ * This function first checks that @op is supported and then tries to execute
+ * it.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_mem_exec_op(const struct spi_mem_op *op)
+{
+ const struct spi_bus_ops *ops = spi_slave.ops;
+ int ret;
+
+ VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addqr:%llx len:%x\n",
+ __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+ op->dummy.buswidth, op->data.buswidth,
+ op->addr.val, op->data.nbytes);
+
+ if (!spi_mem_supports_op(op)) {
+ WARN("Error in spi_mem_support\n");
+ return -ENOTSUP;
+ }
+
+ ret = ops->claim_bus(spi_slave.cs);
+ if (ret != 0) {
+ WARN("Error claim_bus\n");
+ return ret;
+ }
+
+ ret = ops->exec_op(op);
+
+ ops->release_bus();
+
+ return ret;
+}
+
+/*
+ * spi_mem_init_slave() - SPI slave device initialization.
+ * @fdt: Pointer to the device tree blob.
+ * @bus_node: Offset of the bus node.
+ * @ops: The SPI bus ops defined.
+ *
+ * This function first checks that @ops are supported and then tries to find
+ * a SPI slave device.
+ *
+ * Return: 0 in case of success, a negative error code otherwise.
+ */
+int spi_mem_init_slave(void *fdt, int bus_node, const struct spi_bus_ops *ops)
+{
+ int ret;
+ int mode = 0;
+ int nchips = 0;
+ int bus_subnode = 0;
+ const fdt32_t *cuint = NULL;
+
+ ret = spi_mem_check_bus_ops(ops);
+ if (ret != 0) {
+ return ret;
+ }
+
+ fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
+ nchips++;
+ }
+
+ if (nchips != 1) {
+ ERROR("Only one SPI device is currently supported\n");
+ return -EINVAL;
+ }
+
+ fdt_for_each_subnode(bus_subnode, fdt, bus_node) {
+ /* Get chip select */
+ cuint = fdt_getprop(fdt, bus_subnode, "reg", NULL);
+ if (cuint == NULL) {
+ ERROR("Chip select not well defined\n");
+ return -EINVAL;
+ }
+ spi_slave.cs = fdt32_to_cpu(*cuint);
+
+ /* Get max slave frequency */
+ spi_slave.max_hz = SPI_MEM_DEFAULT_SPEED_HZ;
+ cuint = fdt_getprop(fdt, bus_subnode,
+ "spi-max-frequency", NULL);
+ if (cuint != NULL) {
+ spi_slave.max_hz = fdt32_to_cpu(*cuint);
+ }
+
+ /* Get mode */
+ if ((fdt_getprop(fdt, bus_subnode, "spi-cpol", NULL)) != NULL) {
+ mode |= SPI_CPOL;
+ }
+ if ((fdt_getprop(fdt, bus_subnode, "spi-cpha", NULL)) != NULL) {
+ mode |= SPI_CPHA;
+ }
+ if ((fdt_getprop(fdt, bus_subnode, "spi-cs-high", NULL)) !=
+ NULL) {
+ mode |= SPI_CS_HIGH;
+ }
+ if ((fdt_getprop(fdt, bus_subnode, "spi-3wire", NULL)) !=
+ NULL) {
+ mode |= SPI_3WIRE;
+ }
+ if ((fdt_getprop(fdt, bus_subnode, "spi-half-duplex", NULL)) !=
+ NULL) {
+ mode |= SPI_PREAMBLE;
+ }
+
+ /* Get dual/quad mode */
+ cuint = fdt_getprop(fdt, bus_subnode, "spi-tx-bus-width", NULL);
+ if (cuint != NULL) {
+ switch (fdt32_to_cpu(*cuint)) {
+ case 1U:
+ break;
+ case 2U:
+ mode |= SPI_TX_DUAL;
+ break;
+ case 4U:
+ mode |= SPI_TX_QUAD;
+ break;
+ default:
+ WARN("spi-tx-bus-width %d not supported\n",
+ fdt32_to_cpu(*cuint));
+ return -EINVAL;
+ }
+ }
+
+ cuint = fdt_getprop(fdt, bus_subnode, "spi-rx-bus-width", NULL);
+ if (cuint != NULL) {
+ switch (fdt32_to_cpu(*cuint)) {
+ case 1U:
+ break;
+ case 2U:
+ mode |= SPI_RX_DUAL;
+ break;
+ case 4U:
+ mode |= SPI_RX_QUAD;
+ break;
+ default:
+ WARN("spi-rx-bus-width %d not supported\n",
+ fdt32_to_cpu(*cuint));
+ return -EINVAL;
+ }
+ }
+
+ spi_slave.mode = mode;
+ spi_slave.ops = ops;
+ }
+
+ return spi_mem_set_speed_mode();
+}
diff --git a/drivers/staging/renesas/rcar/ddr/boot_init_dram.h b/drivers/renesas/rcar/ddr/boot_init_dram.h
index ac237b2efc..ac237b2efc 100644
--- a/drivers/staging/renesas/rcar/ddr/boot_init_dram.h
+++ b/drivers/renesas/rcar/ddr/boot_init_dram.h
diff --git a/drivers/renesas/rcar/ddr/ddr.mk b/drivers/renesas/rcar/ddr/ddr.mk
new file mode 100644
index 0000000000..c26993d004
--- /dev/null
+++ b/drivers/renesas/rcar/ddr/ddr.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${RCAR_LSI},${RCAR_E3})
+ include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+ BL2_SOURCES += drivers/renesas/rcar/ddr/dram_sub_func.c
+else ifeq (${RCAR_LSI},${RCAR_D3})
+ include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+else ifeq (${RCAR_LSI},${RCAR_V3M})
+ include drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
+else
+ include drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
+ BL2_SOURCES += drivers/renesas/rcar/ddr/dram_sub_func.c
+endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
index 0f89b4350a..0f89b4350a 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
+++ b/drivers/renesas/rcar/ddr/ddr_a/boot_init_dram_regdef.h
diff --git a/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk b/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
new file mode 100644
index 0000000000..7882558d0c
--- /dev/null
+++ b/drivers/renesas/rcar/ddr/ddr_a/ddr_a.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+ifeq (${RCAR_LSI},${RCAR_E3})
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
+else ifeq (${RCAR_LSI},${RCAR_D3})
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
+else
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
+endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
index a49510ed5d..a49510ed5d 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
+++ b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
index fc278ef57c..fc278ef57c 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
+++ b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
index 5410771c92..5410771c92 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
+++ b/drivers/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
index 1d6e83a2c7..1d6e83a2c7 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
index f8caade273..f8caade273 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_config.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
index 5047e5cc20..5047e5cc20 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/boot_init_dram_regdef.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk b/drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
index 875f95339c..2bcc2922de 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk
+++ b/drivers/renesas/rcar/ddr/ddr_b/ddr_b.mk
@@ -4,4 +4,4 @@
# SPDX-License-Identifier: BSD-3-Clause
#
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_b/boot_init_dram.c
+BL2_SOURCES += drivers/renesas/rcar/ddr/ddr_b/boot_init_dram.c
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_regdef.h b/drivers/renesas/rcar/ddr/ddr_b/ddr_regdef.h
index adf8dab18e..adf8dab18e 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/ddr_regdef.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/ddr_regdef.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
index 357f8bad0d..357f8bad0d 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
index e5258af6c6..e5258af6c6 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_h3ver2.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
index b491f0e917..b491f0e917 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
index 8d80842fd1..8d80842fd1 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
+++ b/drivers/renesas/rcar/ddr/ddr_b/init_dram_tbl_m3n.h
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_regs.h b/drivers/renesas/rcar/ddr/ddr_regs.h
index ba26c69c8b..ba26c69c8b 100644
--- a/drivers/staging/renesas/rcar/ddr/ddr_regs.h
+++ b/drivers/renesas/rcar/ddr/ddr_regs.h
diff --git a/drivers/staging/renesas/rcar/ddr/dram_sub_func.c b/drivers/renesas/rcar/ddr/dram_sub_func.c
index ab8eabbc6d..ab8eabbc6d 100644
--- a/drivers/staging/renesas/rcar/ddr/dram_sub_func.c
+++ b/drivers/renesas/rcar/ddr/dram_sub_func.c
diff --git a/drivers/staging/renesas/rcar/ddr/dram_sub_func.h b/drivers/renesas/rcar/ddr/dram_sub_func.h
index 69c4d86053..69c4d86053 100644
--- a/drivers/staging/renesas/rcar/ddr/dram_sub_func.h
+++ b/drivers/renesas/rcar/ddr/dram_sub_func.h
diff --git a/drivers/renesas/rcar/io/io_emmcdrv.c b/drivers/renesas/rcar/io/io_emmcdrv.c
index 4b464fb3e4..84240d2606 100644
--- a/drivers/renesas/rcar/io/io_emmcdrv.c
+++ b/drivers/renesas/rcar/io/io_emmcdrv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,7 +25,7 @@ static int32_t emmcdrv_dev_close(io_dev_info_t *dev_info);
typedef struct {
uint32_t in_use;
uintptr_t base;
- ssize_t file_pos;
+ signed long long file_pos;
EMMC_PARTITION_ID partition;
} file_state_t;
@@ -39,7 +39,7 @@ static io_type_t device_type_emmcdrv(void)
}
static int32_t emmcdrv_block_seek(io_entity_t *entity, int32_t mode,
- ssize_t offset)
+ signed long long offset)
{
if (mode != IO_SEEK_SET)
return IO_FAIL;
@@ -59,12 +59,12 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer,
sector_add = current_file.file_pos >> EMMC_SECTOR_SIZE_SHIFT;
sector_num = (length + EMMC_SECTOR_SIZE - 1U) >> EMMC_SECTOR_SIZE_SHIFT;
- NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%lx(%d) len=0x%lx(%d)\n",
+ NOTICE("BL2: Load dst=0x%lx src=(p:%d)0x%llx(%d) len=0x%lx(%d)\n",
buffer,
current_file.partition, current_file.file_pos,
sector_add, length, sector_num);
- if (buffer + length - 1 <= UINT32_MAX)
+ if ((buffer + length - 1U) <= (uintptr_t)UINT32_MAX)
emmc_dma = LOADIMAGE_FLAGS_DMA_ENABLE;
if (emmc_read_sector((uint32_t *) buffer, sector_add, sector_num,
@@ -72,7 +72,7 @@ static int32_t emmcdrv_block_read(io_entity_t *entity, uintptr_t buffer,
result = IO_FAIL;
*length_read = length;
- fp->file_pos += length;
+ fp->file_pos += (signed long long)length;
return result;
}
@@ -82,7 +82,7 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info,
{
const io_drv_spec_t *block_spec = (io_drv_spec_t *) spec;
- if (current_file.in_use) {
+ if (current_file.in_use != 0U) {
WARN("mmc_block: Only one open spec at a time\n");
return IO_RESOURCES_EXHAUSTED;
}
@@ -103,9 +103,9 @@ static int32_t emmcdrv_block_open(io_dev_info_t *dev_info,
return IO_FAIL;
}
- if (PARTITION_ID_USER == block_spec->partition ||
- PARTITION_ID_BOOT_1 == block_spec->partition ||
- PARTITION_ID_BOOT_2 == block_spec->partition)
+ if ((PARTITION_ID_USER == block_spec->partition) ||
+ (PARTITION_ID_BOOT_1 == block_spec->partition) ||
+ (PARTITION_ID_BOOT_2 == block_spec->partition))
current_file.partition = block_spec->partition;
else
current_file.partition = emmcdrv_bootpartition;
diff --git a/drivers/renesas/rcar/io/io_memdrv.c b/drivers/renesas/rcar/io/io_memdrv.c
index 3f6b4c71b1..7e8c1d3a65 100644
--- a/drivers/renesas/rcar/io/io_memdrv.c
+++ b/drivers/renesas/rcar/io/io_memdrv.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,7 +28,7 @@ static int32_t memdrv_dev_close(io_dev_info_t *dev_info);
typedef struct {
uint32_t in_use;
uintptr_t base;
- ssize_t file_pos;
+ signed long long file_pos;
} file_state_t;
static file_state_t current_file = { 0 };
@@ -47,7 +47,7 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
* spec at a time. When we have dynamic memory we can malloc and set
* entity->info.
*/
- if (current_file.in_use)
+ if (current_file.in_use != 0U)
return IO_RESOURCES_EXHAUSTED;
/* File cursor offset for seek and incremental reads etc. */
@@ -61,7 +61,7 @@ static int32_t memdrv_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
}
static int32_t memdrv_block_seek(io_entity_t *entity, int32_t mode,
- ssize_t offset)
+ signed long long offset)
{
if (mode != IO_SEEK_SET)
return IO_FAIL;
@@ -78,16 +78,17 @@ static int32_t memdrv_block_read(io_entity_t *entity, uintptr_t buffer,
fp = (file_state_t *) entity->info;
- NOTICE("BL2: dst=0x%lx src=0x%lx len=%ld(0x%lx)\n",
- buffer, fp->base + fp->file_pos, length, length);
+ NOTICE("BL2: dst=0x%lx src=0x%llx len=%ld(0x%lx)\n",
+ buffer, (unsigned long long)fp->base +
+ (unsigned long long)fp->file_pos, length, length);
- if (FLASH_MEMORY_SIZE < fp->file_pos + length) {
+ if (FLASH_MEMORY_SIZE < (fp->file_pos + (signed long long)length)) {
ERROR("BL2: check load image (source address)\n");
return IO_FAIL;
}
- rcar_dma_exec(buffer, fp->base + fp->file_pos, length);
- fp->file_pos += length;
+ rcar_dma_exec(buffer, fp->base + (uintptr_t)fp->file_pos, length);
+ fp->file_pos += (signed long long)length;
*cnt = length;
return IO_SUCCESS;
diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/rcar/io/io_rcar.c
index 650931bb45..b82c510780 100644
--- a/drivers/renesas/rcar/io/io_rcar.c
+++ b/drivers/renesas/rcar/io/io_rcar.c
@@ -28,9 +28,6 @@
extern int32_t plat_get_drv_source(uint32_t id, uintptr_t *dev,
uintptr_t *image_spec);
-extern int auth_mod_verify_img(unsigned int img_id, void *ptr,
- unsigned int len);
-
static int32_t rcar_dev_open(const uintptr_t dev_spec __attribute__ ((unused)),
io_dev_info_t **dev_info);
static int32_t rcar_dev_close(io_dev_info_t *dev_info);
diff --git a/drivers/st/fmc/stm32_fmc2_nand.c b/drivers/st/fmc/stm32_fmc2_nand.c
new file mode 100644
index 0000000000..b694fff6bf
--- /dev/null
+++ b/drivers/st/fmc/stm32_fmc2_nand.c
@@ -0,0 +1,877 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/raw_nand.h>
+#include <drivers/st/stm32_fmc2_nand.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/* FMC2 Compatibility */
+#define DT_FMC2_COMPAT "st,stm32mp15-fmc2"
+#define MAX_CS 2U
+
+/* FMC2 Controller Registers */
+#define FMC2_BCR1 0x00U
+#define FMC2_PCR 0x80U
+#define FMC2_SR 0x84U
+#define FMC2_PMEM 0x88U
+#define FMC2_PATT 0x8CU
+#define FMC2_HECCR 0x94U
+#define FMC2_BCHISR 0x254U
+#define FMC2_BCHDSR0 0x27CU
+#define FMC2_BCHDSR1 0x280U
+#define FMC2_BCHDSR2 0x284U
+#define FMC2_BCHDSR3 0x288U
+#define FMC2_BCHDSR4 0x28CU
+
+/* FMC2_BCR1 register */
+#define FMC2_BCR1_FMC2EN BIT(31)
+/* FMC2_PCR register */
+#define FMC2_PCR_PWAITEN BIT(1)
+#define FMC2_PCR_PBKEN BIT(2)
+#define FMC2_PCR_PWID_MASK GENMASK_32(5, 4)
+#define FMC2_PCR_PWID(x) (((x) << 4) & FMC2_PCR_PWID_MASK)
+#define FMC2_PCR_PWID_8 0x0U
+#define FMC2_PCR_PWID_16 0x1U
+#define FMC2_PCR_ECCEN BIT(6)
+#define FMC2_PCR_ECCALG BIT(8)
+#define FMC2_PCR_TCLR_MASK GENMASK_32(12, 9)
+#define FMC2_PCR_TCLR(x) (((x) << 9) & FMC2_PCR_TCLR_MASK)
+#define FMC2_PCR_TCLR_DEFAULT 0xFU
+#define FMC2_PCR_TAR_MASK GENMASK_32(16, 13)
+#define FMC2_PCR_TAR(x) (((x) << 13) & FMC2_PCR_TAR_MASK)
+#define FMC2_PCR_TAR_DEFAULT 0xFU
+#define FMC2_PCR_ECCSS_MASK GENMASK_32(19, 17)
+#define FMC2_PCR_ECCSS(x) (((x) << 17) & FMC2_PCR_ECCSS_MASK)
+#define FMC2_PCR_ECCSS_512 0x1U
+#define FMC2_PCR_ECCSS_2048 0x3U
+#define FMC2_PCR_BCHECC BIT(24)
+#define FMC2_PCR_WEN BIT(25)
+/* FMC2_SR register */
+#define FMC2_SR_NWRF BIT(6)
+/* FMC2_PMEM register*/
+#define FMC2_PMEM_MEMSET(x) (((x) & GENMASK_32(7, 0)) << 0)
+#define FMC2_PMEM_MEMWAIT(x) (((x) & GENMASK_32(7, 0)) << 8)
+#define FMC2_PMEM_MEMHOLD(x) (((x) & GENMASK_32(7, 0)) << 16)
+#define FMC2_PMEM_MEMHIZ(x) (((x) & GENMASK_32(7, 0)) << 24)
+#define FMC2_PMEM_DEFAULT 0x0A0A0A0AU
+/* FMC2_PATT register */
+#define FMC2_PATT_ATTSET(x) (((x) & GENMASK_32(7, 0)) << 0)
+#define FMC2_PATT_ATTWAIT(x) (((x) & GENMASK_32(7, 0)) << 8)
+#define FMC2_PATT_ATTHOLD(x) (((x) & GENMASK_32(7, 0)) << 16)
+#define FMC2_PATT_ATTHIZ(x) (((x) & GENMASK_32(7, 0)) << 24)
+#define FMC2_PATT_DEFAULT 0x0A0A0A0AU
+/* FMC2_BCHISR register */
+#define FMC2_BCHISR_DERF BIT(1)
+/* FMC2_BCHDSR0 register */
+#define FMC2_BCHDSR0_DUE BIT(0)
+#define FMC2_BCHDSR0_DEF BIT(1)
+#define FMC2_BCHDSR0_DEN_MASK GENMASK_32(7, 4)
+#define FMC2_BCHDSR0_DEN_SHIFT 4U
+/* FMC2_BCHDSR1 register */
+#define FMC2_BCHDSR1_EBP1_MASK GENMASK_32(12, 0)
+#define FMC2_BCHDSR1_EBP2_MASK GENMASK_32(28, 16)
+#define FMC2_BCHDSR1_EBP2_SHIFT 16U
+/* FMC2_BCHDSR2 register */
+#define FMC2_BCHDSR2_EBP3_MASK GENMASK_32(12, 0)
+#define FMC2_BCHDSR2_EBP4_MASK GENMASK_32(28, 16)
+#define FMC2_BCHDSR2_EBP4_SHIFT 16U
+/* FMC2_BCHDSR3 register */
+#define FMC2_BCHDSR3_EBP5_MASK GENMASK_32(12, 0)
+#define FMC2_BCHDSR3_EBP6_MASK GENMASK_32(28, 16)
+#define FMC2_BCHDSR3_EBP6_SHIFT 16U
+/* FMC2_BCHDSR4 register */
+#define FMC2_BCHDSR4_EBP7_MASK GENMASK_32(12, 0)
+#define FMC2_BCHDSR4_EBP8_MASK GENMASK_32(28, 16)
+#define FMC2_BCHDSR4_EBP8_SHIFT 16U
+
+/* Timings */
+#define FMC2_THIZ 0x01U
+#define FMC2_TIO 8000U
+#define FMC2_TSYNC 3000U
+#define FMC2_PCR_TIMING_MASK GENMASK_32(3, 0)
+#define FMC2_PMEM_PATT_TIMING_MASK GENMASK_32(7, 0)
+
+#define FMC2_BBM_LEN 2U
+#define FMC2_MAX_ECC_BYTES 14U
+#define TIMEOUT_US_10_MS 10000U
+#define FMC2_PSEC_PER_MSEC (1000UL * 1000UL * 1000UL)
+
+enum stm32_fmc2_ecc {
+ FMC2_ECC_HAM = 1U,
+ FMC2_ECC_BCH4 = 4U,
+ FMC2_ECC_BCH8 = 8U
+};
+
+struct stm32_fmc2_cs_reg {
+ uintptr_t data_base;
+ uintptr_t cmd_base;
+ uintptr_t addr_base;
+};
+
+struct stm32_fmc2_nand_timings {
+ uint8_t tclr;
+ uint8_t tar;
+ uint8_t thiz;
+ uint8_t twait;
+ uint8_t thold_mem;
+ uint8_t tset_mem;
+ uint8_t thold_att;
+ uint8_t tset_att;
+};
+
+struct stm32_fmc2_nfc {
+ uintptr_t reg_base;
+ struct stm32_fmc2_cs_reg cs[MAX_CS];
+ unsigned long clock_id;
+ unsigned int reset_id;
+ uint8_t cs_sel;
+};
+
+static struct stm32_fmc2_nfc stm32_fmc2;
+
+static uintptr_t fmc2_base(void)
+{
+ return stm32_fmc2.reg_base;
+}
+
+static void stm32_fmc2_nand_setup_timing(void)
+{
+ struct stm32_fmc2_nand_timings tims;
+ unsigned long hclk = stm32mp_clk_get_rate(stm32_fmc2.clock_id);
+ unsigned long hclkp = FMC2_PSEC_PER_MSEC / (hclk / 1000U);
+ unsigned long timing, tar, tclr, thiz, twait;
+ unsigned long tset_mem, tset_att, thold_mem, thold_att;
+ uint32_t pcr, pmem, patt;
+
+ tar = MAX(hclkp, NAND_TAR_MIN);
+ timing = div_round_up(tar, hclkp) - 1U;
+ tims.tar = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
+
+ tclr = MAX(hclkp, NAND_TCLR_MIN);
+ timing = div_round_up(tclr, hclkp) - 1U;
+ tims.tclr = MIN(timing, (unsigned long)FMC2_PCR_TIMING_MASK);
+
+ tims.thiz = FMC2_THIZ;
+ thiz = (tims.thiz + 1U) * hclkp;
+
+ /*
+ * tWAIT > tRP
+ * tWAIT > tWP
+ * tWAIT > tREA + tIO
+ */
+ twait = MAX(hclkp, NAND_TRP_MIN);
+ twait = MAX(twait, NAND_TWP_MIN);
+ twait = MAX(twait, NAND_TREA_MAX + FMC2_TIO);
+ timing = div_round_up(twait, hclkp);
+ tims.twait = CLAMP(timing, 1UL,
+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+ /*
+ * tSETUP_MEM > tCS - tWAIT
+ * tSETUP_MEM > tALS - tWAIT
+ * tSETUP_MEM > tDS - (tWAIT - tHIZ)
+ */
+ tset_mem = hclkp;
+ if ((twait < NAND_TCS_MIN) && (tset_mem < (NAND_TCS_MIN - twait))) {
+ tset_mem = NAND_TCS_MIN - twait;
+ }
+ if ((twait < NAND_TALS_MIN) && (tset_mem < (NAND_TALS_MIN - twait))) {
+ tset_mem = NAND_TALS_MIN - twait;
+ }
+ if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
+ (tset_mem < (NAND_TDS_MIN - (twait - thiz)))) {
+ tset_mem = NAND_TDS_MIN - (twait - thiz);
+ }
+ timing = div_round_up(tset_mem, hclkp);
+ tims.tset_mem = CLAMP(timing, 1UL,
+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+ /*
+ * tHOLD_MEM > tCH
+ * tHOLD_MEM > tREH - tSETUP_MEM
+ * tHOLD_MEM > max(tRC, tWC) - (tSETUP_MEM + tWAIT)
+ */
+ thold_mem = MAX(hclkp, NAND_TCH_MIN);
+ if ((tset_mem < NAND_TREH_MIN) &&
+ (thold_mem < (NAND_TREH_MIN - tset_mem))) {
+ thold_mem = NAND_TREH_MIN - tset_mem;
+ }
+ if (((tset_mem + twait) < NAND_TRC_MIN) &&
+ (thold_mem < (NAND_TRC_MIN - (tset_mem + twait)))) {
+ thold_mem = NAND_TRC_MIN - (tset_mem + twait);
+ }
+ if (((tset_mem + twait) < NAND_TWC_MIN) &&
+ (thold_mem < (NAND_TWC_MIN - (tset_mem + twait)))) {
+ thold_mem = NAND_TWC_MIN - (tset_mem + twait);
+ }
+ timing = div_round_up(thold_mem, hclkp);
+ tims.thold_mem = CLAMP(timing, 1UL,
+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+ /*
+ * tSETUP_ATT > tCS - tWAIT
+ * tSETUP_ATT > tCLS - tWAIT
+ * tSETUP_ATT > tALS - tWAIT
+ * tSETUP_ATT > tRHW - tHOLD_MEM
+ * tSETUP_ATT > tDS - (tWAIT - tHIZ)
+ */
+ tset_att = hclkp;
+ if ((twait < NAND_TCS_MIN) && (tset_att < (NAND_TCS_MIN - twait))) {
+ tset_att = NAND_TCS_MIN - twait;
+ }
+ if ((twait < NAND_TCLS_MIN) && (tset_att < (NAND_TCLS_MIN - twait))) {
+ tset_att = NAND_TCLS_MIN - twait;
+ }
+ if ((twait < NAND_TALS_MIN) && (tset_att < (NAND_TALS_MIN - twait))) {
+ tset_att = NAND_TALS_MIN - twait;
+ }
+ if ((thold_mem < NAND_TRHW_MIN) &&
+ (tset_att < (NAND_TRHW_MIN - thold_mem))) {
+ tset_att = NAND_TRHW_MIN - thold_mem;
+ }
+ if ((twait > thiz) && ((twait - thiz) < NAND_TDS_MIN) &&
+ (tset_att < (NAND_TDS_MIN - (twait - thiz)))) {
+ tset_att = NAND_TDS_MIN - (twait - thiz);
+ }
+ timing = div_round_up(tset_att, hclkp);
+ tims.tset_att = CLAMP(timing, 1UL,
+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+ /*
+ * tHOLD_ATT > tALH
+ * tHOLD_ATT > tCH
+ * tHOLD_ATT > tCLH
+ * tHOLD_ATT > tCOH
+ * tHOLD_ATT > tDH
+ * tHOLD_ATT > tWB + tIO + tSYNC - tSETUP_MEM
+ * tHOLD_ATT > tADL - tSETUP_MEM
+ * tHOLD_ATT > tWH - tSETUP_MEM
+ * tHOLD_ATT > tWHR - tSETUP_MEM
+ * tHOLD_ATT > tRC - (tSETUP_ATT + tWAIT)
+ * tHOLD_ATT > tWC - (tSETUP_ATT + tWAIT)
+ */
+ thold_att = MAX(hclkp, NAND_TALH_MIN);
+ thold_att = MAX(thold_att, NAND_TCH_MIN);
+ thold_att = MAX(thold_att, NAND_TCLH_MIN);
+ thold_att = MAX(thold_att, NAND_TCOH_MIN);
+ thold_att = MAX(thold_att, NAND_TDH_MIN);
+ if (((NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC) > tset_mem) &&
+ (thold_att < (NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem))) {
+ thold_att = NAND_TWB_MAX + FMC2_TIO + FMC2_TSYNC - tset_mem;
+ }
+ if ((tset_mem < NAND_TADL_MIN) &&
+ (thold_att < (NAND_TADL_MIN - tset_mem))) {
+ thold_att = NAND_TADL_MIN - tset_mem;
+ }
+ if ((tset_mem < NAND_TWH_MIN) &&
+ (thold_att < (NAND_TWH_MIN - tset_mem))) {
+ thold_att = NAND_TWH_MIN - tset_mem;
+ }
+ if ((tset_mem < NAND_TWHR_MIN) &&
+ (thold_att < (NAND_TWHR_MIN - tset_mem))) {
+ thold_att = NAND_TWHR_MIN - tset_mem;
+ }
+ if (((tset_att + twait) < NAND_TRC_MIN) &&
+ (thold_att < (NAND_TRC_MIN - (tset_att + twait)))) {
+ thold_att = NAND_TRC_MIN - (tset_att + twait);
+ }
+ if (((tset_att + twait) < NAND_TWC_MIN) &&
+ (thold_att < (NAND_TWC_MIN - (tset_att + twait)))) {
+ thold_att = NAND_TWC_MIN - (tset_att + twait);
+ }
+ timing = div_round_up(thold_att, hclkp);
+ tims.thold_att = CLAMP(timing, 1UL,
+ (unsigned long)FMC2_PMEM_PATT_TIMING_MASK);
+
+ VERBOSE("NAND timings: %u - %u - %u - %u - %u - %u - %u - %u\n",
+ tims.tclr, tims.tar, tims.thiz, tims.twait,
+ tims.thold_mem, tims.tset_mem,
+ tims.thold_att, tims.tset_att);
+
+ /* Set tclr/tar timings */
+ pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+ pcr &= ~FMC2_PCR_TCLR_MASK;
+ pcr |= FMC2_PCR_TCLR(tims.tclr);
+ pcr &= ~FMC2_PCR_TAR_MASK;
+ pcr |= FMC2_PCR_TAR(tims.tar);
+
+ /* Set tset/twait/thold/thiz timings in common bank */
+ pmem = FMC2_PMEM_MEMSET(tims.tset_mem);
+ pmem |= FMC2_PMEM_MEMWAIT(tims.twait);
+ pmem |= FMC2_PMEM_MEMHOLD(tims.thold_mem);
+ pmem |= FMC2_PMEM_MEMHIZ(tims.thiz);
+
+ /* Set tset/twait/thold/thiz timings in attribute bank */
+ patt = FMC2_PATT_ATTSET(tims.tset_att);
+ patt |= FMC2_PATT_ATTWAIT(tims.twait);
+ patt |= FMC2_PATT_ATTHOLD(tims.thold_att);
+ patt |= FMC2_PATT_ATTHIZ(tims.thiz);
+
+ mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
+ mmio_write_32(fmc2_base() + FMC2_PMEM, pmem);
+ mmio_write_32(fmc2_base() + FMC2_PATT, patt);
+}
+
+static void stm32_fmc2_set_buswidth_16(bool set)
+{
+ mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_PWID_MASK,
+ (set ? FMC2_PCR_PWID(FMC2_PCR_PWID_16) : 0U));
+}
+
+static void stm32_fmc2_set_ecc(bool enable)
+{
+ mmio_clrsetbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_ECCEN,
+ (enable ? FMC2_PCR_ECCEN : 0U));
+}
+
+static int stm32_fmc2_ham_correct(uint8_t *buffer, uint8_t *eccbuffer,
+ uint8_t *ecc)
+{
+ uint8_t xor_ecc_ones;
+ uint16_t xor_ecc_1b, xor_ecc_2b, xor_ecc_3b;
+ union {
+ uint32_t val;
+ uint8_t bytes[4];
+ } xor_ecc;
+
+ /* Page size--------ECC_Code Size
+ * 256---------------22 bits LSB (ECC_CODE & 0x003FFFFF)
+ * 512---------------24 bits (ECC_CODE & 0x00FFFFFF)
+ * 1024--------------26 bits (ECC_CODE & 0x03FFFFFF)
+ * 2048--------------28 bits (ECC_CODE & 0x0FFFFFFF)
+ * 4096--------------30 bits (ECC_CODE & 0x3FFFFFFF)
+ * 8192--------------32 bits (ECC_CODE & 0xFFFFFFFF)
+ */
+
+ /* For Page size 512, ECC_Code size 24 bits */
+ xor_ecc_1b = ecc[0] ^ eccbuffer[0];
+ xor_ecc_2b = ecc[1] ^ eccbuffer[1];
+ xor_ecc_3b = ecc[2] ^ eccbuffer[2];
+
+ xor_ecc.val = 0L;
+ xor_ecc.bytes[2] = xor_ecc_3b;
+ xor_ecc.bytes[1] = xor_ecc_2b;
+ xor_ecc.bytes[0] = xor_ecc_1b;
+
+ if (xor_ecc.val == 0U) {
+ return 0; /* No Error */
+ }
+
+ xor_ecc_ones = __builtin_popcount(xor_ecc.val);
+ if (xor_ecc_ones < 23U) {
+ if (xor_ecc_ones == 12U) {
+ uint16_t bit_address, byte_address;
+
+ /* Correctable ERROR */
+ bit_address = ((xor_ecc_1b >> 1) & BIT(0)) |
+ ((xor_ecc_1b >> 2) & BIT(1)) |
+ ((xor_ecc_1b >> 3) & BIT(2));
+
+ byte_address = ((xor_ecc_1b >> 7) & BIT(0)) |
+ ((xor_ecc_2b) & BIT(1)) |
+ ((xor_ecc_2b >> 1) & BIT(2)) |
+ ((xor_ecc_2b >> 2) & BIT(3)) |
+ ((xor_ecc_2b >> 3) & BIT(4)) |
+ ((xor_ecc_3b << 4) & BIT(5)) |
+ ((xor_ecc_3b << 3) & BIT(6)) |
+ ((xor_ecc_3b << 2) & BIT(7)) |
+ ((xor_ecc_3b << 1) & BIT(8));
+
+ /* Correct bit error in the data */
+ buffer[byte_address] =
+ buffer[byte_address] ^ BIT(bit_address);
+ VERBOSE("Hamming: 1 ECC error corrected\n");
+
+ return 0;
+ }
+
+ /* Non Correctable ERROR */
+ ERROR("%s: Uncorrectable ECC Errors\n", __func__);
+ return -1;
+ }
+
+ /* ECC ERROR */
+ ERROR("%s: Hamming correction error\n", __func__);
+ return -1;
+}
+
+
+static int stm32_fmc2_ham_calculate(uint8_t *buffer, uint8_t *ecc)
+{
+ uint32_t heccr;
+ uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
+
+ while ((mmio_read_32(fmc2_base() + FMC2_SR) & FMC2_SR_NWRF) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ heccr = mmio_read_32(fmc2_base() + FMC2_HECCR);
+
+ ecc[0] = heccr;
+ ecc[1] = heccr >> 8;
+ ecc[2] = heccr >> 16;
+
+ /* Disable ECC */
+ stm32_fmc2_set_ecc(false);
+
+ return 0;
+}
+
+static int stm32_fmc2_bch_correct(uint8_t *buffer, unsigned int eccsize)
+{
+ uint32_t bchdsr0, bchdsr1, bchdsr2, bchdsr3, bchdsr4;
+ uint16_t pos[8];
+ int i, den;
+ uint64_t timeout = timeout_init_us(TIMEOUT_US_10_MS);
+
+ while ((mmio_read_32(fmc2_base() + FMC2_BCHISR) &
+ FMC2_BCHISR_DERF) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ return -ETIMEDOUT;
+ }
+ }
+
+ bchdsr0 = mmio_read_32(fmc2_base() + FMC2_BCHDSR0);
+ bchdsr1 = mmio_read_32(fmc2_base() + FMC2_BCHDSR1);
+ bchdsr2 = mmio_read_32(fmc2_base() + FMC2_BCHDSR2);
+ bchdsr3 = mmio_read_32(fmc2_base() + FMC2_BCHDSR3);
+ bchdsr4 = mmio_read_32(fmc2_base() + FMC2_BCHDSR4);
+
+ /* Disable ECC */
+ stm32_fmc2_set_ecc(false);
+
+ /* No error found */
+ if ((bchdsr0 & FMC2_BCHDSR0_DEF) == 0U) {
+ return 0;
+ }
+
+ /* Too many errors detected */
+ if ((bchdsr0 & FMC2_BCHDSR0_DUE) != 0U) {
+ return -EBADMSG;
+ }
+
+ pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK;
+ pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT;
+ pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK;
+ pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT;
+ pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK;
+ pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT;
+ pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK;
+ pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT;
+
+ den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT;
+ for (i = 0; i < den; i++) {
+ if (pos[i] < (eccsize * 8U)) {
+ uint8_t bitmask = BIT(pos[i] % 8U);
+ uint32_t offset = pos[i] / 8U;
+
+ *(buffer + offset) ^= bitmask;
+ }
+ }
+
+ return 0;
+}
+
+static void stm32_fmc2_hwctl(struct nand_device *nand)
+{
+ stm32_fmc2_set_ecc(false);
+
+ if (nand->ecc.max_bit_corr != FMC2_ECC_HAM) {
+ mmio_clrbits_32(fmc2_base() + FMC2_PCR, FMC2_PCR_WEN);
+ }
+
+ stm32_fmc2_set_ecc(true);
+}
+
+static int stm32_fmc2_read_page(struct nand_device *nand,
+ unsigned int page, uintptr_t buffer)
+{
+ unsigned int eccsize = nand->ecc.size;
+ unsigned int eccbytes = nand->ecc.bytes;
+ unsigned int eccsteps = nand->page_size / eccsize;
+ uint8_t ecc_corr[FMC2_MAX_ECC_BYTES];
+ uint8_t ecc_cal[FMC2_MAX_ECC_BYTES] = {0U};
+ uint8_t *p;
+ unsigned int i;
+ unsigned int s;
+ int ret;
+
+ VERBOSE(">%s page %i buffer %lx\n", __func__, page, buffer);
+
+ ret = nand_read_page_cmd(page, 0U, 0U, 0U);
+ if (ret != 0) {
+ return ret;
+ }
+
+ for (s = 0U, i = nand->page_size + FMC2_BBM_LEN, p = (uint8_t *)buffer;
+ s < eccsteps;
+ s++, i += eccbytes, p += eccsize) {
+ stm32_fmc2_hwctl(nand);
+
+ /* Read the NAND page sector (512 bytes) */
+ ret = nand_change_read_column_cmd(s * eccsize, (uintptr_t)p,
+ eccsize);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
+ ret = stm32_fmc2_ham_calculate(p, ecc_cal);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ /* Read the corresponding ECC bytes */
+ ret = nand_change_read_column_cmd(i, (uintptr_t)ecc_corr,
+ eccbytes);
+ if (ret != 0) {
+ return ret;
+ }
+
+ /* Correct the data */
+ if (nand->ecc.max_bit_corr == FMC2_ECC_HAM) {
+ ret = stm32_fmc2_ham_correct(p, ecc_corr, ecc_cal);
+ } else {
+ ret = stm32_fmc2_bch_correct(p, eccsize);
+ }
+
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void stm32_fmc2_read_data(struct nand_device *nand,
+ uint8_t *buff, unsigned int length,
+ bool use_bus8)
+{
+ uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
+
+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+ stm32_fmc2_set_buswidth_16(false);
+ }
+
+ if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
+ *buff = mmio_read_8(data_base);
+ buff += sizeof(uint8_t);
+ length -= sizeof(uint8_t);
+ }
+
+ if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
+ (length >= sizeof(uint16_t))) {
+ *(uint16_t *)buff = mmio_read_16(data_base);
+ buff += sizeof(uint16_t);
+ length -= sizeof(uint16_t);
+ }
+
+ /* 32bit aligned */
+ while (length >= sizeof(uint32_t)) {
+ *(uint32_t *)buff = mmio_read_32(data_base);
+ buff += sizeof(uint32_t);
+ length -= sizeof(uint32_t);
+ }
+
+ /* Read remaining bytes */
+ if (length >= sizeof(uint16_t)) {
+ *(uint16_t *)buff = mmio_read_16(data_base);
+ buff += sizeof(uint16_t);
+ length -= sizeof(uint16_t);
+ }
+
+ if (length != 0U) {
+ *buff = mmio_read_8(data_base);
+ }
+
+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+ /* Reconfigure bus width to 16-bit */
+ stm32_fmc2_set_buswidth_16(true);
+ }
+}
+
+static void stm32_fmc2_write_data(struct nand_device *nand,
+ uint8_t *buff, unsigned int length,
+ bool use_bus8)
+{
+ uintptr_t data_base = stm32_fmc2.cs[stm32_fmc2.cs_sel].data_base;
+
+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+ /* Reconfigure bus width to 8-bit */
+ stm32_fmc2_set_buswidth_16(false);
+ }
+
+ if ((((uintptr_t)buff & BIT(0)) != 0U) && (length != 0U)) {
+ mmio_write_8(data_base, *buff);
+ buff += sizeof(uint8_t);
+ length -= sizeof(uint8_t);
+ }
+
+ if ((((uintptr_t)buff & GENMASK_32(1, 0)) != 0U) &&
+ (length >= sizeof(uint16_t))) {
+ mmio_write_16(data_base, *(uint16_t *)buff);
+ buff += sizeof(uint16_t);
+ length -= sizeof(uint16_t);
+ }
+
+ /* 32bits aligned */
+ while (length >= sizeof(uint32_t)) {
+ mmio_write_32(data_base, *(uint32_t *)buff);
+ buff += sizeof(uint32_t);
+ length -= sizeof(uint32_t);
+ }
+
+ /* Read remaining bytes */
+ if (length >= sizeof(uint16_t)) {
+ mmio_write_16(data_base, *(uint16_t *)buff);
+ buff += sizeof(uint16_t);
+ length -= sizeof(uint16_t);
+ }
+
+ if (length != 0U) {
+ mmio_write_8(data_base, *buff);
+ }
+
+ if (use_bus8 && (nand->buswidth == NAND_BUS_WIDTH_16)) {
+ /* Reconfigure bus width to 16-bit */
+ stm32_fmc2_set_buswidth_16(true);
+ }
+}
+
+static void stm32_fmc2_ctrl_init(void)
+{
+ uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+ uint32_t bcr1 = mmio_read_32(fmc2_base() + FMC2_BCR1);
+
+ /* Enable wait feature and NAND flash memory bank */
+ pcr |= FMC2_PCR_PWAITEN;
+ pcr |= FMC2_PCR_PBKEN;
+
+ /* Set buswidth to 8 bits mode for identification */
+ pcr &= ~FMC2_PCR_PWID_MASK;
+
+ /* ECC logic is disabled */
+ pcr &= ~FMC2_PCR_ECCEN;
+
+ /* Default mode */
+ pcr &= ~FMC2_PCR_ECCALG;
+ pcr &= ~FMC2_PCR_BCHECC;
+ pcr &= ~FMC2_PCR_WEN;
+
+ /* Set default ECC sector size */
+ pcr &= ~FMC2_PCR_ECCSS_MASK;
+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048);
+
+ /* Set default TCLR/TAR timings */
+ pcr &= ~FMC2_PCR_TCLR_MASK;
+ pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT);
+ pcr &= ~FMC2_PCR_TAR_MASK;
+ pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT);
+
+ /* Enable FMC2 controller */
+ bcr1 |= FMC2_BCR1_FMC2EN;
+
+ mmio_write_32(fmc2_base() + FMC2_BCR1, bcr1);
+ mmio_write_32(fmc2_base() + FMC2_PCR, pcr);
+ mmio_write_32(fmc2_base() + FMC2_PMEM, FMC2_PMEM_DEFAULT);
+ mmio_write_32(fmc2_base() + FMC2_PATT, FMC2_PATT_DEFAULT);
+}
+
+static int stm32_fmc2_exec(struct nand_req *req)
+{
+ int ret = 0;
+
+ switch (req->type & NAND_REQ_MASK) {
+ case NAND_REQ_CMD:
+ VERBOSE("Write CMD %x\n", (uint8_t)req->type);
+ mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].cmd_base,
+ (uint8_t)req->type);
+ break;
+ case NAND_REQ_ADDR:
+ VERBOSE("Write ADDR %x\n", *(req->addr));
+ mmio_write_8(stm32_fmc2.cs[stm32_fmc2.cs_sel].addr_base,
+ *(req->addr));
+ break;
+ case NAND_REQ_DATAIN:
+ VERBOSE("Read data\n");
+ stm32_fmc2_read_data(req->nand, req->addr, req->length,
+ ((req->type & NAND_REQ_BUS_WIDTH_8) !=
+ 0U));
+ break;
+ case NAND_REQ_DATAOUT:
+ VERBOSE("Write data\n");
+ stm32_fmc2_write_data(req->nand, req->addr, req->length,
+ ((req->type & NAND_REQ_BUS_WIDTH_8) !=
+ 0U));
+ break;
+ case NAND_REQ_WAIT:
+ VERBOSE("WAIT Ready\n");
+ ret = nand_wait_ready(req->delay_ms);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ };
+
+ return ret;
+}
+
+static void stm32_fmc2_setup(struct nand_device *nand)
+{
+ uint32_t pcr = mmio_read_32(fmc2_base() + FMC2_PCR);
+
+ /* Set buswidth */
+ pcr &= ~FMC2_PCR_PWID_MASK;
+ if (nand->buswidth == NAND_BUS_WIDTH_16) {
+ pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_16);
+ }
+
+ if (nand->ecc.mode == NAND_ECC_HW) {
+ nand->mtd_read_page = stm32_fmc2_read_page;
+
+ pcr &= ~FMC2_PCR_ECCALG;
+ pcr &= ~FMC2_PCR_BCHECC;
+
+ pcr &= ~FMC2_PCR_ECCSS_MASK;
+ pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512);
+
+ switch (nand->ecc.max_bit_corr) {
+ case FMC2_ECC_HAM:
+ nand->ecc.bytes = 3;
+ break;
+ case FMC2_ECC_BCH8:
+ pcr |= FMC2_PCR_ECCALG;
+ pcr |= FMC2_PCR_BCHECC;
+ nand->ecc.bytes = 13;
+ break;
+ default:
+ /* Use FMC2 ECC BCH4 */
+ pcr |= FMC2_PCR_ECCALG;
+ nand->ecc.bytes = 7;
+ break;
+ }
+
+ if ((nand->buswidth & NAND_BUS_WIDTH_16) != 0) {
+ nand->ecc.bytes++;
+ }
+ }
+
+ mmio_write_32(stm32_fmc2.reg_base + FMC2_PCR, pcr);
+}
+
+static const struct nand_ctrl_ops ctrl_ops = {
+ .setup = stm32_fmc2_setup,
+ .exec = stm32_fmc2_exec
+};
+
+int stm32_fmc2_init(void)
+{
+ int fmc_node;
+ int fmc_subnode = 0;
+ int nchips = 0;
+ unsigned int i;
+ void *fdt = NULL;
+ const fdt32_t *cuint;
+ struct dt_node_info info;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ fmc_node = dt_get_node(&info, -1, DT_FMC2_COMPAT);
+ if (fmc_node == -FDT_ERR_NOTFOUND) {
+ WARN("No FMC2 node found\n");
+ return fmc_node;
+ }
+
+ if (info.status == DT_DISABLED) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ stm32_fmc2.reg_base = info.base;
+
+ if ((info.clock < 0) || (info.reset < 0)) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ stm32_fmc2.clock_id = (unsigned long)info.clock;
+ stm32_fmc2.reset_id = (unsigned int)info.reset;
+
+ cuint = fdt_getprop(fdt, fmc_node, "reg", NULL);
+ if (cuint == NULL) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ cuint += 2;
+
+ for (i = 0U; i < MAX_CS; i++) {
+ stm32_fmc2.cs[i].data_base = fdt32_to_cpu(*cuint);
+ stm32_fmc2.cs[i].cmd_base = fdt32_to_cpu(*(cuint + 2));
+ stm32_fmc2.cs[i].addr_base = fdt32_to_cpu(*(cuint + 4));
+ cuint += 6;
+ }
+
+ /* Pinctrl initialization */
+ if (dt_set_pinctrl_config(fmc_node) != 0) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ /* Parse flash nodes */
+ fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+ nchips++;
+ }
+
+ if (nchips != 1) {
+ WARN("Only one SLC NAND device supported\n");
+ return -FDT_ERR_BADVALUE;
+ }
+
+ fdt_for_each_subnode(fmc_subnode, fdt, fmc_node) {
+ /* Get chip select */
+ cuint = fdt_getprop(fdt, fmc_subnode, "reg", NULL);
+ if (cuint == NULL) {
+ WARN("Chip select not well defined\n");
+ return -FDT_ERR_BADVALUE;
+ }
+ stm32_fmc2.cs_sel = fdt32_to_cpu(*cuint);
+ VERBOSE("NAND CS %i\n", stm32_fmc2.cs_sel);
+ }
+
+ /* Enable Clock */
+ stm32mp_clk_enable(stm32_fmc2.clock_id);
+
+ /* Reset IP */
+ stm32mp_reset_assert(stm32_fmc2.reset_id);
+ stm32mp_reset_deassert(stm32_fmc2.reset_id);
+
+ /* Setup default IP registers */
+ stm32_fmc2_ctrl_init();
+
+ /* Setup default timings */
+ stm32_fmc2_nand_setup_timing();
+
+ /* Init NAND RAW framework */
+ nand_raw_ctrl_init(&ctrl_ops);
+
+ return 0;
+}
diff --git a/drivers/st/io/io_mmc.c b/drivers/st/io/io_mmc.c
index a239b5f3ad..44b7d19074 100644
--- a/drivers/st/io/io_mmc.c
+++ b/drivers/st/io/io_mmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,14 +20,15 @@ static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info);
static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
-static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset);
+static int mmc_block_seek(io_entity_t *entity, int mode,
+ signed long long offset);
static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
size_t *length_read);
static int mmc_block_close(io_entity_t *entity);
static int mmc_dev_close(io_dev_info_t *dev_info);
static io_type_t device_type_mmc(void);
-static ssize_t seek_offset;
+static signed long long seek_offset;
static const io_dev_connector_t mmc_dev_connector = {
.dev_open = mmc_dev_open
@@ -85,7 +86,8 @@ static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
}
/* Seek to a particular file offset on the mmc device */
-static int mmc_block_seek(io_entity_t *entity, int mode, ssize_t offset)
+static int mmc_block_seek(io_entity_t *entity, int mode,
+ signed long long offset)
{
seek_offset = offset;
return 0;
diff --git a/drivers/st/spi/stm32_qspi.c b/drivers/st/spi/stm32_qspi.c
new file mode 100644
index 0000000000..188d2ff806
--- /dev/null
+++ b/drivers/st/spi/stm32_qspi.c
@@ -0,0 +1,500 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#include <libfdt.h>
+
+#include <platform_def.h>
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <drivers/spi_mem.h>
+#include <drivers/st/stm32_gpio.h>
+#include <drivers/st/stm32mp_reset.h>
+#include <lib/mmio.h>
+#include <lib/utils_def.h>
+
+/* QUADSPI registers */
+#define QSPI_CR 0x00U
+#define QSPI_DCR 0x04U
+#define QSPI_SR 0x08U
+#define QSPI_FCR 0x0CU
+#define QSPI_DLR 0x10U
+#define QSPI_CCR 0x14U
+#define QSPI_AR 0x18U
+#define QSPI_ABR 0x1CU
+#define QSPI_DR 0x20U
+#define QSPI_PSMKR 0x24U
+#define QSPI_PSMAR 0x28U
+#define QSPI_PIR 0x2CU
+#define QSPI_LPTR 0x30U
+
+/* QUADSPI control register */
+#define QSPI_CR_EN BIT(0)
+#define QSPI_CR_ABORT BIT(1)
+#define QSPI_CR_DMAEN BIT(2)
+#define QSPI_CR_TCEN BIT(3)
+#define QSPI_CR_SSHIFT BIT(4)
+#define QSPI_CR_DFM BIT(6)
+#define QSPI_CR_FSEL BIT(7)
+#define QSPI_CR_FTHRES_SHIFT 8U
+#define QSPI_CR_TEIE BIT(16)
+#define QSPI_CR_TCIE BIT(17)
+#define QSPI_CR_FTIE BIT(18)
+#define QSPI_CR_SMIE BIT(19)
+#define QSPI_CR_TOIE BIT(20)
+#define QSPI_CR_APMS BIT(22)
+#define QSPI_CR_PMM BIT(23)
+#define QSPI_CR_PRESCALER_MASK GENMASK_32(31, 24)
+#define QSPI_CR_PRESCALER_SHIFT 24U
+
+/* QUADSPI device configuration register */
+#define QSPI_DCR_CKMODE BIT(0)
+#define QSPI_DCR_CSHT_MASK GENMASK_32(10, 8)
+#define QSPI_DCR_CSHT_SHIFT 8U
+#define QSPI_DCR_FSIZE_MASK GENMASK_32(20, 16)
+#define QSPI_DCR_FSIZE_SHIFT 16U
+
+/* QUADSPI status register */
+#define QSPI_SR_TEF BIT(0)
+#define QSPI_SR_TCF BIT(1)
+#define QSPI_SR_FTF BIT(2)
+#define QSPI_SR_SMF BIT(3)
+#define QSPI_SR_TOF BIT(4)
+#define QSPI_SR_BUSY BIT(5)
+
+/* QUADSPI flag clear register */
+#define QSPI_FCR_CTEF BIT(0)
+#define QSPI_FCR_CTCF BIT(1)
+#define QSPI_FCR_CSMF BIT(3)
+#define QSPI_FCR_CTOF BIT(4)
+
+/* QUADSPI communication configuration register */
+#define QSPI_CCR_DDRM BIT(31)
+#define QSPI_CCR_DHHC BIT(30)
+#define QSPI_CCR_SIOO BIT(28)
+#define QSPI_CCR_FMODE_SHIFT 26U
+#define QSPI_CCR_DMODE_SHIFT 24U
+#define QSPI_CCR_DCYC_SHIFT 18U
+#define QSPI_CCR_ABSIZE_SHIFT 16U
+#define QSPI_CCR_ABMODE_SHIFT 14U
+#define QSPI_CCR_ADSIZE_SHIFT 12U
+#define QSPI_CCR_ADMODE_SHIFT 10U
+#define QSPI_CCR_IMODE_SHIFT 8U
+#define QSPI_CCR_IND_WRITE 0U
+#define QSPI_CCR_IND_READ 1U
+#define QSPI_CCR_MEM_MAP 3U
+
+#define QSPI_MAX_CHIP 2U
+
+#define QSPI_FIFO_TIMEOUT_US 30U
+#define QSPI_CMD_TIMEOUT_US 1000U
+#define QSPI_BUSY_TIMEOUT_US 100U
+#define QSPI_ABT_TIMEOUT_US 100U
+
+#define DT_QSPI_COMPAT "st,stm32f469-qspi"
+
+#define FREQ_100MHZ 100000000U
+
+struct stm32_qspi_ctrl {
+ uintptr_t reg_base;
+ uintptr_t mm_base;
+ size_t mm_size;
+ unsigned long clock_id;
+ unsigned int reset_id;
+};
+
+static struct stm32_qspi_ctrl stm32_qspi;
+
+static uintptr_t qspi_base(void)
+{
+ return stm32_qspi.reg_base;
+}
+
+static int stm32_qspi_wait_for_not_busy(void)
+{
+ uint64_t timeout = timeout_init_us(QSPI_BUSY_TIMEOUT_US);
+
+ while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_BUSY) != 0U) {
+ if (timeout_elapsed(timeout)) {
+ ERROR("%s: busy timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ }
+
+ return 0;
+}
+
+static int stm32_qspi_wait_cmd(const struct spi_mem_op *op)
+{
+ int ret = 0;
+ uint64_t timeout;
+
+ if (op->data.nbytes == 0U) {
+ return stm32_qspi_wait_for_not_busy();
+ }
+
+ timeout = timeout_init_us(QSPI_CMD_TIMEOUT_US);
+ while ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TCF) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ if (ret == 0) {
+ if ((mmio_read_32(qspi_base() + QSPI_SR) & QSPI_SR_TEF) != 0U) {
+ ERROR("%s: transfer error\n", __func__);
+ ret = -EIO;
+ }
+ } else {
+ ERROR("%s: cmd timeout\n", __func__);
+ }
+
+ /* Clear flags */
+ mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF | QSPI_FCR_CTEF);
+
+ return ret;
+}
+
+static void stm32_qspi_read_fifo(uint8_t *val, uintptr_t addr)
+{
+ *val = mmio_read_8(addr);
+}
+
+static void stm32_qspi_write_fifo(uint8_t *val, uintptr_t addr)
+{
+ mmio_write_8(addr, *val);
+}
+
+static int stm32_qspi_poll(const struct spi_mem_op *op)
+{
+ void (*fifo)(uint8_t *val, uintptr_t addr);
+ uint32_t len = op->data.nbytes;
+ uint8_t *buf;
+ uint64_t timeout;
+
+ if (op->data.dir == SPI_MEM_DATA_IN) {
+ fifo = stm32_qspi_read_fifo;
+ } else {
+ fifo = stm32_qspi_write_fifo;
+ }
+
+ buf = (uint8_t *)op->data.buf;
+
+ for (len = op->data.nbytes; len != 0U; len--) {
+ timeout = timeout_init_us(QSPI_FIFO_TIMEOUT_US);
+ while ((mmio_read_32(qspi_base() + QSPI_SR) &
+ QSPI_SR_FTF) == 0U) {
+ if (timeout_elapsed(timeout)) {
+ ERROR("%s: fifo timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+ }
+
+ fifo(buf++, qspi_base() + QSPI_DR);
+ }
+
+ return 0;
+}
+
+static int stm32_qspi_mm(const struct spi_mem_op *op)
+{
+ memcpy(op->data.buf,
+ (void *)(stm32_qspi.mm_base + (size_t)op->addr.val),
+ op->data.nbytes);
+
+ return 0;
+}
+
+static int stm32_qspi_tx(const struct spi_mem_op *op, uint8_t mode)
+{
+ if (op->data.nbytes == 0U) {
+ return 0;
+ }
+
+ if (mode == QSPI_CCR_MEM_MAP) {
+ return stm32_qspi_mm(op);
+ }
+
+ return stm32_qspi_poll(op);
+}
+
+static unsigned int stm32_qspi_get_mode(uint8_t buswidth)
+{
+ if (buswidth == 4U) {
+ return 3U;
+ }
+
+ return buswidth;
+}
+
+static int stm32_qspi_exec_op(const struct spi_mem_op *op)
+{
+ uint64_t timeout;
+ uint32_t ccr;
+ size_t addr_max;
+ uint8_t mode = QSPI_CCR_IND_WRITE;
+ int ret;
+
+ VERBOSE("%s: cmd:%x mode:%d.%d.%d.%d addr:%llx len:%x\n",
+ __func__, op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+ op->dummy.buswidth, op->data.buswidth,
+ op->addr.val, op->data.nbytes);
+
+ ret = stm32_qspi_wait_for_not_busy();
+ if (ret != 0) {
+ return ret;
+ }
+
+ addr_max = op->addr.val + op->data.nbytes + 1U;
+
+ if ((op->data.dir == SPI_MEM_DATA_IN) && (op->data.nbytes != 0U)) {
+ if ((addr_max < stm32_qspi.mm_size) &&
+ (op->addr.buswidth != 0U)) {
+ mode = QSPI_CCR_MEM_MAP;
+ } else {
+ mode = QSPI_CCR_IND_READ;
+ }
+ }
+
+ if (op->data.nbytes != 0U) {
+ mmio_write_32(qspi_base() + QSPI_DLR, op->data.nbytes - 1U);
+ }
+
+ ccr = mode << QSPI_CCR_FMODE_SHIFT;
+ ccr |= op->cmd.opcode;
+ ccr |= stm32_qspi_get_mode(op->cmd.buswidth) << QSPI_CCR_IMODE_SHIFT;
+
+ if (op->addr.nbytes != 0U) {
+ ccr |= (op->addr.nbytes - 1U) << QSPI_CCR_ADSIZE_SHIFT;
+ ccr |= stm32_qspi_get_mode(op->addr.buswidth) <<
+ QSPI_CCR_ADMODE_SHIFT;
+ }
+
+ if ((op->dummy.buswidth != 0U) && (op->dummy.nbytes != 0U)) {
+ ccr |= (op->dummy.nbytes * 8U / op->dummy.buswidth) <<
+ QSPI_CCR_DCYC_SHIFT;
+ }
+
+ if (op->data.nbytes != 0U) {
+ ccr |= stm32_qspi_get_mode(op->data.buswidth) <<
+ QSPI_CCR_DMODE_SHIFT;
+ }
+
+ mmio_write_32(qspi_base() + QSPI_CCR, ccr);
+
+ if ((op->addr.nbytes != 0U) && (mode != QSPI_CCR_MEM_MAP)) {
+ mmio_write_32(qspi_base() + QSPI_AR, op->addr.val);
+ }
+
+ ret = stm32_qspi_tx(op, mode);
+
+ /*
+ * Abort in:
+ * - Error case.
+ * - Memory mapped read: prefetching must be stopped if we read the last
+ * byte of device (device size - fifo size). If device size is not
+ * known then prefetching is always stopped.
+ */
+ if ((ret != 0) || (mode == QSPI_CCR_MEM_MAP)) {
+ goto abort;
+ }
+
+ /* Wait end of TX in indirect mode */
+ ret = stm32_qspi_wait_cmd(op);
+ if (ret != 0) {
+ goto abort;
+ }
+
+ return 0;
+
+abort:
+ mmio_setbits_32(qspi_base() + QSPI_CR, QSPI_CR_ABORT);
+
+ /* Wait clear of abort bit by hardware */
+ timeout = timeout_init_us(QSPI_ABT_TIMEOUT_US);
+ while ((mmio_read_32(qspi_base() + QSPI_CR) & QSPI_CR_ABORT) != 0U) {
+ if (timeout_elapsed(timeout)) {
+ ret = -ETIMEDOUT;
+ break;
+ }
+ }
+
+ mmio_write_32(qspi_base() + QSPI_FCR, QSPI_FCR_CTCF);
+
+ if (ret != 0) {
+ ERROR("%s: exec op error\n", __func__);
+ }
+
+ return ret;
+}
+
+static int stm32_qspi_claim_bus(unsigned int cs)
+{
+ uint32_t cr;
+
+ if (cs >= QSPI_MAX_CHIP) {
+ return -ENODEV;
+ }
+
+ /* Set chip select and enable the controller */
+ cr = QSPI_CR_EN;
+ if (cs == 1U) {
+ cr |= QSPI_CR_FSEL;
+ }
+
+ mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_FSEL, cr);
+
+ return 0;
+}
+
+static void stm32_qspi_release_bus(void)
+{
+ mmio_clrbits_32(qspi_base() + QSPI_CR, QSPI_CR_EN);
+}
+
+static int stm32_qspi_set_speed(unsigned int hz)
+{
+ unsigned long qspi_clk = stm32mp_clk_get_rate(stm32_qspi.clock_id);
+ uint32_t prescaler = UINT8_MAX;
+ uint32_t csht;
+ int ret;
+
+ if (qspi_clk == 0U) {
+ return -EINVAL;
+ }
+
+ if (hz > 0U) {
+ prescaler = div_round_up(qspi_clk, hz) - 1U;
+ if (prescaler > UINT8_MAX) {
+ prescaler = UINT8_MAX;
+ }
+ }
+
+ csht = div_round_up((5U * qspi_clk) / (prescaler + 1U), FREQ_100MHZ);
+ csht = ((csht - 1U) << QSPI_DCR_CSHT_SHIFT) & QSPI_DCR_CSHT_MASK;
+
+ ret = stm32_qspi_wait_for_not_busy();
+ if (ret != 0) {
+ return ret;
+ }
+
+ mmio_clrsetbits_32(qspi_base() + QSPI_CR, QSPI_CR_PRESCALER_MASK,
+ prescaler << QSPI_CR_PRESCALER_SHIFT);
+
+ mmio_clrsetbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CSHT_MASK, csht);
+
+ VERBOSE("%s: speed=%lu\n", __func__, qspi_clk / (prescaler + 1U));
+
+ return 0;
+}
+
+static int stm32_qspi_set_mode(unsigned int mode)
+{
+ int ret;
+
+ ret = stm32_qspi_wait_for_not_busy();
+ if (ret != 0) {
+ return ret;
+ }
+
+ if ((mode & SPI_CS_HIGH) != 0U) {
+ return -ENODEV;
+ }
+
+ if (((mode & SPI_CPHA) != 0U) && ((mode & SPI_CPOL) != 0U)) {
+ mmio_setbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
+ } else if (((mode & SPI_CPHA) == 0U) && ((mode & SPI_CPOL) == 0U)) {
+ mmio_clrbits_32(qspi_base() + QSPI_DCR, QSPI_DCR_CKMODE);
+ } else {
+ return -ENODEV;
+ }
+
+ VERBOSE("%s: mode=0x%x\n", __func__, mode);
+
+ if ((mode & SPI_RX_QUAD) != 0U) {
+ VERBOSE("rx: quad\n");
+ } else if ((mode & SPI_RX_DUAL) != 0U) {
+ VERBOSE("rx: dual\n");
+ } else {
+ VERBOSE("rx: single\n");
+ }
+
+ if ((mode & SPI_TX_QUAD) != 0U) {
+ VERBOSE("tx: quad\n");
+ } else if ((mode & SPI_TX_DUAL) != 0U) {
+ VERBOSE("tx: dual\n");
+ } else {
+ VERBOSE("tx: single\n");
+ }
+
+ return 0;
+}
+
+static const struct spi_bus_ops stm32_qspi_bus_ops = {
+ .claim_bus = stm32_qspi_claim_bus,
+ .release_bus = stm32_qspi_release_bus,
+ .set_speed = stm32_qspi_set_speed,
+ .set_mode = stm32_qspi_set_mode,
+ .exec_op = stm32_qspi_exec_op,
+};
+
+int stm32_qspi_init(void)
+{
+ size_t size;
+ int qspi_node;
+ struct dt_node_info info;
+ void *fdt = NULL;
+ int ret;
+
+ if (fdt_get_address(&fdt) == 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ qspi_node = dt_get_node(&info, -1, DT_QSPI_COMPAT);
+ if (qspi_node < 0) {
+ ERROR("No QSPI ctrl found\n");
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if (info.status == DT_DISABLED) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ ret = fdt_get_reg_props_by_name(qspi_node, "qspi",
+ &stm32_qspi.reg_base, &size);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = fdt_get_reg_props_by_name(qspi_node, "qspi_mm",
+ &stm32_qspi.mm_base,
+ &stm32_qspi.mm_size);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (dt_set_pinctrl_config(qspi_node) != 0) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ if ((info.clock < 0) || (info.reset < 0)) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ stm32_qspi.clock_id = (unsigned long)info.clock;
+ stm32_qspi.reset_id = (unsigned int)info.reset;
+
+ stm32mp_clk_enable(stm32_qspi.clock_id);
+
+ stm32mp_reset_assert(stm32_qspi.reset_id);
+ stm32mp_reset_deassert(stm32_qspi.reset_id);
+
+ mmio_write_32(qspi_base() + QSPI_CR, QSPI_CR_SSHIFT);
+ mmio_write_32(qspi_base() + QSPI_DCR, QSPI_DCR_FSIZE_MASK);
+
+ return spi_mem_init_slave(fdt, qspi_node, &stm32_qspi_bus_ops);
+};
diff --git a/drivers/staging/renesas/rcar/ddr/ddr.mk b/drivers/staging/renesas/rcar/ddr/ddr.mk
deleted file mode 100644
index ed7adc339e..0000000000
--- a/drivers/staging/renesas/rcar/ddr/ddr.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifeq (${RCAR_LSI},${RCAR_E3})
- include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
- BL2_SOURCES += drivers/staging/renesas/rcar/ddr/dram_sub_func.c
-else ifeq (${RCAR_LSI},${RCAR_D3})
- include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
-else ifeq (${RCAR_LSI},${RCAR_V3M})
- include drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
-else
- include drivers/staging/renesas/rcar/ddr/ddr_b/ddr_b.mk
- BL2_SOURCES += drivers/staging/renesas/rcar/ddr/dram_sub_func.c
-endif
diff --git a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk b/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
deleted file mode 100644
index aee27a59a4..0000000000
--- a/drivers/staging/renesas/rcar/ddr/ddr_a/ddr_a.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifeq (${RCAR_LSI},${RCAR_E3})
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_e3.c
-else ifeq (${RCAR_LSI},${RCAR_D3})
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_d3.c
-else
-BL2_SOURCES += drivers/staging/renesas/rcar/ddr/ddr_a/ddr_init_v3m.c
-endif
diff --git a/drivers/ti/uart/aarch32/16550_console.S b/drivers/ti/uart/aarch32/16550_console.S
index 692188412f..5cd9b30cd8 100644
--- a/drivers/ti/uart/aarch32/16550_console.S
+++ b/drivers/ti/uart/aarch32/16550_console.S
@@ -89,16 +89,19 @@ endfunc console_16550_core_init
.globl console_16550_register
/* -------------------------------------------------------
- * int console_stm32_register(uintptr_t baseaddr,
+ * int console_16550_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
- * struct console_stm32 *console);
- * Function to initialize and register a new STM32
+ * console_16550_t *console);
+ * Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
+ * If r1 (UART clock) is 0, initialisation will be
+ * skipped, relying on previous code to have done
+ * this already. r2 is ignored then as well.
* In: r0 - UART register base address
* r1 - UART clock in Hz
- * r2 - Baud rate
- * r3 - pointer to empty console_stm32 struct
+ * r2 - Baud rate (ignored if r1 is 0)
+ * r3 - pointer to empty console_16550_t struct
* Out: return 1 on success, 0 on error
* Clobber list : r0, r1, r2
* -------------------------------------------------------
@@ -110,10 +113,15 @@ func console_16550_register
beq register_fail
str r0, [r4, #CONSOLE_T_16550_BASE]
+ /* A clock rate of zero means to skip the initialisation. */
+ cmp r1, #0
+ beq register_16550
+
bl console_16550_core_init
cmp r0, #0
beq register_fail
+register_16550:
mov r0, r4
pop {r4, lr}
finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index dab46e8c50..80c1b86462 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -92,9 +92,12 @@ endfunc console_16550_core_init
* Function to initialize and register a new 16550
* console. Storage passed in for the console struct
* *must* be persistent (i.e. not from the stack).
+ * If w1 (UART clock) is 0, initialisation will be
+ * skipped, relying on previous code to have done
+ * this already. w2 is ignored then as well.
* In: x0 - UART register base address
* w1 - UART clock in Hz
- * w2 - Baud rate
+ * w2 - Baud rate (ignored if w1 is 0)
* x3 - pointer to empty console_16550_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
@@ -106,9 +109,13 @@ func console_16550_register
cbz x6, register_fail
str x0, [x6, #CONSOLE_T_16550_BASE]
+ /* A clock rate of zero means to skip the initialisation. */
+ cbz w1, register_16550
+
bl console_16550_core_init
cbz x0, register_fail
+register_16550:
mov x0, x6
mov x30, x7
finish_console_register 16550 putc=1, getc=1, flush=1
diff --git a/fdts/a5ds.dts b/fdts/a5ds.dts
index 91212e8a05..31d635ac8b 100644
--- a/fdts/a5ds.dts
+++ b/fdts/a5ds.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,29 +22,30 @@
cpus {
#address-cells = <1>;
#size-cells = <0>;
+ enable-method = "psci";
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a5";
- enable-method = "psci";
reg = <0>;
+ next-level-cache = <&L2>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a5";
- enable-method = "psci";
reg = <1>;
+ next-level-cache = <&L2>;
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a5";
- enable-method = "psci";
reg = <2>;
+ next-level-cache = <&L2>;
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a5";
- enable-method = "psci";
reg = <3>;
+ next-level-cache = <&L2>;
};
};
@@ -53,10 +54,27 @@
reg = <0x80000000 0x7F000000>;
};
- refclk100mhz: refclk100mhz {
+ L2: cache-controller@1C010000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x1C010000 0x1000>;
+ interrupts = <0 84 4>;
+ cache-level = <2>;
+ cache-unified;
+ arm,data-latency = <1 1 1>;
+ arm,tag-latency = <1 1 1>;
+ };
+
+ refclk7500khz: refclk7500khz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <7500000>;
+ clock-output-names = "apb_pclk";
+ };
+
+ refclk24mhz: refclk24mhz {
compatible = "fixed-clock";
#clock-cells = <0>;
- clock-frequency = <100000000>;
+ clock-frequency = <24000000>;
clock-output-names = "apb_pclk";
};
@@ -71,7 +89,7 @@
rtc@1a220000 {
compatible = "arm,pl031", "arm,primecell";
reg = <0x1a220000 0x1000>;
- clocks = <&refclk100mhz>;
+ clocks = <&refclk24mhz>;
interrupts = <0 6 0xf04>;
clock-names = "apb_pclk";
};
@@ -91,7 +109,7 @@
reg = <0x1a200000 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 8 0xf04>;
- clocks = <&refclk100mhz>;
+ clocks = <&refclk7500khz>;
clock-names = "apb_pclk";
};
@@ -100,7 +118,7 @@
reg = <0x1a210000 0x1000>;
interrupt-parent = <&gic>;
interrupts = <0 9 0xf04>;
- clocks = <&refclk100mhz>;
+ clocks = <&refclk7500khz>;
clock-names = "apb_pclk";
};
diff --git a/fdts/stm32mp157-pinctrl.dtsi b/fdts/stm32mp157-pinctrl.dtsi
index 8e480b2c19..7fd902bd2d 100644
--- a/fdts/stm32mp157-pinctrl.dtsi
+++ b/fdts/stm32mp157-pinctrl.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
#include <dt-bindings/pinctrl/stm32-pinfunc.h>
@@ -135,6 +135,31 @@
status = "disabled";
};
+ fmc_pins_a: fmc-0 {
+ pins1 {
+ pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+ <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+ <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
+ <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
+ <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+ <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+ <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+ <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+ <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+ <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+ <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+ <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+ <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
+ bias-disable;
+ drive-push-pull;
+ slew-rate = <1>;
+ };
+ pins2 {
+ pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
+ bias-pull-up;
+ };
+ };
+
qspi_bk1_pins_a: qspi-bk1-0 {
pins1 {
pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
diff --git a/fdts/stm32mp157c-ev1.dts b/fdts/stm32mp157c-ev1.dts
index cfde8ed90e..50c0b939b3 100644
--- a/fdts/stm32mp157c-ev1.dts
+++ b/fdts/stm32mp157c-ev1.dts
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Copyright (C) STMicroelectronics 2017-2019 - All Rights Reserved
* Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
*/
/dts-v1/;
@@ -21,21 +21,20 @@
};
&fmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&fmc_pins_a>;
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
nand: nand@0 {
reg = <0>;
- nand-on-flash-bbt;
- #address-cells = <1>;
- #size-cells = <1>;
};
};
&qspi {
pinctrl-names = "default";
- pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a &qspi_bk2_pins_a>;
+ pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>;
reg = <0x58003000 0x1000>, <0x70000000 0x4000000>;
#address-cells = <1>;
#size-cells = <0>;
@@ -49,15 +48,6 @@
#address-cells = <1>;
#size-cells = <1>;
};
-
- flash1: mx66l51235l@1 {
- compatible = "jedec,spi-nor";
- reg = <1>;
- spi-rx-bus-width = <4>;
- spi-max-frequency = <108000000>;
- #address-cells = <1>;
- #size-cells = <1>;
- };
};
&usart3 {
diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h
index 3ff2912f10..1fcd0f9ba5 100644
--- a/include/arch/aarch64/arch.h
+++ b/include/arch/aarch64/arch.h
@@ -140,6 +140,8 @@
#define ID_AA64PFR0_GIC_MASK ULL(0xf)
#define ID_AA64PFR0_SVE_SHIFT U(32)
#define ID_AA64PFR0_SVE_MASK ULL(0xf)
+#define ID_AA64PFR0_SEL2_SHIFT U(36)
+#define ID_AA64PFR0_SEL2_MASK ULL(0xf)
#define ID_AA64PFR0_MPAM_SHIFT U(40)
#define ID_AA64PFR0_MPAM_MASK ULL(0xf)
#define ID_AA64PFR0_DIT_SHIFT U(48)
@@ -285,6 +287,7 @@
#define SCR_RES1_BITS ((U(1) << 4) | (U(1) << 5))
#define SCR_ATA_BIT (U(1) << 26)
#define SCR_FIEN_BIT (U(1) << 21)
+#define SCR_EEL2_BIT (U(1) << 18)
#define SCR_API_BIT (U(1) << 17)
#define SCR_APK_BIT (U(1) << 16)
#define SCR_TWE_BIT (U(1) << 13)
diff --git a/include/arch/aarch64/el3_common_macros.S b/include/arch/aarch64/el3_common_macros.S
index 378e827ce1..156b18a4fd 100644
--- a/include/arch/aarch64/el3_common_macros.S
+++ b/include/arch/aarch64/el3_common_macros.S
@@ -232,11 +232,18 @@
*
* _exception_vectors:
* Address of the exception vectors to program in the VBAR_EL3 register.
+ *
+ * _pie_fixup_size:
+ * Size of memory region to fixup Global Descriptor Table (GDT).
+ *
+ * A non-zero value is expected when firmware needs GDT to be fixed-up.
+ *
* -----------------------------------------------------------------------------
*/
.macro el3_entrypoint_common \
_init_sctlr, _warm_boot_mailbox, _secondary_cold_boot, \
- _init_memory, _init_c_runtime, _exception_vectors
+ _init_memory, _init_c_runtime, _exception_vectors, \
+ _pie_fixup_size
.if \_init_sctlr
/* -------------------------------------------------------------
@@ -283,6 +290,26 @@
do_cold_boot:
.endif /* _warm_boot_mailbox */
+ .if \_pie_fixup_size
+#if ENABLE_PIE
+ /*
+ * ------------------------------------------------------------
+ * If PIE is enabled fixup the Global descriptor Table only
+ * once during primary core cold boot path.
+ *
+ * Compile time base address, required for fixup, is calculated
+ * using "pie_fixup" label present within first page.
+ * ------------------------------------------------------------
+ */
+ pie_fixup:
+ ldr x0, =pie_fixup
+ and x0, x0, #~(PAGE_SIZE - 1)
+ mov_imm x1, \_pie_fixup_size
+ add x1, x1, x0
+ bl fixup_gdt_reloc
+#endif /* ENABLE_PIE */
+ .endif /* _pie_fixup_size */
+
/* ---------------------------------------------------------------------
* Set the exception vectors.
* ---------------------------------------------------------------------
@@ -355,6 +382,14 @@
add x1, x1, :lo12:__RW_END__
sub x1, x1, x0
bl inv_dcache_range
+#if defined(IMAGE_BL31) && SEPARATE_NOBITS_REGION
+ adrp x0, __NOBITS_START__
+ add x0, x0, :lo12:__NOBITS_START__
+ adrp x1, __NOBITS_END__
+ add x1, x1, :lo12:__NOBITS_END__
+ sub x1, x1, x0
+ bl inv_dcache_range
+#endif
#endif
adrp x0, __BSS_START__
add x0, x0, :lo12:__BSS_START__
diff --git a/include/drivers/allwinner/axp.h b/include/drivers/allwinner/axp.h
new file mode 100644
index 0000000000..9c0035f96b
--- /dev/null
+++ b/include/drivers/allwinner/axp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef AXP_H
+#define AXP_H
+
+#include <stdint.h>
+
+#define NA 0xff
+
+enum {
+ AXP803_CHIP_ID = 0x41,
+ AXP805_CHIP_ID = 0x40,
+};
+
+struct axp_regulator {
+ const char *dt_name;
+ uint16_t min_volt;
+ uint16_t max_volt;
+ uint16_t step;
+ unsigned char split;
+ unsigned char volt_reg;
+ unsigned char switch_reg;
+ unsigned char switch_bit;
+};
+
+extern const uint8_t axp_chip_id;
+extern const char *const axp_compatible;
+extern const struct axp_regulator axp_regulators[];
+
+/*
+ * Since the PMIC can be connected to multiple bus types,
+ * low-level read/write functions must be provided by the platform
+ */
+int axp_read(uint8_t reg);
+int axp_write(uint8_t reg, uint8_t val);
+int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask);
+#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
+#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
+
+int axp_check_id(void);
+void axp_power_off(void);
+void axp_setup_regulators(const void *fdt);
+
+#endif /* AXP_H */
diff --git a/include/drivers/arm/cryptocell/712/rsa.h b/include/drivers/arm/cryptocell/712/rsa.h
index cd9925b325..825214d20f 100644
--- a/include/drivers/arm/cryptocell/712/rsa.h
+++ b/include/drivers/arm/cryptocell/712/rsa.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,19 +21,21 @@ extern "C"
/************************ Defines ******************************/
-/* the modulus size ion bits */
+/* the modulus size in bits */
+#if (KEY_SIZE == 2048)
#define RSA_MOD_SIZE_IN_BITS 2048UL
+#elif (KEY_SIZE == 3072)
+#define RSA_MOD_SIZE_IN_BITS 3072UL
+#else
+#error Unsupported CryptoCell key size requested
+#endif
+
#define RSA_MOD_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_MOD_SIZE_IN_BITS))
#define RSA_MOD_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_MOD_SIZE_IN_BITS))
#define RSA_MOD_SIZE_IN_256BITS (RSA_MOD_SIZE_IN_WORDS/8)
#define RSA_EXP_SIZE_IN_BITS 17UL
#define RSA_EXP_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_EXP_SIZE_IN_BITS))
-/* size of buffer for Barrett modulus tag NP, used in PKA algorithms */
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS 132
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
-#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS (CALC_FULL_32BIT_WORDS(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
-
/*
* @brief The RSA_CalcNp calculates Np value and saves it into Np_ptr:
*
diff --git a/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
index 68b9ef8aec..ed1f2835c8 100644
--- a/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
+++ b/include/drivers/arm/cryptocell/712/secureboot_gen_defs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,7 +24,14 @@ extern "C"
/***********************/
/*RSA definitions*/
+#if (KEY_SIZE == 2048)
#define SB_RSA_MOD_SIZE_IN_WORDS 64
+#elif (KEY_SIZE == 3072)
+#define SB_RSA_MOD_SIZE_IN_WORDS 96
+#else
+#error Unsupported CryptoCell key size requested
+#endif
+
#define SB_RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS 5
@@ -43,9 +50,12 @@ typedef struct {
/********* Supported algorithms definitions ***********/
/*! RSA supported algorithms */
+/* Note: this applies to either 2k or 3k based on CryptoCell SBROM library
+ * version - it means 2k in version 1 and 3k in version 2 (yes, really).
+ */
typedef enum {
- RSA_PSS_2048 = 0x01, /*!< RSA PSS 2048 after hash SHA 256 */
- RSA_PKCS15_2048 = 0x02, /*!< RSA PKX15 */
+ RSA_PSS = 0x01, /*!< RSA PSS after hash SHA 256 */
+ RSA_PKCS15 = 0x02, /*!< RSA PKX15 */
RSA_Last = 0x7FFFFFFF
} CCSbRsaAlg_t;
diff --git a/include/drivers/arm/scu.h b/include/drivers/arm/scu.h
new file mode 100644
index 0000000000..992539f218
--- /dev/null
+++ b/include/drivers/arm/scu.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SCU_H
+#define SCU_H
+
+#include <stdint.h>
+
+#define SCU_CTRL_REG 0x00
+#define SCU_CFG_REG 0x04
+
+#define SCU_ENABLE_BIT (1 << 0)
+
+void enable_snoop_ctrl_unit(uintptr_t base);
+uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base);
+
+#endif /* SCU_H */
diff --git a/include/drivers/io/io_driver.h b/include/drivers/io/io_driver.h
index 2b704f491e..d8bb435aa9 100644
--- a/include/drivers/io/io_driver.h
+++ b/include/drivers/io/io_driver.h
@@ -39,7 +39,7 @@ typedef struct io_dev_funcs {
io_type_t (*type)(void);
int (*open)(io_dev_info_t *dev_info, const uintptr_t spec,
io_entity_t *entity);
- int (*seek)(io_entity_t *entity, int mode, ssize_t offset);
+ int (*seek)(io_entity_t *entity, int mode, signed long long offset);
int (*size)(io_entity_t *entity, size_t *length);
int (*read)(io_entity_t *entity, uintptr_t buffer, size_t length,
size_t *length_read);
diff --git a/include/drivers/io/io_mtd.h b/include/drivers/io/io_mtd.h
new file mode 100644
index 0000000000..1395ff6019
--- /dev/null
+++ b/include/drivers/io/io_mtd.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IO_MTD_H
+#define IO_MTD_H
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include <drivers/io/io_storage.h>
+
+/* MTD devices ops */
+typedef struct io_mtd_ops {
+ /*
+ * Initialize MTD framework and retrieve device information.
+ *
+ * @size: [out] MTD device size in bytes.
+ * @erase_size: [out] MTD erase size in bytes.
+ * Return 0 on success, a negative error code otherwise.
+ */
+ int (*init)(unsigned long long *size, unsigned int *erase_size);
+
+ /*
+ * Execute a read memory operation.
+ *
+ * @offset: Offset in bytes to start read operation.
+ * @buffer: [out] Buffer to store read data.
+ * @length: Required length to be read in bytes.
+ * @out_length: [out] Length read in bytes.
+ * Return 0 on success, a negative error code otherwise.
+ */
+ int (*read)(unsigned int offset, uintptr_t buffer, size_t length,
+ size_t *out_length);
+
+ /*
+ * Execute a write memory operation.
+ *
+ * @offset: Offset in bytes to start write operation.
+ * @buffer: Buffer to be written in device.
+ * @length: Required length to be written in bytes.
+ * Return 0 on success, a negative error code otherwise.
+ */
+ int (*write)(unsigned int offset, uintptr_t buffer, size_t length);
+} io_mtd_ops_t;
+
+typedef struct io_mtd_dev_spec {
+ unsigned long long device_size;
+ unsigned int erase_size;
+ io_mtd_ops_t ops;
+} io_mtd_dev_spec_t;
+
+struct io_dev_connector;
+
+int register_io_dev_mtd(const struct io_dev_connector **dev_con);
+
+#endif /* IO_MTD_H */
diff --git a/include/drivers/io/io_storage.h b/include/drivers/io/io_storage.h
index 084c67c470..0e6ffd6193 100644
--- a/include/drivers/io/io_storage.h
+++ b/include/drivers/io/io_storage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,6 +22,7 @@ typedef enum {
IO_TYPE_DUMMY,
IO_TYPE_FIRMWARE_IMAGE_PACKAGE,
IO_TYPE_BLOCK,
+ IO_TYPE_MTD,
IO_TYPE_MMC,
IO_TYPE_STM32IMAGE,
IO_TYPE_MAX
@@ -86,7 +87,7 @@ int io_dev_close(uintptr_t dev_handle);
/* Synchronous operations */
int io_open(uintptr_t dev_handle, const uintptr_t spec, uintptr_t *handle);
-int io_seek(uintptr_t handle, io_seek_mode_t mode, ssize_t offset);
+int io_seek(uintptr_t handle, io_seek_mode_t mode, signed long long offset);
int io_size(uintptr_t handle, size_t *length);
diff --git a/include/drivers/nand.h b/include/drivers/nand.h
new file mode 100644
index 0000000000..1dbb008f9c
--- /dev/null
+++ b/include/drivers/nand.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_NAND_H
+#define DRIVERS_NAND_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/utils_def.h>
+
+#define PSEC_TO_MSEC(x) div_round_up((x), 1000000000ULL)
+
+struct ecc {
+ unsigned int mode; /* ECC mode NAND_ECC_MODE_{NONE|HW|ONDIE} */
+ unsigned int size; /* Data byte per ECC step */
+ unsigned int bytes; /* ECC bytes per step */
+ unsigned int max_bit_corr; /* Max correctible bits per ECC steps */
+};
+
+struct nand_device {
+ unsigned int block_size;
+ unsigned int page_size;
+ unsigned long long size;
+ unsigned int nb_planes;
+ unsigned int buswidth;
+ struct ecc ecc;
+ int (*mtd_block_is_bad)(unsigned int block);
+ int (*mtd_read_page)(struct nand_device *nand, unsigned int page,
+ uintptr_t buffer);
+};
+
+/*
+ * Read bytes from NAND device
+ *
+ * @offset: Byte offset to read from in device
+ * @buffer: [out] Bytes read from device
+ * @length: Number of bytes to read
+ * @length_read: [out] Number of bytes read from device
+ * Return: 0 on success, a negative errno on failure
+ */
+int nand_read(unsigned int offset, uintptr_t buffer, size_t length,
+ size_t *length_read);
+
+/*
+ * Get NAND device instance
+ *
+ * Return: NAND device instance reference
+ */
+struct nand_device *get_nand_device(void);
+
+#endif /* DRIVERS_NAND_H */
diff --git a/include/drivers/raw_nand.h b/include/drivers/raw_nand.h
new file mode 100644
index 0000000000..18e4b73da3
--- /dev/null
+++ b/include/drivers/raw_nand.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_RAW_NAND_H
+#define DRIVERS_RAW_NAND_H
+
+#include <stdint.h>
+
+#include <drivers/nand.h>
+
+/* NAND ONFI default value mode 0 in picosecond */
+#define NAND_TADL_MIN 400000UL
+#define NAND_TALH_MIN 20000UL
+#define NAND_TALS_MIN 50000UL
+#define NAND_TAR_MIN 25000UL
+#define NAND_TCCS_MIN 500000UL
+#define NAND_TCEA_MIN 100000UL
+#define NAND_TCEH_MIN 20000UL
+#define NAND_TCH_MIN 20000UL
+#define NAND_TCHZ_MAX 100000UL
+#define NAND_TCLH_MIN 20000UL
+#define NAND_TCLR_MIN 20000UL
+#define NAND_TCLS_MIN 50000UL
+#define NAND_TCOH_MIN 0UL
+#define NAND_TCS_MIN 70000UL
+#define NAND_TDH_MIN 20000UL
+#define NAND_TDS_MIN 40000UL
+#define NAND_TFEAT_MAX 1000000UL
+#define NAND_TIR_MIN 10000UL
+#define NAND_TITC_MIN 1000000UL
+#define NAND_TR_MAX 200000000UL
+#define NAND_TRC_MIN 100000UL
+#define NAND_TREA_MAX 40000UL
+#define NAND_TREH_MIN 30000UL
+#define NAND_TRHOH_MIN 0UL
+#define NAND_TRHW_MIN 200000UL
+#define NAND_TRHZ_MAX 200000UL
+#define NAND_TRLOH_MIN 0UL
+#define NAND_TRP_MIN 50000UL
+#define NAND_TRR_MIN 40000UL
+#define NAND_TRST_MAX 250000000000ULL
+#define NAND_TWB_MAX 200000UL
+#define NAND_TWC_MIN 100000UL
+#define NAND_TWH_MIN 30000UL
+#define NAND_TWHR_MIN 120000UL
+#define NAND_TWP_MIN 50000UL
+#define NAND_TWW_MIN 100000UL
+
+/* NAND request types */
+#define NAND_REQ_CMD 0x0000U
+#define NAND_REQ_ADDR 0x1000U
+#define NAND_REQ_DATAIN 0x2000U
+#define NAND_REQ_DATAOUT 0x3000U
+#define NAND_REQ_WAIT 0x4000U
+#define NAND_REQ_MASK GENMASK(14, 12)
+#define NAND_REQ_BUS_WIDTH_8 BIT(15)
+
+#define PARAM_PAGE_SIZE 256
+
+/* NAND ONFI commands */
+#define NAND_CMD_READ_1ST 0x00U
+#define NAND_CMD_CHANGE_1ST 0x05U
+#define NAND_CMD_READID_SIG_ADDR 0x20U
+#define NAND_CMD_READ_2ND 0x30U
+#define NAND_CMD_STATUS 0x70U
+#define NAND_CMD_READID 0x90U
+#define NAND_CMD_CHANGE_2ND 0xE0U
+#define NAND_CMD_READ_PARAM_PAGE 0xECU
+#define NAND_CMD_RESET 0xFFU
+
+#define ONFI_REV_21 BIT(3)
+#define ONFI_FEAT_BUS_WIDTH_16 BIT(0)
+#define ONFI_FEAT_EXTENDED_PARAM BIT(7)
+
+/* NAND ECC type */
+#define NAND_ECC_NONE U(0)
+#define NAND_ECC_HW U(1)
+#define NAND_ECC_ONDIE U(2)
+
+/* NAND bus width */
+#define NAND_BUS_WIDTH_8 U(0)
+#define NAND_BUS_WIDTH_16 U(1)
+
+struct nand_req {
+ struct nand_device *nand;
+ uint16_t type;
+ uint8_t *addr;
+ unsigned int length;
+ unsigned int delay_ms;
+ unsigned int inst_delay;
+};
+
+struct nand_param_page {
+ /* Rev information and feature block */
+ uint32_t page_sig;
+ uint16_t rev;
+ uint16_t features;
+ uint16_t opt_cmd;
+ uint8_t jtg;
+ uint8_t train_cmd;
+ uint16_t ext_param_length;
+ uint8_t nb_param_pages;
+ uint8_t reserved1[17];
+ /* Manufacturer information */
+ uint8_t manufacturer[12];
+ uint8_t model[20];
+ uint8_t manufacturer_id;
+ uint16_t data_code;
+ uint8_t reserved2[13];
+ /* Memory organization */
+ uint32_t bytes_per_page;
+ uint16_t spare_per_page;
+ uint32_t bytes_per_partial;
+ uint16_t spare_per_partial;
+ uint32_t num_pages_per_blk;
+ uint32_t num_blk_in_lun;
+ uint8_t num_lun;
+ uint8_t num_addr_cycles;
+ uint8_t bit_per_cell;
+ uint16_t max_bb_per_lun;
+ uint16_t blk_endur;
+ uint8_t valid_blk_begin;
+ uint16_t blk_enbur_valid;
+ uint8_t nb_prog_page;
+ uint8_t partial_prog_attr;
+ uint8_t nb_ecc_bits;
+ uint8_t plane_addr;
+ uint8_t mplanes_ops;
+ uint8_t ez_nand;
+ uint8_t reserved3[12];
+ /* Electrical parameters */
+ uint8_t io_pin_cap_max;
+ uint16_t sdr_timing_mode;
+ uint16_t sdr_prog_cache_timing;
+ uint16_t tprog;
+ uint16_t tbers;
+ uint16_t tr;
+ uint16_t tccs;
+ uint8_t nvddr_timing_mode;
+ uint8_t nvddr2_timing_mode;
+ uint8_t nvddr_features;
+ uint16_t clk_input_cap_typ;
+ uint16_t io_pin_cap_typ;
+ uint16_t input_pin_cap_typ;
+ uint8_t input_pin_cap_max;
+ uint8_t drv_strength_support;
+ uint16_t tr_max;
+ uint16_t tadl;
+ uint16_t tr_typ;
+ uint8_t reserved4[6];
+ /* Vendor block */
+ uint16_t vendor_revision;
+ uint8_t vendor[88];
+ uint16_t crc16;
+} __packed;
+
+struct nand_ctrl_ops {
+ int (*exec)(struct nand_req *req);
+ void (*setup)(struct nand_device *nand);
+};
+
+struct rawnand_device {
+ struct nand_device *nand_dev;
+ const struct nand_ctrl_ops *ops;
+};
+
+int nand_raw_init(unsigned long long *size, unsigned int *erase_size);
+int nand_wait_ready(unsigned long delay);
+int nand_read_page_cmd(unsigned int page, unsigned int offset,
+ uintptr_t buffer, unsigned int len);
+int nand_change_read_column_cmd(unsigned int offset, uintptr_t buffer,
+ unsigned int len);
+void nand_raw_ctrl_init(const struct nand_ctrl_ops *ops);
+
+/*
+ * Platform can implement this to override default raw NAND instance
+ * configuration.
+ *
+ * @device: target raw NAND instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_raw_nand_data(struct rawnand_device *device);
+
+#endif /* DRIVERS_RAW_NAND_H */
diff --git a/include/drivers/spi_mem.h b/include/drivers/spi_mem.h
new file mode 100644
index 0000000000..d1953acf4c
--- /dev/null
+++ b/include/drivers/spi_mem.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_MEM_H
+#define DRIVERS_SPI_MEM_H
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#define SPI_MEM_BUSWIDTH_1_LINE 1U
+#define SPI_MEM_BUSWIDTH_2_LINE 2U
+#define SPI_MEM_BUSWIDTH_4_LINE 4U
+
+/*
+ * enum spi_mem_data_dir - Describes the direction of a SPI memory data
+ * transfer from the controller perspective.
+ * @SPI_MEM_DATA_IN: data coming from the SPI memory.
+ * @SPI_MEM_DATA_OUT: data sent to the SPI memory.
+ */
+enum spi_mem_data_dir {
+ SPI_MEM_DATA_IN,
+ SPI_MEM_DATA_OUT,
+};
+
+/*
+ * struct spi_mem_op - Describes a SPI memory operation.
+ *
+ * @cmd.buswidth: Number of IO lines used to transmit the command.
+ * @cmd.opcode: Operation opcode.
+ * @addr.nbytes: Number of address bytes to send. Can be zero if the operation
+ * does not need to send an address.
+ * @addr.buswidth: Number of IO lines used to transmit the address.
+ * @addr.val: Address value. This value is always sent MSB first on the bus.
+ * Note that only @addr.nbytes are taken into account in this
+ * address value, so users should make sure the value fits in the
+ * assigned number of bytes.
+ * @dummy.nbytes: Number of dummy bytes to send after an opcode or address. Can
+ * be zero if the operation does not require dummy bytes.
+ * @dummy.buswidth: Number of IO lines used to transmit the dummy bytes.
+ * @data.buswidth: Number of IO lines used to send/receive the data.
+ * @data.dir: Direction of the transfer.
+ * @data.nbytes: Number of data bytes to transfer.
+ * @data.buf: Input or output data buffer depending on data::dir.
+ */
+struct spi_mem_op {
+ struct {
+ uint8_t buswidth;
+ uint8_t opcode;
+ } cmd;
+
+ struct {
+ uint8_t nbytes;
+ uint8_t buswidth;
+ uint64_t val;
+ } addr;
+
+ struct {
+ uint8_t nbytes;
+ uint8_t buswidth;
+ } dummy;
+
+ struct {
+ uint8_t buswidth;
+ enum spi_mem_data_dir dir;
+ unsigned int nbytes;
+ void *buf;
+ } data;
+};
+
+/* SPI mode flags */
+#define SPI_CPHA BIT(0) /* clock phase */
+#define SPI_CPOL BIT(1) /* clock polarity */
+#define SPI_CS_HIGH BIT(2) /* CS active high */
+#define SPI_LSB_FIRST BIT(3) /* per-word bits-on-wire */
+#define SPI_3WIRE BIT(4) /* SI/SO signals shared */
+#define SPI_PREAMBLE BIT(5) /* Skip preamble bytes */
+#define SPI_TX_DUAL BIT(6) /* transmit with 2 wires */
+#define SPI_TX_QUAD BIT(7) /* transmit with 4 wires */
+#define SPI_RX_DUAL BIT(8) /* receive with 2 wires */
+#define SPI_RX_QUAD BIT(9) /* receive with 4 wires */
+
+struct spi_bus_ops {
+ /*
+ * Claim the bus and prepare it for communication.
+ *
+ * @cs: The chip select.
+ * Returns: 0 if the bus was claimed successfully, or a negative value
+ * if it wasn't.
+ */
+ int (*claim_bus)(unsigned int cs);
+
+ /*
+ * Release the SPI bus.
+ */
+ void (*release_bus)(void);
+
+ /*
+ * Set transfer speed.
+ *
+ * @hz: The transfer speed in Hertz.
+ * Returns: 0 on success, a negative error code otherwise.
+ */
+ int (*set_speed)(unsigned int hz);
+
+ /*
+ * Set the SPI mode/flags.
+ *
+ * @mode: Requested SPI mode (SPI_... flags).
+ * Returns: 0 on success, a negative error code otherwise.
+ */
+ int (*set_mode)(unsigned int mode);
+
+ /*
+ * Execute a SPI memory operation.
+ *
+ * @op: The memory operation to execute.
+ * Returns: 0 on success, a negative error code otherwise.
+ */
+ int (*exec_op)(const struct spi_mem_op *op);
+};
+
+int spi_mem_exec_op(const struct spi_mem_op *op);
+int spi_mem_init_slave(void *fdt, int bus_node,
+ const struct spi_bus_ops *ops);
+
+#endif /* DRIVERS_SPI_MEM_H */
diff --git a/include/drivers/spi_nand.h b/include/drivers/spi_nand.h
new file mode 100644
index 0000000000..40e2063751
--- /dev/null
+++ b/include/drivers/spi_nand.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_NAND_H
+#define DRIVERS_SPI_NAND_H
+
+#include <drivers/nand.h>
+#include <drivers/spi_mem.h>
+
+#define SPI_NAND_OP_GET_FEATURE 0x0FU
+#define SPI_NAND_OP_SET_FEATURE 0x1FU
+#define SPI_NAND_OP_READ_ID 0x9FU
+#define SPI_NAND_OP_LOAD_PAGE 0x13U
+#define SPI_NAND_OP_RESET 0xFFU
+#define SPI_NAND_OP_READ_FROM_CACHE 0x03U
+#define SPI_NAND_OP_READ_FROM_CACHE_2X 0x3BU
+#define SPI_NAND_OP_READ_FROM_CACHE_4X 0x6BU
+
+/* Configuration register */
+#define SPI_NAND_REG_CFG 0xB0U
+#define SPI_NAND_CFG_ECC_EN BIT(4)
+#define SPI_NAND_CFG_QE BIT(0)
+
+/* Status register */
+#define SPI_NAND_REG_STATUS 0xC0U
+#define SPI_NAND_STATUS_BUSY BIT(0)
+#define SPI_NAND_STATUS_ECC_UNCOR BIT(5)
+
+struct spinand_device {
+ struct nand_device *nand_dev;
+ struct spi_mem_op spi_read_cache_op;
+ uint8_t cfg_cache; /* Cached value of SPI NAND device register CFG */
+};
+
+int spi_nand_init(unsigned long long *size, unsigned int *erase_size);
+
+/*
+ * Platform can implement this to override default SPI-NAND instance
+ * configuration.
+ *
+ * @device: target SPI-NAND instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_spi_nand_data(struct spinand_device *device);
+
+#endif /* DRIVERS_SPI_NAND_H */
diff --git a/include/drivers/spi_nor.h b/include/drivers/spi_nor.h
new file mode 100644
index 0000000000..72cfe5b346
--- /dev/null
+++ b/include/drivers/spi_nor.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DRIVERS_SPI_NOR_H
+#define DRIVERS_SPI_NOR_H
+
+#include <drivers/spi_mem.h>
+
+/* OPCODE */
+#define SPI_NOR_OP_WREN 0x06U /* Write enable */
+#define SPI_NOR_OP_WRSR 0x01U /* Write status register 1 byte */
+#define SPI_NOR_OP_READ_ID 0x9FU /* Read JEDEC ID */
+#define SPI_NOR_OP_READ_CR 0x35U /* Read configuration register */
+#define SPI_NOR_OP_READ_SR 0x05U /* Read status register */
+#define SPI_NOR_OP_READ_FSR 0x70U /* Read flag status register */
+#define SPINOR_OP_RDEAR 0xC8U /* Read Extended Address Register */
+#define SPINOR_OP_WREAR 0xC5U /* Write Extended Address Register */
+
+/* Used for Spansion flashes only. */
+#define SPINOR_OP_BRWR 0x17U /* Bank register write */
+#define SPINOR_OP_BRRD 0x16U /* Bank register read */
+
+#define SPI_NOR_OP_READ 0x03U /* Read data bytes (low frequency) */
+#define SPI_NOR_OP_READ_FAST 0x0BU /* Read data bytes (high frequency) */
+#define SPI_NOR_OP_READ_1_1_2 0x3BU /* Read data bytes (Dual Output SPI) */
+#define SPI_NOR_OP_READ_1_2_2 0xBBU /* Read data bytes (Dual I/O SPI) */
+#define SPI_NOR_OP_READ_1_1_4 0x6BU /* Read data bytes (Quad Output SPI) */
+#define SPI_NOR_OP_READ_1_4_4 0xEBU /* Read data bytes (Quad I/O SPI) */
+
+/* Flags for NOR specific configuration */
+#define SPI_NOR_USE_FSR BIT(0)
+#define SPI_NOR_USE_BANK BIT(1)
+
+struct nor_device {
+ struct spi_mem_op read_op;
+ uint32_t size;
+ uint32_t flags;
+ uint8_t selected_bank;
+ uint8_t bank_write_cmd;
+ uint8_t bank_read_cmd;
+};
+
+int spi_nor_read(unsigned int offset, uintptr_t buffer, size_t length,
+ size_t *length_read);
+int spi_nor_init(unsigned long long *device_size, unsigned int *erase_size);
+
+/*
+ * Platform can implement this to override default NOR instance configuration.
+ *
+ * @device: target NOR instance.
+ * Return 0 on success, negative value otherwise.
+ */
+int plat_get_nor_data(struct nor_device *device);
+
+#endif /* DRIVERS_SPI_NOR_H */
diff --git a/include/drivers/st/io_stm32image.h b/include/drivers/st/io_stm32image.h
index 68060558ba..f9fa3630c6 100644
--- a/include/drivers/st/io_stm32image.h
+++ b/include/drivers/st/io_stm32image.h
@@ -23,7 +23,7 @@ struct stm32image_part_info {
struct stm32image_device_info {
struct stm32image_part_info part_info[STM32_PART_NUM];
- uint32_t device_size;
+ unsigned long long device_size;
uint32_t lba_size;
};
diff --git a/include/drivers/st/stm32_fmc2_nand.h b/include/drivers/st/stm32_fmc2_nand.h
new file mode 100644
index 0000000000..81d5b9de19
--- /dev/null
+++ b/include/drivers/st/stm32_fmc2_nand.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32_FMC2_NAND_H
+#define STM32_FMC2_NAND_H
+
+int stm32_fmc2_init(void);
+
+#endif /* STM32_FMC2_NAND_H */
diff --git a/include/drivers/st/stm32_qspi.h b/include/drivers/st/stm32_qspi.h
new file mode 100644
index 0000000000..f47fca445e
--- /dev/null
+++ b/include/drivers/st/stm32_qspi.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+ */
+
+#ifndef STM32_QSPI_H
+#define STM32_QSPI_H
+
+int stm32_qspi_init(void);
+
+#endif /* STM32_QSPI_H */
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
index 32e38f0ac1..2b95fa33a6 100644
--- a/include/drivers/ti/uart/uart_16550.h
+++ b/include/drivers/ti/uart/uart_16550.h
@@ -87,6 +87,11 @@ typedef struct {
* framework. The |console| pointer must point to storage that will be valid
* for the lifetime of the console, such as a global or static local variable.
* Its contents will be reinitialized from scratch.
+ * When |clock| has a value of 0, the UART will *not* be initialised. This
+ * means the UART should already be enabled and the baudrate and clock setup
+ * should have been done already, either by platform specific code or by
+ * previous firmware stages. The |baud| parameter will be ignored in this
+ * case as well.
*/
int console_16550_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud,
console_16550_t *console);
diff --git a/include/export/lib/utils_def_exp.h b/include/export/lib/utils_def_exp.h
index 86c409ce12..d4a4a85dd4 100644
--- a/include/export/lib/utils_def_exp.h
+++ b/include/export/lib/utils_def_exp.h
@@ -25,11 +25,13 @@
# define L(_x) (_x)
# define LL(_x) (_x)
#else
-# define U(_x) (_x##U)
+# define U_(_x) (_x##U)
+# define U(_x) U_(_x)
# define UL(_x) (_x##UL)
# define ULL(_x) (_x##ULL)
# define L(_x) (_x##L)
# define LL(_x) (_x##LL)
+
#endif
#endif /* ARM_TRUSTED_FIRMWARE_EXPORT_LIB_UTILS_DEF_EXP_H */
diff --git a/include/lib/cpus/aarch64/cortex_a72.h b/include/lib/cpus/aarch64/cortex_a72.h
index 4a444c67aa..28b440e19d 100644
--- a/include/lib/cpus/aarch64/cortex_a72.h
+++ b/include/lib/cpus/aarch64/cortex_a72.h
@@ -43,7 +43,14 @@
******************************************************************************/
#define CORTEX_A72_L2ACTLR_EL1 S3_1_C15_C0_0
+#define CORTEX_A72_L2ACTLR_FORCE_TAG_BANK_CLK_ACTIVE (ULL(1) << 28)
+#define CORTEX_A72_L2ACTLR_FORCE_L2_LOGIC_CLK_ACTIVE (ULL(1) << 27)
+#define CORTEX_A72_L2ACTLR_FORCE_L2_GIC_TIMER_RCG_CLK_ACTIVE (ULL(1) << 26)
#define CORTEX_A72_L2ACTLR_ENABLE_UNIQUE_CLEAN (ULL(1) << 14)
+#define CORTEX_A72_L2ACTLR_DISABLE_DSB_WITH_NO_DVM_SYNC (ULL(1) << 11)
+#define CORTEX_A72_L2ACTLR_DISABLE_DVM_CMO_BROADCAST (ULL(1) << 8)
+#define CORTEX_A72_L2ACTLR_ENABLE_HAZARD_DETECT_TIMEOUT (ULL(1) << 7)
+#define CORTEX_A72_L2ACTLR_DISABLE_ACE_SH_OR_CHI (ULL(1) << 6)
/*******************************************************************************
* L2 Control register specific definitions.
@@ -51,8 +58,12 @@
#define CORTEX_A72_L2CTLR_EL1 S3_1_C11_C0_2
#define CORTEX_A72_L2CTLR_DATA_RAM_LATENCY_SHIFT U(0)
+#define CORTEX_A72_L2CTLR_DATA_RAM_SETUP_SHIFT U(5)
#define CORTEX_A72_L2CTLR_TAG_RAM_LATENCY_SHIFT U(6)
+#define CORTEX_A72_L2CTLR_TAG_RAM_SETUP_SHIFT U(9)
+#define CORTEX_A72_L2_DATA_RAM_LATENCY_MASK U(0x7)
+#define CORTEX_A72_L2_TAG_RAM_LATENCY_MASK U(0x7)
#define CORTEX_A72_L2_DATA_RAM_LATENCY_3_CYCLES U(0x2)
#define CORTEX_A72_L2_TAG_RAM_LATENCY_2_CYCLES U(0x1)
#define CORTEX_A72_L2_TAG_RAM_LATENCY_3_CYCLES U(0x2)
diff --git a/include/lib/cpus/aarch64/cortex_hercules.h b/include/lib/cpus/aarch64/cortex_hercules.h
index b943e7a4d3..d5ca85ed28 100644
--- a/include/lib/cpus/aarch64/cortex_hercules.h
+++ b/include/lib/cpus/aarch64/cortex_hercules.h
@@ -27,6 +27,9 @@
******************************************************************************/
#define CORTEX_HERCULES_ACTLR_TAM_BIT (ULL(1) << 30)
+#define CORTEX_HERCULES_ACTLR2_EL1 S3_0_C15_C1_1
+#define CORTEX_HERCULES_ACTLR2_EL1_BIT_1 (ULL(1) << 1)
+
/*******************************************************************************
* CPU Activity Monitor Unit register specific definitions.
******************************************************************************/
diff --git a/include/lib/debugfs.h b/include/lib/debugfs.h
new file mode 100644
index 0000000000..8ed237ae21
--- /dev/null
+++ b/include/lib/debugfs.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEBUGFS_H
+#define DEBUGFS_H
+
+#define NAMELEN 13 /* Maximum length of a file name */
+#define PATHLEN 41 /* Maximum length of a path */
+#define STATLEN 41 /* Size of static part of dir format */
+#define ROOTLEN (2 + 4) /* Size needed to encode root string */
+#define FILNAMLEN (2 + NAMELEN) /* Size needed to encode filename */
+#define DIRLEN (STATLEN + FILNAMLEN + 3*ROOTLEN) /* Size of dir entry */
+
+#define KSEEK_SET 0
+#define KSEEK_CUR 1
+#define KSEEK_END 2
+
+#define NELEM(tab) (sizeof(tab) / sizeof((tab)[0]))
+
+typedef unsigned short qid_t; /* FIXME: short type not recommended? */
+
+/*******************************************************************************
+ * This structure contains the necessary information to represent a 9p
+ * directory.
+ ******************************************************************************/
+typedef struct {
+ char name[NAMELEN];
+ long length;
+ unsigned char mode;
+ unsigned char index;
+ unsigned char dev;
+ qid_t qid;
+} dir_t;
+
+/* Permission definitions used as flags */
+#define O_READ (1 << 0)
+#define O_WRITE (1 << 1)
+#define O_RDWR (1 << 2)
+#define O_BIND (1 << 3)
+#define O_DIR (1 << 4)
+#define O_STAT (1 << 5)
+
+/* 9p interface */
+int mount(const char *srv, const char *mnt, const char *spec);
+int create(const char *name, int flags);
+int open(const char *name, int flags);
+int close(int fd);
+int read(int fd, void *buf, int n);
+int write(int fd, void *buf, int n);
+int seek(int fd, long off, int whence);
+int bind(const char *path, const char *where);
+int stat(const char *path, dir_t *dir);
+
+/* DebugFS initialization */
+void debugfs_init(void);
+int debugfs_smc_setup(void);
+
+/* Debugfs version returned through SMC interface */
+#define DEBUGFS_VERSION (0x000000001U)
+
+/* Function ID for accessing the debugfs interface */
+#define DEBUGFS_FID_VALUE (0x30U)
+
+#define is_debugfs_fid(_fid) \
+ (((_fid) & FUNCID_NUM_MASK) == DEBUGFS_FID_VALUE)
+
+/* Error code for debugfs SMC interface failures */
+#define DEBUGFS_E_INVALID_PARAMS (-2)
+#define DEBUGFS_E_DENIED (-3)
+
+uintptr_t debugfs_smc_handler(unsigned int smc_fid,
+ u_register_t cmd,
+ u_register_t arg2,
+ u_register_t arg3,
+ u_register_t arg4,
+ void *cookie,
+ void *handle,
+ uintptr_t flags);
+
+#endif /* DEBUGFS_H */
diff --git a/include/lib/libc/aarch32/stddef_.h b/include/lib/libc/aarch32/stddef_.h
index 1babfade35..36dc20bd40 100644
--- a/include/lib/libc/aarch32/stddef_.h
+++ b/include/lib/libc/aarch32/stddef_.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,9 +12,4 @@ typedef unsigned int size_t;
#define SIZET_
#endif
-#ifndef _PTRDIFF_T
-typedef long ptrdiff_t;
-#define _PTRDIFF_T
-#endif
-
#endif /* STDDEF__H */
diff --git a/include/lib/libc/aarch32/stdint_.h b/include/lib/libc/aarch32/stdint_.h
deleted file mode 100644
index 4f494859f4..0000000000
--- a/include/lib/libc/aarch32/stdint_.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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
index 50d3cc2ed9..5e49425cbb 100644
--- a/include/lib/libc/aarch32/stdio_.h
+++ b/include/lib/libc/aarch32/stdio_.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,11 +7,6 @@
#ifndef STDIO__H
#define STDIO__H
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
#ifndef SSIZET_
typedef int ssize_t;
#define SSIZET_
diff --git a/include/lib/libc/aarch32/stdlib_.h b/include/lib/libc/aarch32/stdlib_.h
deleted file mode 100644
index 9c07857a5f..0000000000
--- a/include/lib/libc/aarch32/stdlib_.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STDLIB__H
-#define STDLIB__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#endif /* STDLIB__H */
diff --git a/include/lib/libc/aarch32/string_.h b/include/lib/libc/aarch32/string_.h
deleted file mode 100644
index 4e139b0db8..0000000000
--- a/include/lib/libc/aarch32/string_.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STRING__H
-#define STRING__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-#endif /* STRING__H */
diff --git a/include/lib/libc/aarch32/time_.h b/include/lib/libc/aarch32/time_.h
deleted file mode 100644
index a9169c2932..0000000000
--- a/include/lib/libc/aarch32/time_.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TIME__H
-#define TIME__H
-
-#ifndef SIZET_
-typedef unsigned int size_t;
-#define SIZET_
-#endif
-
-typedef long int time_t;
-
-#endif /* TIME__H */
diff --git a/include/lib/libc/aarch64/stddef_.h b/include/lib/libc/aarch64/stddef_.h
index b7d8209af5..6ecc6067c8 100644
--- a/include/lib/libc/aarch64/stddef_.h
+++ b/include/lib/libc/aarch64/stddef_.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,9 +12,4 @@ typedef unsigned long size_t;
#define SIZET_
#endif
-#ifndef _PTRDIFF_T
-typedef long ptrdiff_t;
-#define _PTRDIFF_T
-#endif
-
#endif /* STDDEF__H */
diff --git a/include/lib/libc/aarch64/stdint_.h b/include/lib/libc/aarch64/stdint_.h
deleted file mode 100644
index b17a435b08..0000000000
--- a/include/lib/libc/aarch64/stdint_.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2018-2019, 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;
-
-typedef __int128 int128_t;
-typedef unsigned __int128 uint128_t;
diff --git a/include/lib/libc/aarch64/stdio_.h b/include/lib/libc/aarch64/stdio_.h
index 09b0172dd1..afaeadc218 100644
--- a/include/lib/libc/aarch64/stdio_.h
+++ b/include/lib/libc/aarch64/stdio_.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,11 +7,6 @@
#ifndef STDIO__H
#define STDIO__H
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
#ifndef SSIZET_
typedef long ssize_t;
#define SSIZET_
diff --git a/include/lib/libc/aarch64/stdlib_.h b/include/lib/libc/aarch64/stdlib_.h
deleted file mode 100644
index 81a39d14a5..0000000000
--- a/include/lib/libc/aarch64/stdlib_.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STDLIB__H
-#define STDLIB__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#endif /* STDLIB__H */
diff --git a/include/lib/libc/aarch64/string_.h b/include/lib/libc/aarch64/string_.h
deleted file mode 100644
index 71c51a6cd7..0000000000
--- a/include/lib/libc/aarch64/string_.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef STRING__H
-#define STRING__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-#endif /* STRING__H */
diff --git a/include/lib/libc/aarch64/time_.h b/include/lib/libc/aarch64/time_.h
deleted file mode 100644
index 68ab1b8dd9..0000000000
--- a/include/lib/libc/aarch64/time_.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef TIME__H
-#define TIME__H
-
-#ifndef SIZET_
-typedef unsigned long size_t;
-#define SIZET_
-#endif
-
-typedef long int time_t;
-
-#endif /* TIME__H */
diff --git a/include/lib/libc/stddef.h b/include/lib/libc/stddef.h
index c9957bdb1c..58a519e523 100644
--- a/include/lib/libc/stddef.h
+++ b/include/lib/libc/stddef.h
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
@@ -13,6 +13,11 @@
#include <stddef_.h>
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
+
#ifndef NULL
#define NULL ((void *) 0)
#endif
diff --git a/include/lib/libc/stdint.h b/include/lib/libc/stdint.h
index d44a973f12..818870e164 100644
--- a/include/lib/libc/stdint.h
+++ b/include/lib/libc/stdint.h
@@ -4,13 +4,135 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
#ifndef STDINT_H
#define STDINT_H
-#include <stdint_.h>
+#include <limits.h>
+
+#define INT8_MAX CHAR_MAX
+#define INT8_MIN CHAR_MIN
+#define UINT8_MAX UCHAR_MAX
+
+#define INT16_MAX SHRT_MAX
+#define INT16_MIN SHRT_MIN
+#define UINT16_MAX USHRT_MAX
+
+#define INT32_MAX INT_MAX
+#define INT32_MIN INT_MIN
+#define UINT32_MAX UINT_MAX
+
+#define INT64_MAX LLONG_MAX
+#define INT64_MIN LLONG_MIN
+#define UINT64_MAX ULLONG_MAX
+
+#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 LONG_MIN
+#define INTPTR_MAX LONG_MAX
+#define UINTPTR_MAX ULONG_MAX
+
+#define INTMAX_MIN LLONG_MIN
+#define INTMAX_MAX LLONG_MAX
+#define UINTMAX_MAX ULLONG_MAX
+
+#define PTRDIFF_MIN LONG_MIN
+#define PTRDIFF_MAX LONG_MAX
+
+#define SIZE_MAX ULONG_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;
+
+/*
+* Conceptually, these are supposed to be the largest integers representable in C,
+* but GCC and Clang define them as long long for compatibility.
+*/
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef long register_t;
+typedef unsigned long u_register_t;
+
+#ifdef __aarch64__
+typedef __int128 int128_t;
+typedef unsigned __int128 uint128_t;
+#endif /* __aarch64__ */
#endif /* STDINT_H */
diff --git a/include/lib/libc/stdio.h b/include/lib/libc/stdio.h
index 3d9323efa5..2d9e6557b0 100644
--- a/include/lib/libc/stdio.h
+++ b/include/lib/libc/stdio.h
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
@@ -12,12 +12,9 @@
#define STDIO_H
#include <cdefs.h>
+#include <stddef.h>
#include <stdio_.h>
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-
#define EOF -1
int printf(const char *fmt, ...) __printflike(1, 2);
diff --git a/include/lib/libc/stdlib.h b/include/lib/libc/stdlib.h
index edd6265f51..24e7bae2f8 100644
--- a/include/lib/libc/stdlib.h
+++ b/include/lib/libc/stdlib.h
@@ -4,18 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
#ifndef STDLIB_H
#define STDLIB_H
-#include <stdlib_.h>
+#include <stddef.h>
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
#define _ATEXIT_MAX 1
diff --git a/include/lib/libc/string.h b/include/lib/libc/string.h
index ee6eeacef9..71774b0c81 100644
--- a/include/lib/libc/string.h
+++ b/include/lib/libc/string.h
@@ -4,18 +4,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
#ifndef STRING_H
#define STRING_H
-#include <string_.h>
-
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+#include <stddef.h>
void *memcpy(void *dst, const void *src, size_t len);
void *memmove(void *dst, const void *src, size_t len);
@@ -23,6 +19,7 @@ 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);
+void *memrchr(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);
diff --git a/include/lib/libc/time.h b/include/lib/libc/time.h
index 71d3e7ec96..c1c95e5863 100644
--- a/include/lib/libc/time.h
+++ b/include/lib/libc/time.h
@@ -4,17 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
- * Portions copyright (c) 2018, ARM Limited and Contributors.
+ * Portions copyright (c) 2018-2019, ARM Limited and Contributors.
* All rights reserved.
*/
#ifndef TIME_H
#define TIME_H
-#include <time_.h>
+#include <stddef.h>
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
+typedef long int time_t;
#endif /* TIME_H */
diff --git a/include/lib/pmf/aarch32/pmf_asm_macros.S b/include/lib/pmf/aarch32/pmf_asm_macros.S
new file mode 100644
index 0000000000..1dbb408cac
--- /dev/null
+++ b/include/lib/pmf/aarch32/pmf_asm_macros.S
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PMF_ASM_MACROS_S
+#define PMF_ASM_MACROS_S
+
+#define PMF_TS_SIZE 8
+
+ /*
+ * This macro calculates the address of the per-cpu timestamp
+ * for the given service name and local timestamp id.
+ * Clobbers: r0 - r4
+ */
+ .macro pmf_calc_timestamp_addr _name, _tid
+ mov r4, lr
+ bl plat_my_core_pos
+ mov lr, r4
+ ldr r1, =__PERCPU_TIMESTAMP_SIZE__
+ mov r2, #(\_tid * PMF_TS_SIZE)
+ mla r0, r0, r1, r2
+ ldr r1, =pmf_ts_mem_\_name
+ add r0, r0, r1
+ .endm
+
+#endif /* PMF_ASM_MACROS_S */
diff --git a/include/lib/pmf/pmf_asm_macros.S b/include/lib/pmf/aarch64/pmf_asm_macros.S
index 5f3e6b7ecc..5f3e6b7ecc 100644
--- a/include/lib/pmf/pmf_asm_macros.S
+++ b/include/lib/pmf/aarch64/pmf_asm_macros.S
diff --git a/include/lib/pmf/pmf.h b/include/lib/pmf/pmf.h
index df7c9ff310..3fc8e3863d 100644
--- a/include/lib/pmf/pmf.h
+++ b/include/lib/pmf/pmf.h
@@ -54,108 +54,6 @@
#define PMF_PSCI_STAT_SVC_ID 0
#define PMF_RT_INSTR_SVC_ID 1
-#if ENABLE_PMF
-/*
- * Convenience macros for capturing time-stamp.
- */
-#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \
- void pmf_capture_timestamp_with_cache_maint_ ## _name( \
- unsigned int tid, \
- unsigned long long ts); \
- void pmf_capture_timestamp_ ## _name( \
- unsigned int tid, \
- unsigned long long ts);
-
-#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \
- do { \
- unsigned long long ts = read_cntpct_el0(); \
- if (((_flags) & PMF_CACHE_MAINT) != 0U) \
- pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
- else \
- pmf_capture_timestamp_ ## _name((_tid), ts); \
- } while (0)
-
-#define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \
- do { \
- (_tsval) = read_cntpct_el0(); \
- CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
- if (((_flags) & PMF_CACHE_MAINT) != 0U) \
- pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
- else \
- pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
- } while (0)
-
-#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \
- do { \
- CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
- if (((_flags) & PMF_CACHE_MAINT) != 0U) \
- pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
- else \
- pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
- } while (0)
-
-/*
- * Convenience macros for retrieving time-stamp.
- */
-#define PMF_DECLARE_GET_TIMESTAMP(_name) \
- unsigned long long pmf_get_timestamp_by_index_ ## _name(\
- unsigned int tid, \
- unsigned int cpuid, \
- unsigned int flags); \
- unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
- unsigned int tid, \
- u_register_t mpidr, \
- unsigned int flags);
-
-#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
- _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
-
-#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
- _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
-
-/* Convenience macros to register a PMF service.*/
-/*
- * This macro is used to register a PMF Service. It allocates PMF memory
- * and defines default service-specific PMF functions.
- */
-#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
- PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \
- PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
- PMF_DEFINE_GET_TIMESTAMP(_name)
-
-/*
- * This macro is used to register a PMF service, including an
- * SMC interface to that service.
- */
-#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
- PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
- PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \
- _svcid, _totalid, NULL, \
- pmf_get_timestamp_by_mpidr_ ## _name)
-
-/*
- * This macro is used to register a PMF service that has an SMC interface
- * but provides its own service-specific PMF functions.
- */
-#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
- _init, _getts) \
- PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \
- _init, _getts)
-
-#else
-
-#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
-#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
-#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
- _init, _getts)
-#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
-#define PMF_DECLARE_GET_TIMESTAMP(_name)
-#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
-#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
-#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
-
-#endif /* ENABLE_PMF */
-
/*******************************************************************************
* Function & variable prototypes
******************************************************************************/
diff --git a/include/lib/pmf/pmf_helpers.h b/include/lib/pmf/pmf_helpers.h
index e6798a7ce7..db38e556a9 100644
--- a/include/lib/pmf/pmf_helpers.h
+++ b/include/lib/pmf/pmf_helpers.h
@@ -43,6 +43,108 @@ typedef struct pmf_svc_desc {
pmf_svc_get_ts_t get_ts;
} pmf_svc_desc_t;
+#if ENABLE_PMF
+/*
+ * Convenience macros for capturing time-stamp.
+ */
+#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name) \
+ void pmf_capture_timestamp_with_cache_maint_ ## _name( \
+ unsigned int tid, \
+ unsigned long long ts); \
+ void pmf_capture_timestamp_ ## _name( \
+ unsigned int tid, \
+ unsigned long long ts);
+
+#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags) \
+ do { \
+ unsigned long long ts = read_cntpct_el0(); \
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
+ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), ts);\
+ else \
+ pmf_capture_timestamp_ ## _name((_tid), ts); \
+ } while (0)
+
+#define PMF_CAPTURE_AND_GET_TIMESTAMP(_name, _tid, _flags, _tsval) \
+ do { \
+ (_tsval) = read_cntpct_el0(); \
+ CASSERT(sizeof(_tsval) == sizeof(unsigned long long), invalid_tsval_size);\
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
+ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_tsval));\
+ else \
+ pmf_capture_timestamp_ ## _name((_tid), (_tsval));\
+ } while (0)
+
+#define PMF_WRITE_TIMESTAMP(_name, _tid, _flags, _wrval) \
+ do { \
+ CASSERT(sizeof(_wrval) == sizeof(unsigned long long), invalid_wrval_size);\
+ if (((_flags) & PMF_CACHE_MAINT) != 0U) \
+ pmf_capture_timestamp_with_cache_maint_ ## _name((_tid), (_wrval));\
+ else \
+ pmf_capture_timestamp_ ## _name((_tid), (_wrval));\
+ } while (0)
+
+/*
+ * Convenience macros for retrieving time-stamp.
+ */
+#define PMF_DECLARE_GET_TIMESTAMP(_name) \
+ unsigned long long pmf_get_timestamp_by_index_ ## _name(\
+ unsigned int tid, \
+ unsigned int cpuid, \
+ unsigned int flags); \
+ unsigned long long pmf_get_timestamp_by_mpidr_ ## _name(\
+ unsigned int tid, \
+ u_register_t mpidr, \
+ unsigned int flags);
+
+#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)\
+ _tsval = pmf_get_timestamp_by_mpidr_ ## _name(_tid, _mpidr, _flags)
+
+#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)\
+ _tsval = pmf_get_timestamp_by_index_ ## _name(_tid, _cpuid, _flags)
+
+/* Convenience macros to register a PMF service.*/
+/*
+ * This macro is used to register a PMF Service. It allocates PMF memory
+ * and defines default service-specific PMF functions.
+ */
+#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
+ PMF_ALLOCATE_TIMESTAMP_MEMORY(_name, _totalid) \
+ PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
+ PMF_DEFINE_GET_TIMESTAMP(_name)
+
+/*
+ * This macro is used to register a PMF service, including an
+ * SMC interface to that service.
+ */
+#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)\
+ PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags) \
+ PMF_DEFINE_SERVICE_DESC(_name, PMF_ARM_TIF_IMPL_ID, \
+ _svcid, _totalid, NULL, \
+ pmf_get_timestamp_by_mpidr_ ## _name)
+
+/*
+ * This macro is used to register a PMF service that has an SMC interface
+ * but provides its own service-specific PMF functions.
+ */
+#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
+ _init, _getts) \
+ PMF_DEFINE_SERVICE_DESC(_name, _implid, _svcid, _totalid, \
+ _init, _getts)
+
+#else
+
+#define PMF_REGISTER_SERVICE(_name, _svcid, _totalid, _flags)
+#define PMF_REGISTER_SERVICE_SMC(_name, _svcid, _totalid, _flags)
+#define PMF_REGISTER_SERVICE_SMC_OWN(_name, _implid, _svcid, _totalid, \
+ _init, _getts)
+#define PMF_DECLARE_CAPTURE_TIMESTAMP(_name)
+#define PMF_DECLARE_GET_TIMESTAMP(_name)
+#define PMF_CAPTURE_TIMESTAMP(_name, _tid, _flags)
+#define PMF_GET_TIMESTAMP_BY_MPIDR(_name, _tid, _mpidr, _flags, _tsval)
+#define PMF_GET_TIMESTAMP_BY_INDEX(_name, _tid, _cpuid, _flags, _tsval)
+
+#endif /* ENABLE_PMF */
+
/*
* Convenience macro to allocate memory for a PMF service.
*
@@ -69,9 +171,6 @@ typedef struct pmf_svc_desc {
#define PMF_DEFINE_CAPTURE_TIMESTAMP(_name, _flags) \
void pmf_capture_timestamp_ ## _name( \
unsigned int tid, \
- unsigned long long ts); \
- void pmf_capture_timestamp_ ## _name( \
- unsigned int tid, \
unsigned long long ts) \
{ \
CASSERT(_flags, select_proper_config); \
@@ -84,9 +183,6 @@ typedef struct pmf_svc_desc {
} \
void pmf_capture_timestamp_with_cache_maint_ ## _name( \
unsigned int tid, \
- unsigned long long ts); \
- void pmf_capture_timestamp_with_cache_maint_ ## _name( \
- unsigned int tid, \
unsigned long long ts) \
{ \
CASSERT(_flags, select_proper_config); \
@@ -105,8 +201,6 @@ typedef struct pmf_svc_desc {
*/
#define PMF_DEFINE_GET_TIMESTAMP(_name) \
unsigned long long pmf_get_timestamp_by_index_ ## _name( \
- unsigned int tid, unsigned int cpuid, unsigned int flags);\
- unsigned long long pmf_get_timestamp_by_index_ ## _name( \
unsigned int tid, unsigned int cpuid, unsigned int flags)\
{ \
PMF_VALIDATE_TID(_name, tid); \
@@ -114,8 +208,6 @@ typedef struct pmf_svc_desc {
return __pmf_get_timestamp(base_addr, tid, cpuid, flags);\
} \
unsigned long long pmf_get_timestamp_by_mpidr_ ## _name( \
- unsigned int tid, u_register_t mpidr, unsigned int flags);\
- unsigned long long pmf_get_timestamp_by_mpidr_ ## _name( \
unsigned int tid, u_register_t mpidr, unsigned int flags)\
{ \
PMF_VALIDATE_TID(_name, tid); \
diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h
index 7f7b7e3ff5..b56e98b5f3 100644
--- a/include/lib/psci/psci.h
+++ b/include/lib/psci/psci.h
@@ -20,7 +20,7 @@
#ifdef PLAT_NUM_PWR_DOMAINS
#define PSCI_NUM_PWR_DOMAINS PLAT_NUM_PWR_DOMAINS
#else
-#define PSCI_NUM_PWR_DOMAINS (2 * PLATFORM_CORE_COUNT)
+#define PSCI_NUM_PWR_DOMAINS (U(2) * PLATFORM_CORE_COUNT)
#endif
#define PSCI_NUM_NON_CPU_PWR_DOMAINS (PSCI_NUM_PWR_DOMAINS - \
diff --git a/include/lib/smccc.h b/include/lib/smccc.h
index dd3c578dcc..5e13e6f0a5 100644
--- a/include/lib/smccc.h
+++ b/include/lib/smccc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -41,6 +41,8 @@
#define FUNCID_NUM_MASK U(0xffff)
#define FUNCID_NUM_WIDTH U(16)
+#define GET_SMC_NUM(id) (((id) >> FUNCID_NUM_SHIFT) & \
+ FUNCID_NUM_MASK)
#define GET_SMC_TYPE(id) (((id) >> FUNCID_TYPE_SHIFT) & \
FUNCID_TYPE_MASK)
#define GET_SMC_CC(id) (((id) >> FUNCID_CC_SHIFT) & \
diff --git a/include/lib/sprt/sprt_common.h b/include/lib/sprt/sprt_common.h
deleted file mode 100644
index 27d5027497..0000000000
--- a/include/lib/sprt/sprt_common.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_COMMON_H
-#define SPRT_COMMON_H
-
-#define SPRT_MAX_MSG_ARGS 6
-
-/*
- * Message types supported.
- */
-#define SPRT_MSG_TYPE_SERVICE_HANDLE_OPEN 1
-#define SPRT_MSG_TYPE_SERVICE_HANDLE_CLOSE 2
-/* TODO: Add other types of SPRT messages. */
-#define SPRT_MSG_TYPE_SERVICE_TUN_REQUEST 10
-
-/*
- * Struct that defines the layout of the fields corresponding to a request in
- * shared memory.
- */
-struct __attribute__((__packed__)) sprt_queue_entry_message {
- uint32_t type; /* Type of message (result of an SPCI call). */
- uint16_t client_id; /* SPCI client ID */
- uint16_t service_handle;/* SPCI service handle */
- uint32_t session_id; /* Optional SPCI session ID */
- uint32_t token; /* SPCI request token */
- uint64_t args[SPRT_MAX_MSG_ARGS];
-};
-
-#define SPRT_QUEUE_ENTRY_MSG_SIZE (sizeof(struct sprt_queue_entry_message))
-
-#define SPRT_QUEUE_NUM_BLOCKING 0
-#define SPRT_QUEUE_NUM_NON_BLOCKING 1
-
-#endif /* SPRT_COMMON_H */
diff --git a/include/lib/sprt/sprt_host.h b/include/lib/sprt/sprt_host.h
deleted file mode 100644
index f888141dd1..0000000000
--- a/include/lib/sprt/sprt_host.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef SPRT_HOST_H
-#define SPRT_HOST_H
-
-#include <stddef.h>
-
-#include "sprt_common.h"
-
-/*
- * Initialize the specified buffer to be used by SPM.
- */
-void sprt_initialize_queues(void *buffer_base, size_t buffer_size);
-
-/*
- * Push a message to the queue number `queue_num` in a buffer that has been
- * initialized by `sprt_initialize_queues`.
- */
-int sprt_push_message(void *buffer_base,
- const struct sprt_queue_entry_message *message,
- int queue_num);
-
-#endif /* SPRT_HOST_H */
diff --git a/include/lib/utils.h b/include/lib/utils.h
index cdb125cfa4..17ee93694e 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -79,13 +79,11 @@ void zeromem(void *mem, u_register_t length);
* which is constant and does not depend on the execute address of the binary.
*/
#define DEFINE_LOAD_SYM_ADDR(_name) \
-static inline u_register_t load_addr_## _name(void) \
-{ \
- u_register_t v; \
- /* Create a void reference to silence compiler */ \
- (void) _name; \
- __asm__ volatile ("ldr %0, =" #_name : "=r" (v)); \
- return v; \
+static inline u_register_t load_addr_## _name(void) \
+{ \
+ u_register_t v; \
+ __asm__ volatile ("ldr %0, =" #_name : "=r" (v) : "X" (#_name));\
+ return v; \
}
/* Helper to invoke the function defined by DEFINE_LOAD_SYM_ADDR() */
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
index 35ae33a682..23f59bdc33 100644
--- a/include/lib/utils_def.h
+++ b/include/lib/utils_def.h
@@ -77,6 +77,15 @@
_x > _y ? _x : _y; \
})
+#define CLAMP(x, min, max) __extension__ ({ \
+ __typeof__(x) _x = (x); \
+ __typeof__(min) _min = (min); \
+ __typeof__(max) _max = (max); \
+ (void)(&_x == &_min); \
+ (void)(&_x == &_max); \
+ (_x > _max ? _max : (_x < _min ? _min : _x)); \
+})
+
/*
* The round_up() macro rounds up a value to the given boundary in a
* type-agnostic yet type-safe manner. The boundary must be a power of two.
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 941190fdc1..b419c853e6 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -21,7 +21,7 @@
/* Special value used to verify platform parameters from BL2 to BL31 */
#define ARM_BL31_PLAT_PARAM_VAL ULL(0x0f1e2d3c4b5a6978)
-#define ARM_SYSTEM_COUNT 1
+#define ARM_SYSTEM_COUNT U(1)
#define ARM_CACHE_WRITEBACK_SHIFT 6
@@ -457,7 +457,7 @@
* Trusted DRAM (if available) or the DRAM region secured by the TrustZone
* controller.
*/
-# if ENABLE_SPM
+# if SPM_MM
# define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
# define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000))
# define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000))
@@ -500,9 +500,9 @@
* SPD and no SPM, as they are the only ones that can be used as BL32.
*/
#if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME
-# if defined(SPD_none) && !ENABLE_SPM
+# if defined(SPD_none) && !SPM_MM
# undef BL32_BASE
-# endif /* defined(SPD_none) && !ENABLE_SPM */
+# endif /* defined(SPD_none) && !SPM_MM*/
#endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */
/*******************************************************************************
diff --git a/include/plat/arm/common/arm_reclaim_init.ld.S b/include/plat/arm/common/arm_reclaim_init.ld.S
index 8f22170fe6..b5bf473652 100644
--- a/include/plat/arm/common/arm_reclaim_init.ld.S
+++ b/include/plat/arm/common/arm_reclaim_init.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -27,10 +27,9 @@ SECTIONS
"BL31 init has exceeded progbits limit.")
#endif
-#if RECLAIM_INIT_CODE
ASSERT(__INIT_CODE_END__ <= __STACKS_END__,
"Init code ends past the end of the stacks")
-#endif
+
}
#endif /* ARM_RECLAIM_INIT_LD_S */
diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h
index 16573ce6a6..85fdb289f1 100644
--- a/include/plat/arm/common/arm_sip_svc.h
+++ b/include/plat/arm/common/arm_sip_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,9 +16,15 @@
/* U(0x8200ff02) is reserved */
#define ARM_SIP_SVC_VERSION U(0x8200ff03)
+/* PMF_SMC_GET_TIMESTAMP_32 0x82000010 */
+/* PMF_SMC_GET_TIMESTAMP_64 0xC2000010 */
+
/* Function ID for requesting state switch of lower EL */
#define ARM_SIP_SVC_EXE_STATE_SWITCH U(0x82000020)
+/* DEBUGFS_SMC_32 0x82000030U */
+/* DEBUGFS_SMC_64 0xC2000030U */
+
/* ARM SiP Service Calls version numbers */
#define ARM_SIP_SVC_VERSION_MAJOR U(0x0)
#define ARM_SIP_SVC_VERSION_MINOR U(0x2)
diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h
index 16c806ba6c..c43583de2d 100644
--- a/include/plat/arm/common/arm_spm_def.h
+++ b/include/plat/arm/common/arm_spm_def.h
@@ -10,31 +10,6 @@
#include <lib/xlat_tables/xlat_tables_defs.h>
/*
- * Reserve 4 MiB for binaries of Secure Partitions and Resource Description
- * blobs.
- */
-#define PLAT_SP_PACKAGE_BASE BL32_BASE
-#define PLAT_SP_PACKAGE_SIZE ULL(0x400000)
-
-#define PLAT_MAP_SP_PACKAGE_MEM_RO MAP_REGION_FLAT( \
- PLAT_SP_PACKAGE_BASE, \
- PLAT_SP_PACKAGE_SIZE, \
- MT_MEMORY | MT_RO | MT_SECURE)
-#define PLAT_MAP_SP_PACKAGE_MEM_RW MAP_REGION_FLAT( \
- PLAT_SP_PACKAGE_BASE, \
- PLAT_SP_PACKAGE_SIZE, \
- MT_MEMORY | MT_RW | MT_SECURE)
-
-/*
- * The rest of the memory reserved for BL32 is free for SPM to use it as memory
- * pool to allocate memory regions requested in the resource description.
- */
-#define PLAT_SPM_HEAP_BASE (PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE)
-#define PLAT_SPM_HEAP_SIZE (BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE)
-
-#if SPM_MM
-
-/*
* If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the
* region used by BL31. If BL31 it is placed in SRAM, put the Secure Partition
* at the base of DRAM.
@@ -121,23 +96,8 @@
/* Total number of memory regions with distinct properties */
#define ARM_SP_IMAGE_NUM_MEM_REGIONS 6
-#endif /* SPM_MM */
-
/* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */
#define PLAT_SPM_COOKIE_0 ULL(0)
#define PLAT_SPM_COOKIE_1 ULL(0)
-/*
- * Max number of elements supported by SPM in this platform. The defines below
- * are used to allocate memory at compile time for different arrays in SPM.
- */
-#define PLAT_SPM_MAX_PARTITIONS U(2)
-
-#define PLAT_SPM_MEM_REGIONS_MAX U(80)
-#define PLAT_SPM_NOTIFICATIONS_MAX U(30)
-#define PLAT_SPM_SERVICES_MAX U(30)
-
-#define PLAT_SPCI_HANDLES_MAX_NUM U(20)
-#define PLAT_SPM_RESPONSES_MAX U(30)
-
#endif /* ARM_SPM_DEF_H */
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index c00a041264..02feec7086 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -38,7 +38,7 @@ typedef struct arm_tzc_regions_info {
* - Region 1 with secure access only;
* - the remaining DRAM regions access from the given Non-Secure masters.
******************************************************************************/
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
#define ARM_TZC_REGIONS_DEF \
{ARM_AP_TZC_DRAM1_BASE, ARM_EL3_TZC_DRAM1_END, \
TZC_REGION_S_RDWR, 0}, \
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index eeae62141c..332cfca8d7 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -22,7 +22,7 @@ struct image_desc;
struct bl_load_info;
struct bl_params;
struct mmap_region;
-struct secure_partition_boot_info;
+struct spm_mm_boot_info;
struct sp_res_desc;
/*******************************************************************************
@@ -237,7 +237,7 @@ void plat_psci_stat_accounting_start(const psci_power_state_t *state_info);
void plat_psci_stat_accounting_stop(const psci_power_state_t *state_info);
u_register_t plat_psci_stat_get_residency(unsigned int lvl,
const psci_power_state_t *state_info,
- int last_cpu_idx);
+ unsigned int last_cpu_idx);
plat_local_state_t plat_get_target_pwr_state(unsigned int lvl,
const plat_local_state_t *states,
unsigned int ncpu);
@@ -267,7 +267,7 @@ int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size);
* Secure Partitions functions
******************************************************************************/
const struct mmap_region *plat_get_secure_partition_mmap(void *cookie);
-const struct secure_partition_boot_info *plat_get_secure_partition_boot_info(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
void *cookie);
int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size);
int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
diff --git a/include/plat/marvell/a8k/common/armada_common.h b/include/plat/marvell/a8k/common/armada_common.h
index dd2a24abca..709d009c21 100644
--- a/include/plat/marvell/a8k/common/armada_common.h
+++ b/include/plat/marvell/a8k/common/armada_common.h
@@ -124,5 +124,6 @@ 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);
+int system_power_off(void);
#endif /* ARMADA_COMMON_H */
diff --git a/include/services/mm_svc.h b/include/services/mm_svc.h
deleted file mode 100644
index c11132696c..0000000000
--- a/include/services/mm_svc.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef MM_SVC_H
-#define MM_SVC_H
-
-#if SPM_MM
-
-#include <lib/utils_def.h>
-
-#define MM_VERSION_MAJOR U(1)
-#define MM_VERSION_MAJOR_SHIFT 16
-#define MM_VERSION_MAJOR_MASK U(0x7FFF)
-#define MM_VERSION_MINOR U(0)
-#define MM_VERSION_MINOR_SHIFT 0
-#define MM_VERSION_MINOR_MASK U(0xFFFF)
-#define MM_VERSION_FORM(major, minor) ((major << MM_VERSION_MAJOR_SHIFT) | (minor))
-#define MM_VERSION_COMPILED MM_VERSION_FORM(MM_VERSION_MAJOR, MM_VERSION_MINOR)
-
-/*
- * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
- * These FIDs occupy the range 0x40 - 0x5f.
- * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
- */
-#define MM_VERSION_AARCH32 U(0x84000040)
-
-#define MM_COMMUNICATE_AARCH64 U(0xC4000041)
-#define MM_COMMUNICATE_AARCH32 U(0x84000041)
-
-#endif /* SPM_MM */
-
-#endif /* MM_SVC_H */
diff --git a/include/services/sp_res_desc.h b/include/services/sp_res_desc.h
deleted file mode 100644
index b8be72eeb5..0000000000
--- a/include/services/sp_res_desc.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_RES_DESC_H
-#define SPM_RES_DESC_H
-
-#include <stdint.h>
-
-#include <services/sp_res_desc_def.h>
-
-/*******************************************************************************
- * Attribute Section
- ******************************************************************************/
-
-struct sp_rd_sect_attribute {
- /*
- * Version of the resource description.
- */
- uint16_t version;
-
- /*
- * Type of the Secure Partition:
- * - bit[0]: SP Type
- * - b'0: UP SP
- * - b'1: MP SP
- * If UP SP:
- * - bit[1]: Type of UP SP
- * - b'0: Migratable UP SP
- * - b'1: Pinned UP SP
- */
- uint16_t sp_type;
-
- /*
- * If this is a Pinned UP SP, PE on which the Pinned UP SP will run.
- */
- uint32_t pe_mpidr;
-
- /*
- * Run-Time Exception Level:
- * - 0: SEL0 SP
- * - 1: SEL1 SP
- */
- uint8_t runtime_el;
-
- /*
- * Type of Execution:
- * - 0: Init-time only
- * - 1: Run-time Execution
- */
- uint8_t exec_type;
-
- /*
- * Expected behavior upon failure:
- * - 0: Restartable
- * - 1: One-Shot
- */
- uint8_t panic_policy;
-
- /*
- * Translation Granule to use in the SP translation regime:
- * - 0: 4KB
- * - 1: 16KB
- * - 2: 64KB
- */
- uint8_t xlat_granule;
-
- /*
- * Size of the SP binary in bytes.
- */
- uint32_t binary_size;
-
- /*
- * - If SP is NOT PIE:
- * - VA Address where the SP expects to be loaded.
- * - If SP is PIE:
- * - Ignored.
- */
- uint64_t load_address;
-
- /*
- * Initial execution address. This is a VA as the SP sees it.
- */
- uint64_t entrypoint;
-};
-
-/*******************************************************************************
- * Memory Region Section
- ******************************************************************************/
-
-struct sp_rd_sect_mem_region {
- /*
- * Name of a Memory region, including null terminator. Reserved names:
- * - "Client Shared Memory Region":
- * Memory region where memory shared by clients shall be mapped.
- * - "Queue Memory Region":
- * Memory region shared with SPM for SP queue management.
- */
- char name[RD_MEM_REGION_NAME_LEN];
-
- /*
- * Memory Attributes:
- * - bits[3:0]: Type of memory
- * - 0: Device
- * - 1: Code
- * - 2: Data
- * - 3: BSS
- * - 4: Read-only Data
- * - 5: SPM-to-SP Shared Memory Region
- * - 6: Client Shared Memory Region
- * - 7: Miscellaneous
- * - If memory is { SPM-to-SP shared Memory, Client Shared Memory,
- * Miscellaneous }
- * - bits[4]: Position Independent
- * - b'0: Position Dependent
- * - b'1: Position Independent
- */
- uint32_t attr;
-
- /*
- * Base address of the memory region.
- */
- uint64_t base;
-
- /*
- * Size of the memory region.
- */
- uint64_t size;
-
- /*
- * Pointer to next memory region (or NULL if this is the last one).
- */
- struct sp_rd_sect_mem_region *next;
-};
-
-/*******************************************************************************
- * Notification Section
- ******************************************************************************/
-
-struct sp_rd_sect_notification {
- /*
- * Notification attributes:
- * - bit[31]: Notification Type
- * - b'0: Platform Notification
- * - b'1: Interrupt
- * If Notification Type == Platform Notification
- * - bits[15:0]: Implementation-defined Notification ID
- * If Notification Type == Interrupt
- * - bits[15:0]: IRQ number
- * - bits[23:16]: Interrupt Priority
- * - bit[24]: Trigger Type
- * - b'0: Edge Triggered
- * - b'1: Level Triggered
- * - bit[25]: Trigger Level
- * - b'0: Falling or Low
- * - b'1: Rising or High
- */
- uint32_t attr;
-
- /*
- * Processing Element.
- * If Notification Type == Interrupt && IRQ number is { SGI, LPI }
- * - PE ID to which IRQ will be forwarded
- */
- uint32_t pe;
-
- /*
- * Pointer to next notification (or NULL if this is the last one).
- */
- struct sp_rd_sect_notification *next;
-};
-
-/*******************************************************************************
- * Service Description Section
- ******************************************************************************/
-
-struct sp_rd_sect_service {
- /*
- * Service identifier.
- */
- uint32_t uuid[4];
-
- /*
- * Accessibility Options:
- * - bit[0]: Accessibility by secure-world clients
- * - b'0: Not Accessible
- * - b'1: Accessible
- * - bit[1]: Accessible by EL3
- * - b'0: Not Accessible
- * - b'1: Accessible
- * - bit[2]: Accessible by normal-world clients
- * - b'0: Not Accessible
- * - b'1: Accessible
- */
- uint8_t accessibility;
-
- /*
- * Request type supported:
- * - bit[0]: Blocking request
- * - b'0: Not Enable
- * - b'1: Enable
- * - bit[1]: Non-blocking request
- * - b'0: Not Enable
- * - b'1: Enable
- */
- uint8_t request_type;
-
- /*
- * Maximum number of client connections that the service can support.
- */
- uint16_t connection_quota;
-
- /*
- * If the service requires secure world memory to be shared with its
- * clients:
- * - Maximum amount of secure world memory in bytes to reserve from the
- * secure world memory pool for the service.
- */
- uint32_t secure_mem_size;
-
- /*
- * Interrupt number used to notify the SP for the service.
- * - Should also be enabled in the Notification Section.
- */
- uint32_t interrupt_num;
-
- /*
- * Pointer to next service (or NULL if this is the last one).
- */
- struct sp_rd_sect_service *next;
-};
-
-/*******************************************************************************
- * Complete resource description struct
- ******************************************************************************/
-
-struct sp_res_desc {
-
- /* Attribute Section */
- struct sp_rd_sect_attribute attribute;
-
- /* System Resource Section */
- struct sp_rd_sect_mem_region *mem_region;
-
- struct sp_rd_sect_notification *notification;
-
- /* Service Section */
- struct sp_rd_sect_service *service;
-};
-
-#endif /* SPM_RES_DESC_H */
diff --git a/include/services/sp_res_desc_def.h b/include/services/sp_res_desc_def.h
deleted file mode 100644
index 5a3c50d7f9..0000000000
--- a/include/services/sp_res_desc_def.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_RES_DESC_DEFS_H
-#define SPM_RES_DESC_DEFS_H
-
-#include <lib/utils_def.h>
-
-/*******************************************************************************
- * Attribute Section
- ******************************************************************************/
-
-#define RD_ATTR_TYPE_UP_MIGRATABLE U(0)
-#define RD_ATTR_TYPE_UP_PINNED U(2)
-#define RD_ATTR_TYPE_MP U(1)
-
-#define RD_ATTR_RUNTIME_SEL0 U(0)
-#define RD_ATTR_RUNTIME_SEL1 U(1)
-
-#define RD_ATTR_INIT_ONLY U(0)
-#define RD_ATTR_RUNTIME U(1)
-
-#define RD_ATTR_PANIC_RESTART U(0)
-#define RD_ATTR_PANIC_ONESHOT U(1)
-
-#define RD_ATTR_XLAT_GRANULE_4KB U(0)
-#define RD_ATTR_XLAT_GRANULE_16KB U(1)
-#define RD_ATTR_XLAT_GRANULE_64KB U(2)
-
-/*******************************************************************************
- * Memory Region Section
- ******************************************************************************/
-
-#define RD_MEM_REGION_NAME_LEN U(32)
-
-#define RD_MEM_DEVICE U(0)
-#define RD_MEM_NORMAL_CODE U(1)
-#define RD_MEM_NORMAL_DATA U(2)
-#define RD_MEM_NORMAL_BSS U(3)
-#define RD_MEM_NORMAL_RODATA U(4)
-#define RD_MEM_NORMAL_SPM_SP_SHARED_MEM U(5)
-#define RD_MEM_NORMAL_CLIENT_SHARED_MEM U(6)
-#define RD_MEM_NORMAL_MISCELLANEOUS U(7)
-
-#define RD_MEM_MASK U(15)
-
-#define RD_MEM_IS_PIE (U(1) << 4)
-
-/*******************************************************************************
- * Notification Section
- ******************************************************************************/
-
-#define RD_NOTIF_TYPE_PLATFORM (U(0) << 31)
-#define RD_NOTIF_TYPE_INTERRUPT (U(1) << 31)
-
-#define RD_NOTIF_PLAT_ID_MASK U(0xFFFF)
-#define RD_NOTIF_PLAT_ID_SHIFT U(0)
-
-#define RD_NOTIF_PLATFORM(id) \
- (RD_NOTIF_TYPE_PLATFORM \
- | (((id) & RD_NOTIF_PLAT_ID_MASK) << RD_NOTIF_PLAT_ID_SHIFT))
-
-#define RD_NOTIF_IRQ_NUM_MASK U(0xFFFF)
-#define RD_NOTIF_IRQ_NUM_SHIFT U(0)
-#define RD_NOTIF_IRQ_PRIO_MASK U(0xFF)
-#define RD_NOTIF_IRQ_PRIO_SHIFT U(16)
-
-#define RD_NOTIF_IRQ_EDGE_FALLING U(0)
-#define RD_NOTIF_IRQ_EDGE_RISING U(2)
-#define RD_NOTIF_IRQ_LEVEL_LOW U(1)
-#define RD_NOTIF_IRQ_LEVEL_HIGH U(3)
-#define RD_NOTIF_IRQ_TRIGGER_SHIFT U(24)
-
-#define RD_NOTIF_IRQ(num, prio, trig) \
- (RD_NOTIF_TYPE_IRQ \
- | (((num) & RD_NOTIF_IRQ_NUM_MASK) << RD_NOTIF_IRQ_NUM_SHIFT) \
- | (((prio) & RD_NOTIF_IRQ_PRIO_MASK) << RD_NOTIF_IRQ_PRIO_SHIFT) \
- | (((trig) << RD_NOTIF_IRQ_TRIGGER_SHIFT)))
-
-/*******************************************************************************
- * Service Description Section
- ******************************************************************************/
-
-#define RD_SERV_ACCESS_SECURE (U(1) << 0)
-#define RD_SERV_ACCESS_EL3 (U(1) << 1)
-#define RD_SERV_ACCESS_NORMAL (U(1) << 2)
-
-#define RD_SERV_SUPPORT_BLOCKING (U(1) << 0)
-#define RD_SERV_SUPPORT_NON_BLOCKING (U(1) << 0)
-
-#endif /* SPM_RES_DESC_DEFS_H */
diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h
deleted file mode 100644
index 1d02bfa9cc..0000000000
--- a/include/services/spci_svc.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPCI_SVC_H
-#define SPCI_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* SPCI_VERSION helpers */
-
-#define SPCI_VERSION_MAJOR U(0)
-#define SPCI_VERSION_MAJOR_SHIFT 16
-#define SPCI_VERSION_MAJOR_MASK U(0x7FFF)
-#define SPCI_VERSION_MINOR U(1)
-#define SPCI_VERSION_MINOR_SHIFT 0
-#define SPCI_VERSION_MINOR_MASK U(0xFFFF)
-#define SPCI_VERSION_FORM(major, minor) ((((major) & SPCI_VERSION_MAJOR_MASK) \
- << SPCI_VERSION_MAJOR_SHIFT) | \
- ((minor) & SPCI_VERSION_MINOR_MASK))
-#define SPCI_VERSION_COMPILED SPCI_VERSION_FORM(SPCI_VERSION_MAJOR, \
- SPCI_VERSION_MINOR)
-
-/* Definitions to build the complete SMC ID */
-
-#define SPCI_FID_MISC_FLAG (U(0) << 27)
-#define SPCI_FID_MISC_SHIFT U(20)
-#define SPCI_FID_MISC_MASK U(0x7F)
-
-#define SPCI_FID_TUN_FLAG (U(1) << 27)
-#define SPCI_FID_TUN_SHIFT U(24)
-#define SPCI_FID_TUN_MASK U(0x7)
-
-#define OEN_SPCI_START U(0x30)
-#define OEN_SPCI_END U(0x3F)
-
-#define SPCI_SMC(spci_fid) ((OEN_SPCI_START << FUNCID_OEN_SHIFT) | \
- (U(1) << 31) | (spci_fid))
-#define SPCI_MISC_32(misc_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \
- SPCI_FID_MISC_FLAG | \
- SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_MISC_64(misc_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \
- SPCI_FID_MISC_FLAG | \
- SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_TUN_32(tun_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \
- SPCI_FID_TUN_FLAG | \
- SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-#define SPCI_TUN_64(tun_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \
- SPCI_FID_TUN_FLAG | \
- SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-
-/* SPCI miscellaneous functions */
-
-#define SPCI_FID_VERSION U(0x0)
-#define SPCI_FID_SERVICE_HANDLE_OPEN U(0x2)
-#define SPCI_FID_SERVICE_HANDLE_CLOSE U(0x3)
-#define SPCI_FID_SERVICE_MEM_REGISTER U(0x4)
-#define SPCI_FID_SERVICE_MEM_UNREGISTER U(0x5)
-#define SPCI_FID_SERVICE_MEM_PUBLISH U(0x6)
-#define SPCI_FID_SERVICE_REQUEST_BLOCKING U(0x7)
-#define SPCI_FID_SERVICE_REQUEST_START U(0x8)
-#define SPCI_FID_SERVICE_GET_RESPONSE U(0x9)
-#define SPCI_FID_SERVICE_RESET_CLIENT_STATE U(0xA)
-
-/* SPCI tunneling functions */
-
-#define SPCI_FID_SERVICE_TUN_REQUEST_START U(0x0)
-#define SPCI_FID_SERVICE_REQUEST_RESUME U(0x1)
-#define SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING U(0x2)
-
-/* Complete SMC IDs and associated values */
-
-#define SPCI_VERSION SPCI_MISC_32(SPCI_FID_VERSION)
-
-#define SPCI_SERVICE_HANDLE_OPEN SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_OPEN)
-#define SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT U(1)
-
-#define SPCI_SERVICE_HANDLE_CLOSE SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_CLOSE)
-
-#define SPCI_SERVICE_MEM_REGISTER_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_REGISTER)
-#define SPCI_SERVICE_MEM_REGISTER_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_REGISTER)
-
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_UNREGISTER)
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_UNREGISTER)
-
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_PUBLISH)
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_PUBLISH)
-
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-
-#define SPCI_SERVICE_REQUEST_START_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_START)
-#define SPCI_SERVICE_REQUEST_START_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_START)
-
-#define SPCI_SERVICE_GET_RESPONSE_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_GET_RESPONSE)
-#define SPCI_SERVICE_GET_RESPONSE_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_GET_RESPONSE)
-
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_START)
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_START)
-
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_REQUEST_RESUME)
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_REQUEST_RESUME)
-
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
-
-/* SPCI error codes. */
-
-#define SPCI_SUCCESS 0
-#define SPCI_NOT_SUPPORTED -1
-#define SPCI_INVALID_PARAMETER -2
-#define SPCI_NO_MEMORY -3
-#define SPCI_BUSY -4
-#define SPCI_QUEUED -5
-#define SPCI_DENIED -6
-#define SPCI_NOT_PRESENT -7
-
-#endif /* SPCI_SVC_H */
diff --git a/include/services/secure_partition.h b/include/services/spm_mm_partition.h
index 0510f80ece..ad5ceefbb5 100644
--- a/include/services/secure_partition.h
+++ b/include/services/spm_mm_partition.h
@@ -4,17 +4,15 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef SECURE_PARTITION_H
-#define SECURE_PARTITION_H
-
-#if SPM_MM
+#ifndef SPM_MM_PARTITION_H
+#define SPM_MM_PARTITION_H
#include <stdint.h>
#include <lib/utils_def.h>
/*
- * Flags used by the secure_partition_mp_info structure to describe the
+ * Flags used by the spm_mm_mp_info structure to describe the
* characteristics of a cpu. Only a single flag is defined at the moment to
* indicate the primary cpu.
*/
@@ -24,13 +22,13 @@
* This structure is used to provide information required to initialise a S-EL0
* partition.
*/
-typedef struct secure_partition_mp_info {
+typedef struct spm_mm_mp_info {
uint64_t mpidr;
uint32_t linear_id;
uint32_t flags;
-} secure_partition_mp_info_t;
+} spm_mm_mp_info_t;
-typedef struct secure_partition_boot_info {
+typedef struct spm_mm_boot_info {
param_header_t h;
uint64_t sp_mem_base;
uint64_t sp_mem_limit;
@@ -46,9 +44,7 @@ typedef struct secure_partition_boot_info {
uint64_t sp_shared_buf_size;
uint32_t num_sp_mem_regions;
uint32_t num_cpus;
- secure_partition_mp_info_t *mp_info;
-} secure_partition_boot_info_t;
-
-#endif /* SPM_MM */
+ spm_mm_mp_info_t *mp_info;
+} spm_mm_boot_info_t;
-#endif /* SECURE_PARTITION_H */
+#endif /* SPM_MM_PARTITION_H */
diff --git a/include/services/spm_mm_svc.h b/include/services/spm_mm_svc.h
new file mode 100644
index 0000000000..3148beb80f
--- /dev/null
+++ b/include/services/spm_mm_svc.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SPM_MM_SVC_H
+#define SPM_MM_SVC_H
+
+#include <lib/utils_def.h>
+
+/*
+ * The MM_VERSION_XXX definitions are used when responding to the
+ * MM_VERSION_AARCH32 service request. The version returned is different between
+ * this request and the SPM_MM_VERSION_AARCH32 request - both have been retained
+ * for compatibility.
+ */
+#define MM_VERSION_MAJOR U(1)
+#define MM_VERSION_MAJOR_SHIFT 16
+#define MM_VERSION_MAJOR_MASK U(0x7FFF)
+#define MM_VERSION_MINOR U(0)
+#define MM_VERSION_MINOR_SHIFT 0
+#define MM_VERSION_MINOR_MASK U(0xFFFF)
+#define MM_VERSION_FORM(major, minor) ((major << MM_VERSION_MAJOR_SHIFT) | \
+ (minor))
+#define MM_VERSION_COMPILED MM_VERSION_FORM(MM_VERSION_MAJOR, \
+ MM_VERSION_MINOR)
+
+#define SPM_MM_VERSION_MAJOR U(0)
+#define SPM_MM_VERSION_MAJOR_SHIFT 16
+#define SPM_MM_VERSION_MAJOR_MASK U(0x7FFF)
+#define SPM_MM_VERSION_MINOR U(1)
+#define SPM_MM_VERSION_MINOR_SHIFT 0
+#define SPM_MM_VERSION_MINOR_MASK U(0xFFFF)
+#define SPM_MM_VERSION_FORM(major, minor) ((major << \
+ SPM_MM_VERSION_MAJOR_SHIFT) | \
+ (minor))
+#define SPM_MM_VERSION_COMPILED SPM_MM_VERSION_FORM(SPM_MM_VERSION_MAJOR, \
+ SPM_MM_VERSION_MINOR)
+
+/* These macros are used to identify SPM-MM calls using the SMC function ID */
+#define SPM_MM_FID_MASK U(0xffff)
+#define SPM_MM_FID_MIN_VALUE U(0x40)
+#define SPM_MM_FID_MAX_VALUE U(0x7f)
+#define is_spm_mm_fid(_fid) \
+ ((((_fid) & SPM_MM_FID_MASK) >= SPM_MM_FID_MIN_VALUE) && \
+ (((_fid) & SPM_MM_FID_MASK) <= SPM_MM_FID_MAX_VALUE))
+
+/*
+ * SMC IDs defined in [1] for accessing MM services from the Non-secure world.
+ * These FIDs occupy the range 0x40 - 0x5f.
+ * [1] DEN0060A_ARM_MM_Interface_Specification.pdf
+ */
+#define MM_VERSION_AARCH32 U(0x84000040)
+#define MM_COMMUNICATE_AARCH64 U(0xC4000041)
+#define MM_COMMUNICATE_AARCH32 U(0x84000041)
+
+/*
+ * SMC IDs defined for accessing services implemented by the Secure Partition
+ * Manager from the Secure Partition(s). These services enable a partition to
+ * handle delegated events and request privileged operations from the manager.
+ * They occupy the range 0x60-0x7f.
+ */
+#define SPM_MM_VERSION_AARCH32 U(0x84000060)
+#define MM_SP_EVENT_COMPLETE_AARCH64 U(0xC4000061)
+#define MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 U(0xC4000064)
+#define MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 U(0xC4000065)
+
+/*
+ * Macros used by MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64.
+ */
+
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS U(0)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW U(1)
+/* Value U(2) is reserved. */
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO U(3)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK U(3)
+#define MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT 0
+
+#define MM_SP_MEMORY_ATTRIBUTES_EXEC (U(0) << 2)
+#define MM_SP_MEMORY_ATTRIBUTES_NON_EXEC (U(1) << 2)
+
+
+/* SPM error codes. */
+#define SPM_MM_SUCCESS 0
+#define SPM_MM_NOT_SUPPORTED -1
+#define SPM_MM_INVALID_PARAMETER -2
+#define SPM_MM_DENIED -3
+#define SPM_MM_NO_MEMORY -5
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+int32_t spm_mm_setup(void);
+
+uint64_t spm_mm_smc_handler(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3,
+ uint64_t x4,
+ void *cookie,
+ void *handle,
+ uint64_t flags);
+
+/* Helper to enter a secure partition */
+uint64_t spm_mm_sp_call(uint32_t smc_fid,
+ uint64_t x1,
+ uint64_t x2,
+ uint64_t x3);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SPM_MM_SVC_H */
diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h
deleted file mode 100644
index a3723a0f50..0000000000
--- a/include/services/spm_svc.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_SVC_H
-#define SPM_SVC_H
-
-#if SPM_MM
-
-#include <lib/utils_def.h>
-
-#define SPM_VERSION_MAJOR U(0)
-#define SPM_VERSION_MAJOR_SHIFT 16
-#define SPM_VERSION_MAJOR_MASK U(0x7FFF)
-#define SPM_VERSION_MINOR U(1)
-#define SPM_VERSION_MINOR_SHIFT 0
-#define SPM_VERSION_MINOR_MASK U(0xFFFF)
-#define SPM_VERSION_FORM(major, minor) ((major << SPM_VERSION_MAJOR_SHIFT) | (minor))
-#define SPM_VERSION_COMPILED SPM_VERSION_FORM(SPM_VERSION_MAJOR, SPM_VERSION_MINOR)
-
-/* The macros below are used to identify SPM calls from the SMC function ID */
-#define SPM_FID_MASK U(0xffff)
-#define SPM_FID_MIN_VALUE U(0x40)
-#define SPM_FID_MAX_VALUE U(0x7f)
-#define is_spm_fid(_fid) \
- ((((_fid) & SPM_FID_MASK) >= SPM_FID_MIN_VALUE) && \
- (((_fid) & SPM_FID_MASK) <= SPM_FID_MAX_VALUE))
-
-/*
- * SMC IDs defined for accessing services implemented by the Secure Partition
- * Manager from the Secure Partition(s). These services enable a partition to
- * handle delegated events and request privileged operations from the manager.
- * They occupy the range 0x60-0x7f.
- */
-#define SPM_VERSION_AARCH32 U(0x84000060)
-#define SP_EVENT_COMPLETE_AARCH64 U(0xC4000061)
-#define SP_MEMORY_ATTRIBUTES_GET_AARCH64 U(0xC4000064)
-#define SP_MEMORY_ATTRIBUTES_SET_AARCH64 U(0xC4000065)
-
-/*
- * Macros used by SP_MEMORY_ATTRIBUTES_SET_AARCH64.
- */
-
-#define SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS U(0)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_RW U(1)
-/* Value U(2) is reserved. */
-#define SP_MEMORY_ATTRIBUTES_ACCESS_RO U(3)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_MASK U(3)
-#define SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT 0
-
-#define SP_MEMORY_ATTRIBUTES_EXEC (U(0) << 2)
-#define SP_MEMORY_ATTRIBUTES_NON_EXEC (U(1) << 2)
-
-
-/* SPM error codes. */
-#define SPM_SUCCESS 0
-#define SPM_NOT_SUPPORTED -1
-#define SPM_INVALID_PARAMETER -2
-#define SPM_DENIED -3
-#define SPM_NO_MEMORY -5
-
-#endif /* SPM_MM */
-
-#ifndef __ASSEMBLER__
-
-#include <stdint.h>
-
-int32_t spm_setup(void);
-
-#if SPM_MM
-
-uint64_t spm_smc_handler(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- void *cookie,
- void *handle,
- uint64_t flags);
-
-/* Helper to enter a Secure Partition */
-uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3);
-
-#endif /* SPM_MM */
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* SPM_SVC_H */
diff --git a/include/services/sprt_svc.h b/include/services/sprt_svc.h
deleted file mode 100644
index 2421ea251a..0000000000
--- a/include/services/sprt_svc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_SVC_H
-#define SPRT_SVC_H
-
-#include <lib/smccc.h>
-#include <lib/utils_def.h>
-
-/* SPRT_VERSION helpers */
-
-#define SPRT_VERSION_MAJOR U(0)
-#define SPRT_VERSION_MAJOR_SHIFT 16
-#define SPRT_VERSION_MAJOR_MASK U(0x7FFF)
-#define SPRT_VERSION_MINOR U(1)
-#define SPRT_VERSION_MINOR_SHIFT 0
-#define SPRT_VERSION_MINOR_MASK U(0xFFFF)
-#define SPRT_VERSION_FORM(major, minor) ((((major) & SPRT_VERSION_MAJOR_MASK) \
- << SPRT_VERSION_MAJOR_SHIFT) | \
- ((minor) & SPRT_VERSION_MINOR_MASK))
-#define SPRT_VERSION_COMPILED SPRT_VERSION_FORM(SPRT_VERSION_MAJOR, \
- SPRT_VERSION_MINOR)
-
-/* SPRT function IDs */
-
-#define SPRT_FID_VERSION U(0x0)
-#define SPRT_FID_PUT_RESPONSE U(0x1)
-#define SPRT_FID_YIELD U(0x5)
-#define SPRT_FID_PANIC U(0x7)
-#define SPRT_FID_MEMORY_PERM_ATTR_GET U(0xB)
-#define SPRT_FID_MEMORY_PERM_ATTR_SET U(0xC)
-
-#define SPRT_FID_MASK U(0xFF)
-
-/* Definitions to build the complete SMC ID */
-
-#define OEN_SPRT_START U(0x20)
-#define OEN_SPRT_END U(0x2F)
-
-#define SPRT_SMC_64(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
- (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
- (SMC_64 << FUNCID_CC_SHIFT))
-#define SPRT_SMC_32(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \
- (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \
- (SMC_32 << FUNCID_CC_SHIFT))
-
-/* Complete SMC IDs */
-
-#define SPRT_VERSION SPRT_SMC_32(SPRT_FID_VERSION)
-#define SPRT_PUT_RESPONSE_AARCH64 SPRT_SMC_64(SPRT_FID_PUT_RESPONSE)
-#define SPRT_YIELD_AARCH64 SPRT_SMC_64(SPRT_FID_YIELD)
-#define SPRT_PANIC_AARCH64 SPRT_SMC_64(SPRT_FID_PANIC)
-#define SPRT_MEMORY_PERM_ATTR_GET_AARCH64 SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_GET)
-#define SPRT_MEMORY_PERM_ATTR_SET_AARCH64 SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_SET)
-
-/* Defines used by SPRT_MEMORY_PERM_ATTR_{GET,SET}_AARCH64 */
-
-#define SPRT_MEMORY_PERM_ATTR_RO U(0)
-#define SPRT_MEMORY_PERM_ATTR_RW U(1)
-#define SPRT_MEMORY_PERM_ATTR_RO_EXEC U(2)
-/* U(3) is reserved */
-#define SPRT_MEMORY_PERM_ATTR_MASK U(3)
-#define SPRT_MEMORY_PERM_ATTR_SHIFT 3
-
-/* SPRT error codes. */
-
-#define SPRT_SUCCESS 0
-#define SPRT_NOT_SUPPORTED -1
-#define SPRT_INVALID_PARAMETER -2
-
-#endif /* SPRT_SVC_H */
diff --git a/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S
new file mode 100644
index 0000000000..038ae5d723
--- /dev/null
+++ b/lib/compiler-rt/builtins/arm/aeabi_ldivmod.S
@@ -0,0 +1,46 @@
+//===-- aeabi_ldivmod.S - EABI ldivmod implementation ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../assembly.h"
+
+// struct { int64_t quot, int64_t rem}
+// __aeabi_ldivmod(int64_t numerator, int64_t denominator) {
+// int64_t rem, quot;
+// quot = __divmoddi4(numerator, denominator, &rem);
+// return {quot, rem};
+// }
+
+#if defined(__MINGW32__)
+#define __aeabi_ldivmod __rt_sdiv64
+#endif
+
+ .syntax unified
+ .p2align 2
+DEFINE_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+ push {r6, lr}
+ sub sp, sp, #16
+ add r6, sp, #8
+ str r6, [sp]
+#if defined(__MINGW32__)
+ movs r6, r0
+ movs r0, r2
+ movs r2, r6
+ movs r6, r1
+ movs r1, r3
+ movs r3, r6
+#endif
+ bl SYMBOL_NAME(__divmoddi4)
+ ldr r2, [sp, #8]
+ ldr r3, [sp, #12]
+ add sp, sp, #16
+ pop {r6, pc}
+END_COMPILERRT_FUNCTION(__aeabi_ldivmod)
+
+NO_EXEC_STACK_DIRECTIVE
+
diff --git a/lib/compiler-rt/builtins/divdi3.c b/lib/compiler-rt/builtins/divdi3.c
new file mode 100644
index 0000000000..b8eebcb204
--- /dev/null
+++ b/lib/compiler-rt/builtins/divdi3.c
@@ -0,0 +1,29 @@
+/* ===-- divdi3.c - Implement __divdi3 -------------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divdi3 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a / b */
+
+COMPILER_RT_ABI di_int
+__divdi3(di_int a, di_int b)
+{
+ const int bits_in_dword_m1 = (int)(sizeof(di_int) * CHAR_BIT) - 1;
+ di_int s_a = a >> bits_in_dword_m1; /* s_a = a < 0 ? -1 : 0 */
+ di_int s_b = b >> bits_in_dword_m1; /* s_b = b < 0 ? -1 : 0 */
+ a = (a ^ s_a) - s_a; /* negate if s_a == -1 */
+ b = (b ^ s_b) - s_b; /* negate if s_b == -1 */
+ s_a ^= s_b; /*sign of quotient */
+ return (__udivmoddi4(a, b, (du_int*)0) ^ s_a) - s_a; /* negate if s_a == -1 */
+}
diff --git a/lib/compiler-rt/builtins/divmoddi4.c b/lib/compiler-rt/builtins/divmoddi4.c
new file mode 100644
index 0000000000..0d4df67a63
--- /dev/null
+++ b/lib/compiler-rt/builtins/divmoddi4.c
@@ -0,0 +1,25 @@
+/*===-- divmoddi4.c - Implement __divmoddi4 --------------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __divmoddi4 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: a / b, *rem = a % b */
+
+COMPILER_RT_ABI di_int
+__divmoddi4(di_int a, di_int b, di_int* rem)
+{
+ di_int d = __divdi3(a,b);
+ *rem = a - (d*b);
+ return d;
+}
diff --git a/lib/compiler-rt/builtins/popcountdi2.c b/lib/compiler-rt/builtins/popcountdi2.c
new file mode 100644
index 0000000000..5e8a62f075
--- /dev/null
+++ b/lib/compiler-rt/builtins/popcountdi2.c
@@ -0,0 +1,36 @@
+/* ===-- popcountdi2.c - Implement __popcountdi2 ----------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountdi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+COMPILER_RT_ABI si_int
+__popcountdi2(di_int a)
+{
+ du_int x2 = (du_int)a;
+ x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
+ /* Every 2 bits holds the sum of every pair of bits (32) */
+ x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) (16) */
+ x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) (8) */
+ su_int x = (su_int)(x2 + (x2 >> 32));
+ /* The lower 32 bits hold four 16 bit sums (5 significant bits). */
+ /* Upper 32 bits are garbage */
+ x = x + (x >> 16);
+ /* The lower 16 bits hold two 32 bit sums (6 significant bits). */
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0x0000007F; /* (7 significant bits) */
+}
diff --git a/lib/compiler-rt/builtins/popcountsi2.c b/lib/compiler-rt/builtins/popcountsi2.c
new file mode 100644
index 0000000000..44544ff498
--- /dev/null
+++ b/lib/compiler-rt/builtins/popcountsi2.c
@@ -0,0 +1,33 @@
+/* ===-- popcountsi2.c - Implement __popcountsi2 ---------------------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is dual licensed under the MIT and the University of Illinois Open
+ * Source Licenses. See LICENSE.TXT for details.
+ *
+ * ===----------------------------------------------------------------------===
+ *
+ * This file implements __popcountsi2 for the compiler_rt library.
+ *
+ * ===----------------------------------------------------------------------===
+ */
+
+#include "int_lib.h"
+
+/* Returns: count of 1 bits */
+
+COMPILER_RT_ABI si_int
+__popcountsi2(si_int a)
+{
+ su_int x = (su_int)a;
+ x = x - ((x >> 1) & 0x55555555);
+ /* Every 2 bits holds the sum of every pair of bits */
+ x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
+ /* Every 4 bits holds the sum of every 4-set of bits (3 significant bits) */
+ x = (x + (x >> 4)) & 0x0F0F0F0F;
+ /* Every 8 bits holds the sum of every 8-set of bits (4 significant bits) */
+ x = (x + (x >> 16));
+ /* The lower 16 bits hold two 8 bit sums (5 significant bits).*/
+ /* Upper 16 bits are garbage */
+ return (x + (x >> 8)) & 0x0000003F; /* (6 significant bits) */
+}
diff --git a/lib/compiler-rt/compiler-rt.mk b/lib/compiler-rt/compiler-rt.mk
index 49e497eb83..40c669f989 100644
--- a/lib/compiler-rt/compiler-rt.mk
+++ b/lib/compiler-rt/compiler-rt.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
@@ -28,9 +28,15 @@
# POSSIBILITY OF SUCH DAMAGE.
#
+COMPILER_RT_SRCS := lib/compiler-rt/builtins/popcountdi2.c \
+ lib/compiler-rt/builtins/popcountsi2.c
+
ifeq (${ARCH},aarch32)
-COMPILER_RT_SRCS := lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \
- lib/compiler-rt/builtins/udivmoddi4.c \
+COMPILER_RT_SRCS += lib/compiler-rt/builtins/arm/aeabi_ldivmod.S \
+ lib/compiler-rt/builtins/arm/aeabi_uldivmod.S \
lib/compiler-rt/builtins/ctzdi2.c \
- lib/compiler-rt/builtins/lshrdi3.c
+ lib/compiler-rt/builtins/divdi3.c \
+ lib/compiler-rt/builtins/divmoddi4.c \
+ lib/compiler-rt/builtins/lshrdi3.c \
+ lib/compiler-rt/builtins/udivmoddi4.c
endif
diff --git a/lib/cpus/aarch64/cortex_hercules.S b/lib/cpus/aarch64/cortex_hercules.S
index 4e048145f4..a239196266 100644
--- a/lib/cpus/aarch64/cortex_hercules.S
+++ b/lib/cpus/aarch64/cortex_hercules.S
@@ -16,12 +16,49 @@
#error "cortex_hercules must be compiled with HW_ASSISTED_COHERENCY enabled"
#endif
+
+/* --------------------------------------------------
+ * Errata Workaround for Hercules Erratum 1688305.
+ * This applies to revision r0p0 and r1p0 of Hercules.
+ * Inputs:
+ * x0: variant[4:7] and revision[0:3] of current cpu.
+ * Shall clobber: x0-x17
+ * --------------------------------------------------
+ */
+func errata_hercules_1688305_wa
+ /* Compare x0 against revision r1p0 */
+ mov x17, x30
+ bl check_errata_1688305
+ cbz x0, 1f
+ mrs x1, CORTEX_HERCULES_ACTLR2_EL1
+ orr x1, x1, CORTEX_HERCULES_ACTLR2_EL1_BIT_1
+ msr CORTEX_HERCULES_ACTLR2_EL1, x1
+ isb
+1:
+ ret x17
+endfunc errata_hercules_1688305_wa
+
+func check_errata_1688305
+ /* Applies to r0p0 and r1p0 */
+ mov x1, #0x10
+ b cpu_rev_var_ls
+endfunc check_errata_1688305
+
/* -------------------------------------------------
* The CPU Ops reset function for Cortex-Hercules
* -------------------------------------------------
*/
-#if ENABLE_AMU
func cortex_hercules_reset_func
+ mov x19, x30
+ bl cpu_get_rev_var
+ mov x18, x0
+
+#if ERRATA_HERCULES_1688305
+ mov x0, x18
+ bl errata_hercules_1688305_wa
+#endif
+
+#if ENABLE_AMU
/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
mrs x0, actlr_el3
bic x0, x0, #CORTEX_HERCULES_ACTLR_TAM_BIT
@@ -39,11 +76,11 @@ func cortex_hercules_reset_func
/* Enable group1 counters */
mov x0, #CORTEX_HERCULES_AMU_GROUP1_MASK
msr CPUAMCNTENSET1_EL0, x0
- isb
+#endif
- ret
+ isb
+ ret x19
endfunc cortex_hercules_reset_func
-#endif
/* ---------------------------------------------
* HW will do the cache maintenance while powering down
@@ -66,6 +103,18 @@ endfunc cortex_hercules_core_pwr_dwn
*/
#if REPORT_ERRATA
func cortex_hercules_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 ERRATA_HERCULES_1688305, cortex_hercules, 1688305
+
+ ldp x8, x30, [sp], #16
ret
endfunc cortex_hercules_errata_report
#endif
@@ -89,12 +138,6 @@ func cortex_hercules_cpu_reg_dump
ret
endfunc cortex_hercules_cpu_reg_dump
-#if ENABLE_AMU
-#define HERCULES_RESET_FUNC cortex_hercules_reset_func
-#else
-#define HERCULES_RESET_FUNC CPU_NO_RESET_FUNC
-#endif
-
declare_cpu_ops cortex_hercules, CORTEX_HERCULES_MIDR, \
- HERCULES_RESET_FUNC, \
+ cortex_hercules_reset_func, \
cortex_hercules_core_pwr_dwn
diff --git a/lib/cpus/cpu-ops.mk b/lib/cpus/cpu-ops.mk
index 078888ebf6..c9b9b387ee 100644
--- a/lib/cpus/cpu-ops.mk
+++ b/lib/cpus/cpu-ops.mk
@@ -234,6 +234,10 @@ ERRATA_A76_1275112 ?=0
# only to revision <= r3p0 of the Cortex A76 cpu.
ERRATA_A76_1286807 ?=0
+# Flag to apply erratum 1688305 workaround during reset. This erratum applies
+# to revisions r0p0 - r1p0 of the Hercules cpu.
+ERRATA_HERCULES_1688305 ?=0
+
# Flag to apply T32 CLREX workaround during reset. This erratum applies
# only to r0p0 and r1p0 of the Neoverse N1 cpu.
ERRATA_N1_1043202 ?=1
@@ -467,6 +471,10 @@ $(eval $(call add_define,ERRATA_A76_1275112))
$(eval $(call assert_boolean,ERRATA_A76_1286807))
$(eval $(call add_define,ERRATA_A76_1286807))
+# Process ERRATA_HERCULES_1688305 flag
+$(eval $(call assert_boolean,ERRATA_HERCULES_1688305))
+$(eval $(call add_define,ERRATA_HERCULES_1688305))
+
# Process ERRATA_N1_1043202 flag
$(eval $(call assert_boolean,ERRATA_N1_1043202))
$(eval $(call add_define,ERRATA_N1_1043202))
diff --git a/lib/debugfs/blobs.h b/lib/debugfs/blobs.h
new file mode 100644
index 0000000000..54ca9f75da
--- /dev/null
+++ b/lib/debugfs/blobs.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "dev.h"
+
+static const dirtab_t blobtab[] = {
+ {"ctl", DEV_ROOT_QBLOBCTL, 0, O_READ},
+ {"fip.bin", DEV_ROOT_QBLOBCTL + 1, 0x100000, O_READ, (void *)0x8000000}
+};
diff --git a/lib/debugfs/debugfs.mk b/lib/debugfs/debugfs.mk
new file mode 100644
index 0000000000..138fc72a1b
--- /dev/null
+++ b/lib/debugfs/debugfs.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+DEBUGFS_SRCS := $(addprefix lib/debugfs/, \
+ dev.c \
+ devc.c \
+ devroot.c \
+ devfip.c)
+
+DEBUGFS_SRCS += lib/debugfs/debugfs_smc.c
diff --git a/lib/debugfs/debugfs_smc.c b/lib/debugfs/debugfs_smc.c
new file mode 100644
index 0000000000..400c166d7c
--- /dev/null
+++ b/lib/debugfs/debugfs_smc.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include <lib/debugfs.h>
+#include <lib/smccc.h>
+#include <lib/spinlock.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <smccc_helpers.h>
+
+#define MAX_PATH_LEN 256
+
+#define MOUNT 0
+#define CREATE 1
+#define OPEN 2
+#define CLOSE 3
+#define READ 4
+#define WRITE 5
+#define SEEK 6
+#define BIND 7
+#define STAT 8
+#define INIT 10
+#define VERSION 11
+
+/* This is the virtual address to which we map the NS shared buffer */
+#define DEBUGFS_SHARED_BUF_VIRT ((void *)0x81000000U)
+
+static union debugfs_parms {
+ struct {
+ char fname[MAX_PATH_LEN];
+ } open;
+
+ struct {
+ char srv[MAX_PATH_LEN];
+ char where[MAX_PATH_LEN];
+ char spec[MAX_PATH_LEN];
+ } mount;
+
+ struct {
+ char path[MAX_PATH_LEN];
+ dir_t dir;
+ } stat;
+
+ struct {
+ char oldpath[MAX_PATH_LEN];
+ char newpath[MAX_PATH_LEN];
+ } bind;
+} parms;
+
+/* debugfs_access_lock protects shared buffer and internal */
+/* FS functions from concurrent acccesses. */
+static spinlock_t debugfs_access_lock;
+
+static bool debugfs_initialized;
+
+uintptr_t debugfs_smc_handler(unsigned int smc_fid,
+ u_register_t cmd,
+ u_register_t arg2,
+ u_register_t arg3,
+ u_register_t arg4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ int64_t smc_ret = DEBUGFS_E_INVALID_PARAMS, smc_resp = 0;
+ int ret;
+
+ /* Allow calls from non-secure only */
+ if (is_caller_secure(flags)) {
+ SMC_RET1(handle, DEBUGFS_E_DENIED);
+ }
+
+ /* Expect a SiP service fast call */
+ if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) ||
+ (GET_SMC_OEN(smc_fid) != OEN_SIP_START)) {
+ SMC_RET1(handle, SMC_UNK);
+ }
+
+ /* Truncate parameters if 32b SMC convention call */
+ if (GET_SMC_CC(smc_fid) == SMC_32) {
+ arg2 &= 0xffffffff;
+ arg3 &= 0xffffffff;
+ arg4 &= 0xffffffff;
+ }
+
+ spin_lock(&debugfs_access_lock);
+
+ if (debugfs_initialized == true) {
+ /* Copy NS shared buffer to internal secure location */
+ memcpy(&parms, (void *)DEBUGFS_SHARED_BUF_VIRT,
+ sizeof(union debugfs_parms));
+ }
+
+ switch (cmd) {
+ case INIT:
+ if (debugfs_initialized == false) {
+ /* TODO: check PA validity e.g. whether */
+ /* it is an NS region. */
+ ret = mmap_add_dynamic_region(arg2,
+ (uintptr_t)DEBUGFS_SHARED_BUF_VIRT,
+ PAGE_SIZE_4KB,
+ MT_MEMORY | MT_RW | MT_NS);
+ if (ret == 0) {
+ debugfs_initialized = true;
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ }
+ break;
+
+ case VERSION:
+ smc_ret = SMC_OK;
+ smc_resp = DEBUGFS_VERSION;
+ break;
+
+ case MOUNT:
+ ret = mount(parms.mount.srv,
+ parms.mount.where,
+ parms.mount.spec);
+ if (ret == 0) {
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ break;
+
+ case OPEN:
+ ret = open(parms.open.fname, arg2);
+ if (ret >= 0) {
+ smc_ret = SMC_OK;
+ smc_resp = ret;
+ }
+ break;
+
+ case CLOSE:
+ ret = close(arg2);
+ if (ret == 0) {
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ break;
+
+ case READ:
+ ret = read(arg2, DEBUGFS_SHARED_BUF_VIRT, arg3);
+ if (ret >= 0) {
+ smc_ret = SMC_OK;
+ smc_resp = ret;
+ }
+ break;
+
+ case SEEK:
+ ret = seek(arg2, arg3, arg4);
+ if (ret == 0) {
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ break;
+
+ case BIND:
+ ret = bind(parms.bind.oldpath, parms.bind.newpath);
+ if (ret == 0) {
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ break;
+
+ case STAT:
+ ret = stat(parms.stat.path, &parms.stat.dir);
+ if (ret == 0) {
+ memcpy((void *)DEBUGFS_SHARED_BUF_VIRT, &parms,
+ sizeof(union debugfs_parms));
+ smc_ret = SMC_OK;
+ smc_resp = 0;
+ }
+ break;
+
+ /* Not implemented */
+ case CREATE:
+ /* Intentional fall-through */
+
+ /* Not implemented */
+ case WRITE:
+ /* Intentional fall-through */
+
+ default:
+ smc_ret = SMC_UNK;
+ smc_resp = 0;
+ }
+
+ spin_unlock(&debugfs_access_lock);
+
+ SMC_RET2(handle, smc_ret, smc_resp);
+
+ /* Not reached */
+ return smc_ret;
+}
+
+int debugfs_smc_setup(void)
+{
+ debugfs_initialized = false;
+ debugfs_access_lock.lock = 0;
+
+ return 0;
+}
diff --git a/lib/debugfs/dev.c b/lib/debugfs/dev.c
new file mode 100644
index 0000000000..0361437b85
--- /dev/null
+++ b/lib/debugfs/dev.c
@@ -0,0 +1,849 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cdefs.h>
+#include <common/debug.h>
+#include <lib/debugfs.h>
+#include <string.h>
+
+#include "dev.h"
+
+#define NR_MOUNT_POINTS 4
+
+struct mount_point {
+ chan_t *new;
+ chan_t *old;
+};
+
+/* This array contains all the available channels of the filesystem.
+ * A file descriptor is the index of a specific channel in this array.
+ */
+static chan_t fdset[NR_CHANS];
+
+/* This array contains all the available mount points of the filesystem. */
+static struct mount_point mount_points[NR_MOUNT_POINTS];
+
+/* This variable stores the channel associated to the root directory. */
+static chan_t slash_channel;
+
+/* This function creates a channel from a device index and registers
+ * it to fdset.
+ */
+static chan_t *create_new_channel(unsigned char index)
+{
+ chan_t *channel = NULL;
+ int i;
+
+ for (i = 0; i < NR_CHANS; i++) {
+ if (fdset[i].index == NODEV) {
+ channel = &fdset[i];
+ channel->index = index;
+ break;
+ }
+ }
+
+ return channel;
+}
+
+/*******************************************************************************
+ * This function returns a pointer to an existing channel in fdset from a file
+ * descriptor.
+ ******************************************************************************/
+static chan_t *fd_to_channel(int fd)
+{
+ if ((fd < 0) || (fd >= NR_CHANS) || (fdset[fd].index == NODEV)) {
+ return NULL;
+ }
+
+ return &fdset[fd];
+}
+
+/*******************************************************************************
+ * This function returns a file descriptor from a channel.
+ * The caller must be sure that the channel is registered in fdset.
+ ******************************************************************************/
+static int channel_to_fd(chan_t *channel)
+{
+ return (channel == NULL) ? -1 : (channel - fdset);
+}
+
+/*******************************************************************************
+ * This function checks the validity of a mode.
+ ******************************************************************************/
+static bool is_valid_mode(int mode)
+{
+ if ((mode & O_READ) && (mode & (O_WRITE | O_RDWR))) {
+ return false;
+ }
+ if ((mode & O_WRITE) && (mode & (O_READ | O_RDWR))) {
+ return false;
+ }
+ if ((mode & O_RDWR) && (mode & (O_READ | O_WRITE))) {
+ return false;
+ }
+
+ return true;
+}
+
+/*******************************************************************************
+ * This function extracts the next part of the given path contained and puts it
+ * in token. It returns a pointer to the remainder of the path.
+ ******************************************************************************/
+static const char *next(const char *path, char *token)
+{
+ int index;
+ const char *cursor;
+
+ while (*path == '/') {
+ ++path;
+ }
+
+ index = 0;
+ cursor = path;
+ if (*path != '\0') {
+ while (*cursor != '/' && *cursor != '\0') {
+ if (index == NAMELEN) {
+ return NULL;
+ }
+ token[index++] = *cursor++;
+ }
+ }
+ token[index] = '\0';
+
+ return cursor;
+}
+
+/*******************************************************************************
+ * This function returns the driver index in devtab of the driver
+ * identified by id.
+ ******************************************************************************/
+static int get_device_index(int id)
+{
+ int index;
+ dev_t * const *dp;
+
+ for (index = 0, dp = devtab; *dp && (*dp)->id != id; ++dp) {
+ index++;
+ }
+
+ if (*dp == NULL) {
+ return -1;
+ }
+
+ return index;
+}
+
+/*******************************************************************************
+ * This function clears a given channel fields
+ ******************************************************************************/
+static void channel_clear(chan_t *channel)
+{
+ channel->offset = 0;
+ channel->qid = 0;
+ channel->index = NODEV;
+ channel->dev = 0;
+ channel->mode = 0;
+}
+
+/*******************************************************************************
+ * This function closes the channel pointed to by c.
+ ******************************************************************************/
+void channel_close(chan_t *channel)
+{
+ if (channel != NULL) {
+ channel_clear(channel);
+ }
+}
+
+/*******************************************************************************
+ * This function copies data from src to dst after applying the offset of the
+ * channel c. nbytes bytes are expected to be copied unless the data goes over
+ * dst + len.
+ * It returns the actual number of bytes that were copied.
+ ******************************************************************************/
+int buf_to_channel(chan_t *channel, void *dst, void *src, int nbytes, long len)
+{
+ const char *addr = src;
+
+ if ((channel == NULL) || (dst == NULL) || (src == NULL)) {
+ return 0;
+ }
+
+ if (channel->offset >= len) {
+ return 0;
+ }
+
+ if ((channel->offset + nbytes) > len) {
+ nbytes = len - channel->offset;
+ }
+
+ memcpy(dst, addr + channel->offset, nbytes);
+
+ channel->offset += nbytes;
+
+ return nbytes;
+}
+
+/*******************************************************************************
+ * This function checks whether a channel (identified by its device index and
+ * qid) is registered as a mount point.
+ * Returns a pointer to the channel it is mounted to when found, NULL otherwise.
+ ******************************************************************************/
+static chan_t *mount_point_to_channel(int index, qid_t qid)
+{
+ chan_t *channel;
+ struct mount_point *mp;
+
+ for (mp = mount_points; mp < &mount_points[NR_MOUNT_POINTS]; mp++) {
+ channel = mp->new;
+ if (channel == NULL) {
+ continue;
+ }
+
+ if ((channel->index == index) && (channel->qid == qid)) {
+ return mp->old;
+ }
+ }
+
+ return NULL;
+}
+
+/*******************************************************************************
+ * This function calls the attach function of the driver identified by id.
+ ******************************************************************************/
+chan_t *attach(int id, int dev)
+{
+ /* Get the devtab index for the driver identified by id */
+ int index = get_device_index(id);
+
+ if (index < 0) {
+ return NULL;
+ }
+
+ return devtab[index]->attach(id, dev);
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver attach function.
+ * It creates a new channel and returns a pointer to it.
+ ******************************************************************************/
+chan_t *devattach(int id, int dev)
+{
+ chan_t *channel;
+ int index;
+
+ index = get_device_index(id);
+ if (index < 0) {
+ return NULL;
+ }
+
+ channel = create_new_channel(index);
+ if (channel == NULL) {
+ return NULL;
+ }
+
+ channel->dev = dev;
+ channel->qid = CHDIR;
+
+ return channel;
+}
+
+/*******************************************************************************
+ * This function returns a channel given a path.
+ * It goes through the filesystem, from the root namespace ('/') or from a
+ * device namespace ('#'), switching channel on mount points.
+ ******************************************************************************/
+chan_t *path_to_channel(const char *path, int mode)
+{
+ int i, n;
+ const char *path_next;
+ chan_t *mnt, *channel;
+ char elem[NAMELEN];
+
+ if (path == NULL) {
+ return NULL;
+ }
+
+ switch (path[0]) {
+ case '/':
+ channel = clone(&slash_channel, NULL);
+ path_next = path;
+ break;
+ case '#':
+ path_next = next(path + 1, elem);
+ if (path_next == NULL) {
+ goto noent;
+ }
+
+ n = 0;
+ for (i = 1; (elem[i] >= '0') && (elem[i] <= '9'); i++) {
+ n += elem[i] - '0';
+ }
+
+ if (elem[i] != '\0') {
+ goto noent;
+ }
+
+ channel = attach(elem[0], n);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (channel == NULL) {
+ return NULL;
+ }
+
+ for (path_next = next(path_next, elem); *elem;
+ path_next = next(path_next, elem)) {
+ if ((channel->qid & CHDIR) == 0) {
+ goto notfound;
+ }
+
+ if (devtab[channel->index]->walk(channel, elem) < 0) {
+ channel_close(channel);
+ goto notfound;
+ }
+
+ mnt = mount_point_to_channel(channel->index, channel->qid);
+ if (mnt != NULL) {
+ clone(mnt, channel);
+ }
+ }
+
+ if (path_next == NULL) {
+ goto notfound;
+ }
+
+ /* TODO: check mode */
+ return channel;
+
+notfound:
+ channel_close(channel);
+noent:
+ return NULL;
+}
+
+/*******************************************************************************
+ * This function calls the clone function of the driver associated to the
+ * channel c.
+ ******************************************************************************/
+chan_t *clone(chan_t *c, chan_t *nc)
+{
+ return devtab[c->index]->clone(c, nc);
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver clone function.
+ * It creates a new channel and returns a pointer to it.
+ * It clones channel into new_channel.
+ ******************************************************************************/
+chan_t *devclone(chan_t *channel, chan_t *new_channel)
+{
+ if (channel == NULL) {
+ return NULL;
+ }
+
+ if (new_channel == NULL) {
+ new_channel = create_new_channel(channel->index);
+ if (new_channel == NULL) {
+ return NULL;
+ }
+ }
+
+ new_channel->qid = channel->qid;
+ new_channel->dev = channel->dev;
+ new_channel->mode = channel->mode;
+ new_channel->offset = channel->offset;
+ new_channel->index = channel->index;
+
+ return new_channel;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver walk function.
+ * It goes through all the elements of tab using the gen function until a match
+ * is found with name.
+ * If a match is found, it copies the qid of the new directory.
+ ******************************************************************************/
+int devwalk(chan_t *channel, const char *name, const dirtab_t *tab,
+ int ntab, devgen_t *gen)
+{
+ int i;
+ dir_t dir;
+
+ if ((channel == NULL) || (name == NULL) || (gen == NULL)) {
+ return -1;
+ }
+
+ if ((name[0] == '.') && (name[1] == '\0')) {
+ return 1;
+ }
+
+ for (i = 0; ; i++) {
+ switch ((*gen)(channel, tab, ntab, i, &dir)) {
+ case 0:
+ /* Intentional fall-through */
+ case -1:
+ return -1;
+ case 1:
+ if (strncmp(name, dir.name, NAMELEN) != 0) {
+ continue;
+ }
+ channel->qid = dir.qid;
+ return 1;
+ }
+ }
+}
+
+/*******************************************************************************
+ * This is a helper function which exposes the content of a directory, element
+ * by element. It is meant to be called until the end of the directory is
+ * reached or an error occurs.
+ * It returns -1 on error, 0 on end of directory and 1 when a new file is found.
+ ******************************************************************************/
+int dirread(chan_t *channel, dir_t *dir, const dirtab_t *tab,
+ int ntab, devgen_t *gen)
+{
+ int i, ret;
+
+ if ((channel == NULL) || (dir == NULL) || (gen == NULL)) {
+ return -1;
+ }
+
+ i = channel->offset/sizeof(dir_t);
+ ret = (*gen)(channel, tab, ntab, i, dir);
+ if (ret == 1) {
+ channel->offset += sizeof(dir_t);
+ }
+
+ return ret;
+}
+
+/*******************************************************************************
+ * This function sets the elements of dir.
+ ******************************************************************************/
+void make_dir_entry(chan_t *channel, dir_t *dir,
+ const char *name, long length, qid_t qid, unsigned int mode)
+{
+ if ((channel == NULL) || (dir == NULL) || (name == NULL)) {
+ return;
+ }
+
+ strlcpy(dir->name, name, sizeof(dir->name));
+ dir->length = length;
+ dir->qid = qid;
+ dir->mode = mode;
+
+ if ((qid & CHDIR) != 0) {
+ dir->mode |= O_DIR;
+ }
+
+ dir->index = channel->index;
+ dir->dev = channel->dev;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the internal driver gen
+ * function.
+ * It copies and formats the information of the nth element of tab into dir.
+ ******************************************************************************/
+int devgen(chan_t *channel, const dirtab_t *tab, int ntab, int n, dir_t *dir)
+{
+ const dirtab_t *dp;
+
+ if ((channel == NULL) || (dir == NULL) || (tab == NULL) ||
+ (n >= ntab)) {
+ return 0;
+ }
+
+ dp = &tab[n];
+ make_dir_entry(channel, dir, dp->name, dp->length, dp->qid, dp->perm);
+ return 1;
+}
+
+/*******************************************************************************
+ * This function returns a file descriptor identifying the channel associated to
+ * the given path.
+ ******************************************************************************/
+int open(const char *path, int mode)
+{
+ chan_t *channel;
+
+ if (path == NULL) {
+ return -1;
+ }
+
+ if (is_valid_mode(mode) == false) {
+ return -1;
+ }
+
+ channel = path_to_channel(path, mode);
+
+ return channel_to_fd(channel);
+}
+
+/*******************************************************************************
+ * This function closes the channel identified by the file descriptor fd.
+ ******************************************************************************/
+int close(int fd)
+{
+ chan_t *channel;
+
+ channel = fd_to_channel(fd);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ channel_close(channel);
+ return 0;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver stat function.
+ * It goes through all the elements of tab using the gen function until a match
+ * is found with file.
+ * If a match is found, dir contains the information file.
+ ******************************************************************************/
+int devstat(chan_t *dirc, const char *file, dir_t *dir,
+ const dirtab_t *tab, int ntab, devgen_t *gen)
+{
+ int i, r = 0;
+ chan_t *c, *mnt;
+
+ if ((dirc == NULL) || (dir == NULL) || (gen == NULL)) {
+ return -1;
+ }
+
+ c = path_to_channel(file, O_STAT);
+ if (c == NULL) {
+ return -1;
+ }
+
+ for (i = 0; ; i++) {
+ switch ((*gen)(dirc, tab, ntab, i, dir)) {
+ case 0:
+ /* Intentional fall-through */
+ case -1:
+ r = -1;
+ goto leave;
+ case 1:
+ mnt = mount_point_to_channel(dir->index, dir->qid);
+ if (mnt != NULL) {
+ dir->qid = mnt->qid;
+ dir->index = mnt->index;
+ }
+
+ if ((dir->qid != c->qid) || (dir->index != c->index)) {
+ continue;
+ }
+
+ goto leave;
+ }
+ }
+
+leave:
+ channel_close(c);
+ return r;
+}
+
+/*******************************************************************************
+ * This function calls the stat function of the driver associated to the parent
+ * directory of the file in path.
+ * The result is stored in dir.
+ ******************************************************************************/
+int stat(const char *path, dir_t *dir)
+{
+ int r;
+ size_t len;
+ chan_t *channel;
+ char *p, dirname[PATHLEN];
+
+ if ((path == NULL) || (dir == NULL)) {
+ return -1;
+ }
+
+ len = strlen(path);
+ if ((len + 1) > sizeof(dirname)) {
+ return -1;
+ }
+
+ memcpy(dirname, path, len);
+ for (p = dirname + len; p > dirname; --p) {
+ if (*p != '/') {
+ break;
+ }
+ }
+
+ p = memrchr(dirname, '/', p - dirname);
+ if (p == NULL) {
+ return -1;
+ }
+
+ dirname[p - dirname + 1] = '\0';
+
+ channel = path_to_channel(dirname, O_STAT);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ r = devtab[channel->index]->stat(channel, path, dir);
+ channel_close(channel);
+
+ return r;
+}
+
+/*******************************************************************************
+ * This function calls the read function of the driver associated to fd.
+ * It fills buf with at most n bytes.
+ * It returns the number of bytes that were actually read.
+ ******************************************************************************/
+int read(int fd, void *buf, int n)
+{
+ chan_t *channel;
+
+ if (buf == NULL) {
+ return -1;
+ }
+
+ channel = fd_to_channel(fd);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ if (((channel->qid & CHDIR) != 0) && (n < sizeof(dir_t))) {
+ return -1;
+ }
+
+ return devtab[channel->index]->read(channel, buf, n);
+}
+
+/*******************************************************************************
+ * This function calls the write function of the driver associated to fd.
+ * It writes at most n bytes of buf.
+ * It returns the number of bytes that were actually written.
+ ******************************************************************************/
+int write(int fd, void *buf, int n)
+{
+ chan_t *channel;
+
+ if (buf == NULL) {
+ return -1;
+ }
+
+ channel = fd_to_channel(fd);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ if ((channel->qid & CHDIR) != 0) {
+ return -1;
+ }
+
+ return devtab[channel->index]->write(channel, buf, n);
+}
+
+/*******************************************************************************
+ * This function calls the seek function of the driver associated to fd.
+ * It applies the offset off according to the strategy whence.
+ ******************************************************************************/
+int seek(int fd, long off, int whence)
+{
+ chan_t *channel;
+
+ channel = fd_to_channel(fd);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ if ((channel->qid & CHDIR) != 0) {
+ return -1;
+ }
+
+ return devtab[channel->index]->seek(channel, off, whence);
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver mount
+ * function.
+ ******************************************************************************/
+chan_t *deverrmount(chan_t *channel, const char *spec)
+{
+ return NULL;
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver write
+ * function.
+ ******************************************************************************/
+int deverrwrite(chan_t *channel, void *buf, int n)
+{
+ return -1;
+}
+
+/*******************************************************************************
+ * This function is the default error implementation of the driver seek
+ * function.
+ ******************************************************************************/
+int deverrseek(chan_t *channel, long off, int whence)
+{
+ return -1;
+}
+
+/*******************************************************************************
+ * This function is the default implementation of the driver seek function.
+ * It applies the offset off according to the strategy whence to the channel c.
+ ******************************************************************************/
+int devseek(chan_t *channel, long off, int whence)
+{
+ switch (whence) {
+ case KSEEK_SET:
+ channel->offset = off;
+ break;
+ case KSEEK_CUR:
+ channel->offset += off;
+ break;
+ case KSEEK_END:
+ /* Not implemented */
+ return -1;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function registers the channel associated to the path new as a mount
+ * point for the channel c.
+ ******************************************************************************/
+static int add_mount_point(chan_t *channel, const char *new)
+{
+ int i;
+ chan_t *cn;
+ struct mount_point *mp;
+
+ if (new == NULL) {
+ goto err0;
+ }
+
+ cn = path_to_channel(new, O_READ);
+ if (cn == NULL) {
+ goto err0;
+ }
+
+ if ((cn->qid & CHDIR) == 0) {
+ goto err1;
+ }
+
+ for (i = NR_MOUNT_POINTS - 1; i >= 0; i--) {
+ mp = &mount_points[i];
+ if (mp->new == NULL) {
+ break;
+ }
+ }
+
+ if (i < 0) {
+ goto err1;
+ }
+
+ mp->new = cn;
+ mp->old = channel;
+
+ return 0;
+
+err1:
+ channel_close(cn);
+err0:
+ return -1;
+}
+
+/*******************************************************************************
+ * This function registers the path new as a mount point for the path old.
+ ******************************************************************************/
+int bind(const char *old, const char *new)
+{
+ chan_t *channel;
+
+ channel = path_to_channel(old, O_BIND);
+ if (channel == NULL) {
+ return -1;
+ }
+
+ if (add_mount_point(channel, new) < 0) {
+ channel_close(channel);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
+ * This function calls the mount function of the driver associated to the path
+ * srv.
+ * It mounts the path srv on the path where.
+ ******************************************************************************/
+int mount(const char *srv, const char *where, const char *spec)
+{
+ chan_t *channel, *mount_point_chan;
+ int ret;
+
+ channel = path_to_channel(srv, O_RDWR);
+ if (channel == NULL) {
+ goto err0;
+ }
+
+ mount_point_chan = devtab[channel->index]->mount(channel, spec);
+ if (mount_point_chan == NULL) {
+ goto err1;
+ }
+
+ ret = add_mount_point(mount_point_chan, where);
+ if (ret < 0) {
+ goto err2;
+ }
+
+ channel_close(channel);
+
+ return 0;
+
+err2:
+ channel_close(mount_point_chan);
+err1:
+ channel_close(channel);
+err0:
+ return -1;
+}
+
+/*******************************************************************************
+ * This function initializes the device environment.
+ * It creates the '/' channel.
+ * It links the device drivers to the physical drivers.
+ ******************************************************************************/
+void debugfs_init(void)
+{
+ chan_t *channel, *cloned_channel;
+
+ for (channel = fdset; channel < &fdset[NR_CHANS]; channel++) {
+ channel_clear(channel);
+ }
+
+ channel = devattach('/', 0);
+ if (channel == NULL) {
+ panic();
+ }
+
+ cloned_channel = clone(channel, &slash_channel);
+ if (cloned_channel == NULL) {
+ panic();
+ }
+
+ channel_close(channel);
+ devlink();
+}
+
+__dead2 void devpanic(const char *cause)
+{
+ panic();
+}
diff --git a/lib/debugfs/dev.h b/lib/debugfs/dev.h
new file mode 100644
index 0000000000..c142651c76
--- /dev/null
+++ b/lib/debugfs/dev.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef DEV_H
+#define DEV_H
+
+#include <cdefs.h>
+#include <lib/debugfs.h>
+#include <stddef.h>
+
+/* FIXME: need configurability */
+#define NR_CHANS 10
+#define NR_CONSS 1
+#define NR_BINDS 4
+#define NR_FILES 18
+
+#define NODEV 255
+#define CHDIR (1 << 15)
+
+#define SYNCDEV 0
+#define SYNCALL 1
+
+typedef struct dev dev_t;
+typedef struct chan chan_t;
+typedef struct dirtab dirtab_t;
+typedef int devgen_t(chan_t *, const dirtab_t *, int, int, dir_t *);
+typedef struct attr attr_t;
+
+enum {
+ DEV_ROOT_QROOT,
+ DEV_ROOT_QDEV,
+ DEV_ROOT_QFIP,
+ DEV_ROOT_QBLOBS,
+ DEV_ROOT_QBLOBCTL,
+ DEV_ROOT_QPSCI
+};
+
+/*******************************************************************************
+ * This structure contains the necessary information to represent a directory
+ * of the filesystem.
+ ******************************************************************************/
+struct dirtab {
+ char name[NAMELEN];
+ qid_t qid;
+ long length;
+ unsigned char perm;
+ void *data;
+};
+
+/*******************************************************************************
+ * This structure defines the interface of device drivers.
+ * Each driver must implement a subset of those functions.
+ * It is possible to redirect to default implementations defined in dev.c.
+ ******************************************************************************/
+/* FIXME: comments for the callbacks */
+struct dev {
+ char id;
+ int (*stat)(chan_t *c, const char *file, dir_t *dir);
+ int (*walk)(chan_t *c, const char *name);
+ int (*read)(chan_t *c, void *buf, int n);
+ int (*write)(chan_t *c, void *buf, int n);
+ int (*seek)(chan_t *c, long off, int whence);
+ chan_t *(*clone)(chan_t *c, chan_t *nc);
+ chan_t *(*attach)(int id, int dev);
+ chan_t *(*mount)(chan_t *c, const char *spec);
+};
+
+/*******************************************************************************
+ * This structure defines the channel structure.
+ * A channel is a handle on an element of the filesystem.
+ ******************************************************************************/
+struct chan {
+ long offset;
+ qid_t qid;
+ unsigned char index; /* device index in devtab */
+ unsigned char dev;
+ unsigned char mode;
+};
+
+/*******************************************************************************
+ * This structure defines an abstract argument passed to physical drivers from
+ * the configuration file.
+ ******************************************************************************/
+struct attr {
+ char *key;
+ char *value;
+};
+
+chan_t *path_to_channel(const char *path, int mode);
+chan_t *clone(chan_t *c, chan_t *nc);
+chan_t *attach(int id, int dev);
+void channel_close(chan_t *c);
+int buf_to_channel(chan_t *c, void *dst, void *src, int nbytes, long len);
+int dirread(chan_t *c, dir_t *dir, const dirtab_t *tab,
+ int ntab, devgen_t *gen);
+void make_dir_entry(chan_t *c, dir_t *dir, const char *name, long length,
+ qid_t qid, unsigned int mode);
+void devlink(void);
+
+chan_t *devattach(int id, int dev);
+int devseek(chan_t *c, long off, int whence);
+chan_t *devclone(chan_t *c, chan_t *nc);
+int devgen(chan_t *c, const dirtab_t *tab, int ntab, int n, dir_t *dir);
+int devwalk(chan_t *c, const char *name, const dirtab_t *tab, int ntab,
+ devgen_t *gen);
+int devstat(chan_t *dirc, const char *file, dir_t *dir,
+ const dirtab_t *tab, int ntab, devgen_t *gen);
+
+chan_t *deverrmount(chan_t *c, const char *spec);
+int deverrwrite(chan_t *c, void *buf, int n);
+int deverrseek(chan_t *c, long off, int whence);
+
+extern dev_t *const devtab[];
+
+void __dead2 devpanic(const char *cause);
+
+#endif /* DEV_H */
diff --git a/lib/debugfs/devc.c b/lib/debugfs/devc.c
new file mode 100644
index 0000000000..1099a85d89
--- /dev/null
+++ b/lib/debugfs/devc.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+typedef struct dev dev_t;
+
+extern dev_t rootdevtab;
+extern dev_t fipdevtab;
+
+dev_t *const devtab[] = {
+ &rootdevtab,
+ &fipdevtab,
+ 0
+};
+
+void devlink(void)
+{
+}
diff --git a/lib/debugfs/devfip.c b/lib/debugfs/devfip.c
new file mode 100644
index 0000000000..5581b219fa
--- /dev/null
+++ b/lib/debugfs/devfip.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <lib/debugfs.h>
+#include <limits.h>
+#include <plat/arm/common/plat_arm.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tools_share/firmware_image_package.h>
+
+#include "dev.h"
+
+#define NR_FIPS 1
+#define STOC_HEADER (sizeof(fip_toc_header_t))
+#define STOC_ENTRY (sizeof(fip_toc_entry_t))
+
+struct fipfile {
+ chan_t *c;
+ long offset[NR_FILES];
+ long size[NR_FILES];
+};
+
+struct fip_entry {
+ uuid_t uuid;
+ long long offset_address;
+ long long size;
+ long long flags;
+};
+
+struct uuidnames {
+ const char name[NAMELEN];
+ const uuid_t uuid;
+};
+
+/*******************************************************************************
+ * This array links the FIP file names to their UUID.
+ * The elements are ordered according to the image number stored in
+ * tbbr_img_def.h, starting at index 1.
+ *
+ * TODO: this name to uuid binding will preferably be done using
+ * the coming Property Access Layer / Firmware CONFiguration feature.
+ ******************************************************************************/
+static const struct uuidnames uuidnames[] = {
+ {"", { {0}, {0}, {0}, 0, 0, {0} } },
+ {"bl2.bin", UUID_TRUSTED_BOOT_FIRMWARE_BL2},
+ {"scp-bl2.bin", UUID_SCP_FIRMWARE_SCP_BL2},
+ {"bl31.bin", UUID_EL3_RUNTIME_FIRMWARE_BL31},
+ {"bl32.bin", UUID_SECURE_PAYLOAD_BL32},
+ {"bl33.bin", UUID_NON_TRUSTED_FIRMWARE_BL33},
+ {"tb-fw.crt", UUID_TRUSTED_BOOT_FW_CERT},
+ {"trstd-k.crt", UUID_TRUSTED_KEY_CERT},
+ {"scp-fw-k.crt", UUID_SCP_FW_KEY_CERT},
+ {"soc-fw-k.crt", UUID_SOC_FW_KEY_CERT},
+ {"tos-fw-k.crt", UUID_TRUSTED_OS_FW_KEY_CERT},
+ {"nt-fw-k.crt", UUID_NON_TRUSTED_FW_KEY_CERT},
+ {"scp-fw-c.crt", UUID_SCP_FW_CONTENT_CERT},
+ {"soc-fw-c.crt", UUID_SOC_FW_CONTENT_CERT},
+ {"tos-fw-c.crt", UUID_TRUSTED_OS_FW_CONTENT_CERT},
+ {"nt-fw-c.crt", UUID_NON_TRUSTED_FW_CONTENT_CERT},
+ { },
+ {"fwu.crt", UUID_TRUSTED_FWU_CERT},
+ {"scp-bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_SCP_BL2U},
+ {"bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_BL2U},
+ {"ns-bl2u.bin", UUID_TRUSTED_UPDATE_FIRMWARE_NS_BL2U},
+ {"bl32-xtr1.bin", UUID_SECURE_PAYLOAD_BL32_EXTRA1},
+ {"bl32-xtr2.bin", UUID_SECURE_PAYLOAD_BL32_EXTRA2},
+ {"hw.cfg", UUID_HW_CONFIG},
+ {"tb-fw.cfg", UUID_TB_FW_CONFIG},
+ {"soc-fw.cfg", UUID_SOC_FW_CONFIG},
+ {"tos-fw.cfg", UUID_TOS_FW_CONFIG},
+ {"nt-fw.cfg", UUID_NT_FW_CONFIG},
+ {"rot-k.crt", UUID_ROT_KEY_CERT},
+ {"nt-k.crt", UUID_NON_TRUSTED_WORLD_KEY_CERT}
+};
+
+/*******************************************************************************
+ * This array contains all the available FIP files.
+ ******************************************************************************/
+static struct fipfile archives[NR_FIPS];
+
+/*******************************************************************************
+ * This variable stores the current number of registered FIP files.
+ ******************************************************************************/
+static int nfips;
+
+/*******************************************************************************
+ * This function parses the ToC of the FIP.
+ ******************************************************************************/
+static int get_entry(chan_t *c, struct fip_entry *entry)
+{
+ int n;
+
+ n = devtab[c->index]->read(c, entry, sizeof(struct fip_entry));
+ if (n <= 0) {
+ return n;
+ }
+
+ if (n != sizeof(struct fip_entry)) {
+ return -1;
+ }
+
+ if ((entry->size > LONG_MAX) || (entry->offset_address > LONG_MAX)) {
+ return -1;
+ }
+
+ if (entry->size == 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+/*******************************************************************************
+ * This function exposes the FIP images as files.
+ ******************************************************************************/
+static int fipgen(chan_t *c, const dirtab_t *tab, int ntab, int n, dir_t *dir)
+{
+ int i, r;
+ long off;
+ chan_t nc;
+ struct fip_entry entry;
+ struct fipfile *fip;
+ static const char unk[] = "unknown";
+
+ if (c->dev >= nfips) {
+ panic();
+ }
+
+ clone(archives[c->dev].c, &nc);
+ fip = &archives[nc.dev];
+
+ off = STOC_HEADER;
+ for (i = 0; i <= n; i++) {
+ if (fip->offset[i] == -1) {
+ return 0;
+ }
+
+ if (devtab[nc.index]->seek(&nc, off, KSEEK_SET) < 0) {
+ return -1;
+ }
+
+ r = get_entry(&nc, &entry);
+ if (r <= 0) {
+ return r;
+ }
+
+ off += sizeof(entry);
+ }
+
+ for (i = 1; i < NELEM(uuidnames); i++) {
+ if (memcmp(&uuidnames[i].uuid,
+ &entry.uuid, sizeof(uuid_t)) == 0) {
+ break;
+ }
+ }
+
+ if (i < NELEM(uuidnames)) {
+ make_dir_entry(c, dir, uuidnames[i].name,
+ entry.size, n, O_READ);
+ } else {
+ // TODO: set name depending on uuid node value
+ make_dir_entry(c, dir, unk, entry.size, n, O_READ);
+ }
+
+ return 1;
+}
+
+static int fipwalk(chan_t *c, const char *name)
+{
+ return devwalk(c, name, NULL, 0, fipgen);
+}
+
+static int fipstat(chan_t *c, const char *file, dir_t *dir)
+{
+ return devstat(c, file, dir, NULL, 0, fipgen);
+}
+
+/*******************************************************************************
+ * This function copies at most n bytes of the FIP image referred by c into
+ * buf.
+ ******************************************************************************/
+static int fipread(chan_t *c, void *buf, int n)
+{
+ long off;
+ chan_t cs;
+ struct fipfile *fip;
+ long size;
+
+ /* Only makes sense when using debug language */
+ assert(c->qid != CHDIR);
+
+ if ((c->dev >= nfips) || ((c->qid & CHDIR) != 0)) {
+ panic();
+ }
+
+ fip = &archives[c->dev];
+
+ if ((c->qid >= NR_FILES) || (fip->offset[c->qid] < 0)) {
+ panic();
+ }
+
+ clone(fip->c, &cs);
+
+ size = fip->size[c->qid];
+ if (c->offset >= size) {
+ return 0;
+ }
+
+ if (n < 0) {
+ return -1;
+ }
+
+ if (n > (size - c->offset)) {
+ n = size - c->offset;
+ }
+
+ off = fip->offset[c->qid] + c->offset;
+ if (devtab[cs.index]->seek(&cs, off, KSEEK_SET) < 0) {
+ return -1;
+ }
+
+ n = devtab[cs.index]->read(&cs, buf, n);
+ if (n > 0) {
+ c->offset += n;
+ }
+
+ return n;
+}
+
+/*******************************************************************************
+ * This function parses the FIP spec and registers its images in order to
+ * expose them as files in the driver namespace.
+ * It acts as an initialization function for the FIP driver.
+ * It returns a pointer to the newly created channel.
+ ******************************************************************************/
+static chan_t *fipmount(chan_t *c, const char *spec)
+{
+ int r, n, t;
+ chan_t *cspec;
+ uint32_t hname;
+ struct fip_entry entry;
+ struct fipfile *fip;
+ dir_t dir;
+
+ if (nfips == NR_FIPS) {
+ return NULL;
+ }
+
+ fip = &archives[nfips];
+
+ for (n = 0; n < NR_FILES; n++) {
+ fip->offset[n] = -1;
+ }
+
+ cspec = path_to_channel(spec, O_READ);
+ if (cspec == NULL) {
+ return NULL;
+ }
+
+ fip->c = cspec;
+
+ r = devtab[cspec->index]->read(cspec, &hname, sizeof(hname));
+ if (r < 0) {
+ goto err;
+ }
+
+ if ((r != sizeof(hname)) || (hname != TOC_HEADER_NAME)) {
+ goto err;
+ }
+
+ if (stat(spec, &dir) < 0) {
+ goto err;
+ }
+
+ t = cspec->index;
+ if (devtab[t]->seek(cspec, STOC_HEADER, KSEEK_SET) < 0) {
+ goto err;
+ }
+
+ for (n = 0; n < NR_FILES; n++) {
+ switch (get_entry(cspec, &entry)) {
+ case 0:
+ return attach('F', nfips++);
+ case -1:
+ goto err;
+ default:
+ if ((entry.offset_address + entry.size) > dir.length) {
+ goto err;
+ }
+
+ fip->offset[n] = entry.offset_address;
+ fip->size[n] = entry.size;
+ break;
+ }
+ }
+
+err:
+ channel_close(cspec);
+ return NULL;
+}
+
+const dev_t fipdevtab = {
+ .id = 'F',
+ .stat = fipstat,
+ .clone = devclone,
+ .attach = devattach,
+ .walk = fipwalk,
+ .read = fipread,
+ .write = deverrwrite,
+ .mount = fipmount,
+ .seek = devseek
+};
+
diff --git a/lib/debugfs/devroot.c b/lib/debugfs/devroot.c
new file mode 100644
index 0000000000..9dd6c92ef4
--- /dev/null
+++ b/lib/debugfs/devroot.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <lib/debugfs.h>
+
+#include "blobs.h"
+#include "dev.h"
+
+/*******************************************************************************
+ * This array contains the directories available from the root directory.
+ ******************************************************************************/
+static const dirtab_t dirtab[] = {
+ {"dev", CHDIR | DEV_ROOT_QDEV, 0, O_READ},
+ {"blobs", CHDIR | DEV_ROOT_QBLOBS, 0, O_READ},
+ {"fip", CHDIR | DEV_ROOT_QFIP, 0, O_READ}
+};
+
+static const dirtab_t devfstab[] = {
+};
+
+/*******************************************************************************
+ * This function exposes the elements of the root directory.
+ * It also exposes the content of the dev and blobs directories.
+ ******************************************************************************/
+static int rootgen(chan_t *channel, const dirtab_t *tab, int ntab,
+ int n, dir_t *dir)
+{
+ switch (channel->qid & ~CHDIR) {
+ case DEV_ROOT_QROOT:
+ tab = dirtab;
+ ntab = NELEM(dirtab);
+ break;
+ case DEV_ROOT_QDEV:
+ tab = devfstab;
+ ntab = NELEM(devfstab);
+ break;
+ case DEV_ROOT_QBLOBS:
+ tab = blobtab;
+ ntab = NELEM(blobtab);
+ break;
+ default:
+ return 0;
+ }
+
+ return devgen(channel, tab, ntab, n, dir);
+}
+
+static int rootwalk(chan_t *channel, const char *name)
+{
+ return devwalk(channel, name, NULL, 0, rootgen);
+}
+
+/*******************************************************************************
+ * This function copies at most n bytes from the element referred by c into buf.
+ ******************************************************************************/
+static int rootread(chan_t *channel, void *buf, int size)
+{
+ const dirtab_t *dp;
+ dir_t *dir;
+
+ if ((channel->qid & CHDIR) != 0) {
+ if (size < sizeof(dir_t)) {
+ return -1;
+ }
+
+ dir = buf;
+ return dirread(channel, dir, NULL, 0, rootgen);
+ }
+
+ /* Only makes sense when using debug language */
+ assert(channel->qid != DEV_ROOT_QBLOBCTL);
+
+ dp = &blobtab[channel->qid - DEV_ROOT_QBLOBCTL];
+ return buf_to_channel(channel, buf, dp->data, size, dp->length);
+}
+
+static int rootstat(chan_t *channel, const char *file, dir_t *dir)
+{
+ return devstat(channel, file, dir, NULL, 0, rootgen);
+}
+
+const dev_t rootdevtab = {
+ .id = '/',
+ .stat = rootstat,
+ .clone = devclone,
+ .attach = devattach,
+ .walk = rootwalk,
+ .read = rootread,
+ .write = deverrwrite,
+ .mount = deverrmount,
+ .seek = devseek
+};
diff --git a/lib/el3_runtime/aarch64/context.S b/lib/el3_runtime/aarch64/context.S
index 1101425206..1bbd61005f 100644
--- a/lib/el3_runtime/aarch64/context.S
+++ b/lib/el3_runtime/aarch64/context.S
@@ -6,6 +6,7 @@
#include <arch.h>
#include <asm_macros.S>
+#include <assert_macros.S>
#include <context.h>
.global el1_sysregs_context_save
@@ -477,6 +478,13 @@ endfunc restore_gp_pmcr_pauth_regs
* ------------------------------------------------------------------
*/
func el3_exit
+#if ENABLE_ASSERTIONS
+ /* el3_exit assumes SP_EL0 on entry */
+ mrs x17, spsel
+ cmp x17, #MODE_SP_EL0
+ ASM_ASSERT(eq)
+#endif
+
/* ----------------------------------------------------------
* Save the current SP_EL0 i.e. the EL3 runtime stack which
* will be used for handling the next SMC.
diff --git a/lib/el3_runtime/aarch64/context_mgmt.c b/lib/el3_runtime/aarch64/context_mgmt.c
index d65e02d5e1..b7908adec4 100644
--- a/lib/el3_runtime/aarch64/context_mgmt.c
+++ b/lib/el3_runtime/aarch64/context_mgmt.c
@@ -181,6 +181,16 @@ void cm_setup_context(cpu_context_t *ctx, const entry_point_info_t *ep)
scr_el3 |= SCR_HCE_BIT;
}
+ /* Enable S-EL2 if the next EL is EL2 and security state is secure */
+ if ((security_state == SECURE) && (GET_EL(ep->spsr) == MODE_EL2)) {
+ if (GET_RW(ep->spsr) != MODE_RW_64) {
+ ERROR("S-EL2 can not be used in AArch32.");
+ panic();
+ }
+
+ scr_el3 |= SCR_EEL2_BIT;
+ }
+
/*
* Initialise SCTLR_EL1 to the reset value corresponding to the target
* execution state setting all fields rather than relying of the hw.
diff --git a/lib/libc/libc.mk b/lib/libc/libc.mk
index e1b5560f84..93d30d0356 100644
--- a/lib/libc/libc.mk
+++ b/lib/libc/libc.mk
@@ -12,6 +12,7 @@ LIBC_SRCS := $(addprefix lib/libc/, \
memcmp.c \
memcpy.c \
memmove.c \
+ memrchr.c \
memset.c \
printf.c \
putchar.c \
diff --git a/lib/libc/memrchr.c b/lib/libc/memrchr.c
new file mode 100644
index 0000000000..01caef3aef
--- /dev/null
+++ b/lib/libc/memrchr.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#undef memrchr
+
+void *memrchr(const void *src, int c, size_t len)
+{
+ const unsigned char *s = src + (len - 1);
+
+ while (len--) {
+ if (*s == (unsigned char)c) {
+ return (void*) s;
+ }
+
+ s--;
+ }
+
+ return NULL;
+}
diff --git a/lib/psci/psci_common.c b/lib/psci/psci_common.c
index 7c42be7e51..ea1a01de95 100644
--- a/lib/psci/psci_common.c
+++ b/lib/psci/psci_common.c
@@ -43,6 +43,7 @@ const spd_pm_ops_t *psci_spd_pm;
static plat_local_state_t
psci_req_local_pwr_states[PLAT_MAX_PWR_LVL][PLATFORM_CORE_COUNT];
+unsigned int psci_plat_core_count;
/*******************************************************************************
* Arrays that hold the platform's power domain tree information for state
@@ -161,7 +162,7 @@ unsigned int psci_is_last_on_cpu(void)
{
unsigned int cpu_idx, my_idx = plat_my_core_pos();
- for (cpu_idx = 0; cpu_idx < (unsigned int)PLATFORM_CORE_COUNT;
+ for (cpu_idx = 0; cpu_idx < psci_plat_core_count;
cpu_idx++) {
if (cpu_idx == my_idx) {
assert(psci_get_aff_info_state() == AFF_STATE_ON);
@@ -208,7 +209,7 @@ static void psci_set_req_local_pwr_state(unsigned int pwrlvl,
{
assert(pwrlvl > PSCI_CPU_PWR_LVL);
if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
- (cpu_idx < (unsigned int) PLATFORM_CORE_COUNT)) {
+ (cpu_idx < psci_plat_core_count)) {
psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx] = req_pwr_state;
}
}
@@ -220,10 +221,10 @@ void __init psci_init_req_local_pwr_states(void)
{
/* Initialize the requested state of all non CPU power domains as OFF */
unsigned int pwrlvl;
- int core;
+ unsigned int core;
for (pwrlvl = 0U; pwrlvl < PLAT_MAX_PWR_LVL; pwrlvl++) {
- for (core = 0; core < PLATFORM_CORE_COUNT; core++) {
+ for (core = 0; core < psci_plat_core_count; core++) {
psci_req_local_pwr_states[pwrlvl][core] =
PLAT_MAX_OFF_STATE;
}
@@ -244,7 +245,7 @@ static plat_local_state_t *psci_get_req_local_pwr_states(unsigned int pwrlvl,
assert(pwrlvl > PSCI_CPU_PWR_LVL);
if ((pwrlvl > PSCI_CPU_PWR_LVL) && (pwrlvl <= PLAT_MAX_PWR_LVL) &&
- (cpu_idx < (unsigned int) PLATFORM_CORE_COUNT)) {
+ (cpu_idx < psci_plat_core_count)) {
return &psci_req_local_pwr_states[pwrlvl - 1U][cpu_idx];
} else
return NULL;
@@ -888,7 +889,7 @@ int psci_spd_migrate_info(u_register_t *mpidr)
void psci_print_power_domain_map(void)
{
#if LOG_LEVEL >= LOG_LEVEL_INFO
- int idx;
+ unsigned int idx;
plat_local_state_t state;
plat_local_state_type_t state_type;
@@ -900,7 +901,7 @@ void psci_print_power_domain_map(void)
};
INFO("PSCI Power Domain Map:\n");
- for (idx = 0; idx < (PSCI_NUM_PWR_DOMAINS - PLATFORM_CORE_COUNT);
+ for (idx = 0; idx < (PSCI_NUM_PWR_DOMAINS - psci_plat_core_count);
idx++) {
state_type = find_local_state_type(
psci_non_cpu_pd_nodes[idx].local_state);
@@ -912,7 +913,7 @@ void psci_print_power_domain_map(void)
psci_non_cpu_pd_nodes[idx].local_state);
}
- for (idx = 0; idx < PLATFORM_CORE_COUNT; idx++) {
+ for (idx = 0; idx < psci_plat_core_count; idx++) {
state = psci_get_cpu_local_state_by_idx(idx);
state_type = find_local_state_type(state);
INFO(" CPU Node : MPID 0x%llx, parent_node %d,"
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 5c0e952a99..52a8b8a18b 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -219,16 +219,19 @@ int psci_cpu_off(void)
int psci_affinity_info(u_register_t target_affinity,
unsigned int lowest_affinity_level)
{
- int target_idx;
+ int ret;
+ unsigned int target_idx;
/* We dont support level higher than PSCI_CPU_PWR_LVL */
if (lowest_affinity_level > PSCI_CPU_PWR_LVL)
return PSCI_E_INVALID_PARAMS;
/* Calculate the cpu index of the target */
- target_idx = plat_core_pos_by_mpidr(target_affinity);
- if (target_idx == -1)
+ ret = plat_core_pos_by_mpidr(target_affinity);
+ if (ret == -1) {
return PSCI_E_INVALID_PARAMS;
+ }
+ target_idx = (unsigned int)ret;
/*
* Generic management:
@@ -245,7 +248,7 @@ 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((unsigned int)target_idx,
+ flush_cpu_data_by_index(target_idx,
psci_svc_cpu_data.aff_info_state);
return psci_get_aff_info_state_by_idx(target_idx);
diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c
index e8cd8feb0a..54470457a8 100644
--- a/lib/psci/psci_off.c
+++ b/lib/psci/psci_off.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,7 +43,7 @@ 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;
- int idx = (int) plat_my_core_pos();
+ unsigned int idx = plat_my_core_pos();
psci_power_state_t state_info;
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
diff --git a/lib/psci/psci_on.c b/lib/psci/psci_on.c
index 470b4f33ec..dd48e105d0 100644
--- a/lib/psci/psci_on.c
+++ b/lib/psci/psci_on.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -20,12 +20,12 @@
/*
* Helper functions for the CPU level spinlocks
*/
-static inline void psci_spin_lock_cpu(int idx)
+static inline void psci_spin_lock_cpu(unsigned int idx)
{
spin_lock(&psci_cpu_pd_nodes[idx].cpu_lock);
}
-static inline void psci_spin_unlock_cpu(int idx)
+static inline void psci_spin_unlock_cpu(unsigned int idx)
{
spin_unlock(&psci_cpu_pd_nodes[idx].cpu_lock);
}
@@ -61,12 +61,14 @@ int psci_cpu_on_start(u_register_t target_cpu,
{
int rc;
aff_info_state_t target_aff_state;
- int target_idx = plat_core_pos_by_mpidr(target_cpu);
+ int ret = plat_core_pos_by_mpidr(target_cpu);
+ unsigned int target_idx = (unsigned int)ret;
/* Calling function must supply valid input arguments */
- assert(target_idx >= 0);
+ assert(ret >= 0);
assert(ep != NULL);
+
/*
* This function must only be called on platforms where the
* CPU_ON platform hooks have been implemented.
@@ -93,7 +95,7 @@ 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((unsigned int)target_idx,
+ flush_cpu_data_by_index(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)
@@ -113,7 +115,7 @@ 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((unsigned int)target_idx,
+ flush_cpu_data_by_index(target_idx,
psci_svc_cpu_data.aff_info_state);
/*
@@ -126,7 +128,7 @@ 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((unsigned int)target_idx,
+ flush_cpu_data_by_index(target_idx,
psci_svc_cpu_data.aff_info_state);
assert(psci_get_aff_info_state_by_idx(target_idx) ==
@@ -146,11 +148,11 @@ int psci_cpu_on_start(u_register_t target_cpu,
if (rc == PSCI_E_SUCCESS)
/* Store the re-entry information for the non-secure world. */
- cm_init_context_by_index((unsigned int)target_idx, ep);
+ cm_init_context_by_index(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((unsigned int)target_idx,
+ flush_cpu_data_by_index(target_idx,
psci_svc_cpu_data.aff_info_state);
}
@@ -164,7 +166,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(int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_on_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
{
/*
* Plat. management: Perform the platform specific actions
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index b49847c950..e2dcfa8b1e 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -251,6 +251,7 @@ extern const plat_psci_ops_t *psci_plat_pm_ops;
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;
+extern unsigned int psci_plat_core_count;
/*******************************************************************************
* SPD's power management hooks registered with PSCI
@@ -300,7 +301,7 @@ void prepare_cpu_pwr_dwn(unsigned int power_level);
int psci_cpu_on_start(u_register_t target_cpu,
const entry_point_info_t *ep);
-void psci_cpu_on_finish(int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_on_finish(unsigned 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);
@@ -311,7 +312,7 @@ void psci_cpu_suspend_start(const entry_point_info_t *ep,
psci_power_state_t *state_info,
unsigned int is_power_down_state);
-void psci_cpu_suspend_finish(int cpu_idx, const psci_power_state_t *state_info);
+void psci_cpu_suspend_finish(unsigned 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);
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 853f9157cf..d1ec998084 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -84,15 +84,16 @@ static void __init psci_init_pwr_domain_node(unsigned char node_idx,
*******************************************************************************/
static void __init psci_update_pwrlvl_limits(void)
{
- int j, cpu_idx;
+ unsigned int cpu_idx;
+ int j;
unsigned int nodes_idx[PLAT_MAX_PWR_LVL] = {0};
unsigned int temp_index[PLAT_MAX_PWR_LVL];
- for (cpu_idx = 0; cpu_idx < PLATFORM_CORE_COUNT; cpu_idx++) {
+ for (cpu_idx = 0; cpu_idx < psci_plat_core_count; cpu_idx++) {
psci_get_parent_pwr_domain_nodes(cpu_idx,
- (unsigned int)PLAT_MAX_PWR_LVL,
+ PLAT_MAX_PWR_LVL,
temp_index);
- for (j = (int) 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,12 +110,13 @@ static void __init psci_update_pwrlvl_limits(void)
* informs the number of root power domains. The parent nodes of the root nodes
* will point to an invalid entry(-1).
******************************************************************************/
-static void __init populate_power_domain_tree(const unsigned char *topology)
+static unsigned int __init populate_power_domain_tree(const unsigned char
+ *topology)
{
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;
+ unsigned int parent_node_index = 0U;
+ int level = (int)PLAT_MAX_PWR_LVL;
/*
* For each level the inputs are:
@@ -143,8 +145,8 @@ static void __init populate_power_domain_tree(const unsigned char *topology)
for (j = node_index;
j < (node_index + num_children); j++)
psci_init_pwr_domain_node((unsigned char)j,
- parent_node_index - 1,
- (unsigned char)level);
+ parent_node_index - 1U,
+ (unsigned char)level);
node_index = j;
num_nodes_at_next_lvl += num_children;
@@ -160,7 +162,8 @@ static void __init populate_power_domain_tree(const unsigned char *topology)
}
/* Validate the sanity of array exported by the platform */
- assert((int) j == PLATFORM_CORE_COUNT);
+ assert(j <= PLATFORM_CORE_COUNT);
+ return j;
}
/*******************************************************************************
@@ -199,7 +202,7 @@ int __init psci_setup(const psci_lib_args_t *lib_args)
topology_tree = plat_get_power_domain_tree_desc();
/* Populate the power domain arrays using the platform topology map */
- populate_power_domain_tree(topology_tree);
+ psci_plat_core_count = populate_power_domain_tree(topology_tree);
/* Update the CPU limits for each node in psci_non_cpu_pd_nodes */
psci_update_pwrlvl_limits();
diff --git a/lib/psci/psci_stat.c b/lib/psci/psci_stat.c
index 772a1840a1..ecef95ab66 100644
--- a/lib/psci/psci_stat.c
+++ b/lib/psci/psci_stat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,7 +28,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 - 1U] = -1};
/*
* Following are used to store PSCI STAT values for
@@ -77,7 +77,7 @@ void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
unsigned int lvl, parent_idx;
- int cpu_idx = (int) plat_my_core_pos();
+ unsigned int cpu_idx = plat_my_core_pos();
assert(end_pwrlvl <= PLAT_MAX_PWR_LVL);
assert(state_info != NULL);
@@ -94,7 +94,7 @@ void psci_stats_update_pwr_down(unsigned int end_pwrlvl,
* The power domain is entering a low power state, so this is
* the last CPU for this power domain
*/
- last_cpu_in_non_cpu_pd[parent_idx] = cpu_idx;
+ last_cpu_in_non_cpu_pd[parent_idx] = (int)cpu_idx;
parent_idx = psci_non_cpu_pd_nodes[parent_idx].parent_node;
}
@@ -110,7 +110,7 @@ void psci_stats_update_pwr_up(unsigned int end_pwrlvl,
const psci_power_state_t *state_info)
{
unsigned int lvl, parent_idx;
- int cpu_idx = (int) plat_my_core_pos();
+ unsigned int cpu_idx = plat_my_core_pos();
int stat_idx;
plat_local_state_t local_state;
u_register_t residency;
@@ -150,7 +150,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]);
+ (unsigned int)last_cpu_in_non_cpu_pd[parent_idx]);
/* Initialize back to reset value */
last_cpu_in_non_cpu_pd[parent_idx] = -1;
diff --git a/lib/psci/psci_suspend.c b/lib/psci/psci_suspend.c
index 98dd2d62c3..da9f328a5b 100644
--- a/lib/psci/psci_suspend.c
+++ b/lib/psci/psci_suspend.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,7 +25,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(int cpu_idx,
+static void psci_suspend_to_standby_finisher(unsigned int cpu_idx,
unsigned int end_pwrlvl)
{
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
@@ -157,7 +157,7 @@ void psci_cpu_suspend_start(const entry_point_info_t *ep,
unsigned int is_power_down_state)
{
int skip_wfi = 0;
- int idx = (int) plat_my_core_pos();
+ unsigned int idx = plat_my_core_pos();
unsigned int parent_nodes[PLAT_MAX_PWR_LVL] = {0};
/*
@@ -276,7 +276,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_suspend_finish(int cpu_idx, const psci_power_state_t *state_info)
+void psci_cpu_suspend_finish(unsigned int cpu_idx, const psci_power_state_t *state_info)
{
unsigned int counter_freq;
unsigned int max_off_lvl;
diff --git a/lib/sprt/sprt_host.c b/lib/sprt/sprt_host.c
deleted file mode 100644
index c4d436e1ce..0000000000
--- a/lib/sprt/sprt_host.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#include "sprt_common.h"
-#include "sprt_queue.h"
-
-void sprt_initialize_queues(void *buffer_base, size_t buffer_size)
-{
- /* Initialize queue for blocking messages */
-
- void *blocking_base = buffer_base;
- uint32_t blocking_num = 4U;
- size_t blocking_size = SPRT_QUEUE_HEADER_SIZE +
- SPRT_QUEUE_ENTRY_MSG_SIZE * blocking_num;
-
- sprt_queue_init(blocking_base, blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE);
-
- /* Initialize queue for non-blocking messages */
-
- void *non_blocking_base = (void *)((uintptr_t)blocking_base + blocking_size);
- size_t non_blocking_size = buffer_size - blocking_size;
- uint32_t non_blocking_num = (non_blocking_size - SPRT_QUEUE_HEADER_SIZE) /
- SPRT_QUEUE_ENTRY_MSG_SIZE;
-
- sprt_queue_init(non_blocking_base, non_blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE);
-}
-
-int sprt_push_message(void *buffer_base,
- const struct sprt_queue_entry_message *message,
- int queue_num)
-{
- struct sprt_queue *q = buffer_base;
-
- while (queue_num-- > 0) {
- uintptr_t next_addr = (uintptr_t)q + sizeof(struct sprt_queue) +
- q->entry_num * q->entry_size;
- q = (struct sprt_queue *) next_addr;
- }
-
- return sprt_queue_push(q, message);
-}
diff --git a/lib/sprt/sprt_host.mk b/lib/sprt/sprt_host.mk
deleted file mode 100644
index abcfe5e498..0000000000
--- a/lib/sprt/sprt_host.mk
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-SPRT_LIB_SOURCES := $(addprefix lib/sprt/, \
- sprt_host.c \
- sprt_queue.c)
-
-SPRT_LIB_INCLUDES := -Iinclude/lib/sprt/
diff --git a/lib/sprt/sprt_queue.c b/lib/sprt/sprt_queue.c
deleted file mode 100644
index 2bd4139ea4..0000000000
--- a/lib/sprt/sprt_queue.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "sprt_queue.h"
-
-void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size)
-{
- assert(queue_base != NULL);
- assert(entry_size > 0U);
- assert(entry_num > 0U);
-
- struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
- queue->entry_num = entry_num;
- queue->entry_size = entry_size;
- queue->idx_write = 0U;
- queue->idx_read = 0U;
-
- memset(queue->data, 0, entry_num * entry_size);
-}
-
-int sprt_queue_is_empty(void *queue_base)
-{
- assert(queue_base != NULL);
-
- struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
- return (queue->idx_write == queue->idx_read);
-}
-
-int sprt_queue_is_full(void *queue_base)
-{
- assert(queue_base != NULL);
-
- struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
- uint32_t idx_next_write = (queue->idx_write + 1) % queue->entry_num;
-
- return (idx_next_write == queue->idx_read);
-}
-
-int sprt_queue_push(void *queue_base, const void *entry)
-{
- assert(entry != NULL);
- assert(queue_base != NULL);
-
- if (sprt_queue_is_full(queue_base) != 0) {
- return -ENOMEM;
- }
-
- struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
- uint8_t *dst_entry = &queue->data[queue->entry_size * queue->idx_write];
-
- memcpy(dst_entry, entry, queue->entry_size);
-
- /*
- * Make sure that the message data is visible before increasing the
- * counter of available messages.
- */
- __asm__ volatile("dmb st" ::: "memory");
-
- queue->idx_write = (queue->idx_write + 1) % queue->entry_num;
-
- __asm__ volatile("dmb st" ::: "memory");
-
- return 0;
-}
-
-int sprt_queue_pop(void *queue_base, void *entry)
-{
- assert(entry != NULL);
- assert(queue_base != NULL);
-
- if (sprt_queue_is_empty(queue_base) != 0) {
- return -ENOENT;
- }
-
- struct sprt_queue *queue = (struct sprt_queue *)queue_base;
-
- uint8_t *src_entry = &queue->data[queue->entry_size * queue->idx_read];
-
- memcpy(entry, src_entry, queue->entry_size);
-
- /*
- * Make sure that the message data is visible before increasing the
- * counter of read messages.
- */
- __asm__ volatile("dmb st" ::: "memory");
-
- queue->idx_read = (queue->idx_read + 1) % queue->entry_num;
-
- __asm__ volatile("dmb st" ::: "memory");
-
- return 0;
-}
diff --git a/lib/sprt/sprt_queue.h b/lib/sprt/sprt_queue.h
deleted file mode 100644
index 4ea1bc231b..0000000000
--- a/lib/sprt/sprt_queue.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPRT_QUEUE_H
-#define SPRT_QUEUE_H
-
-#include <stdint.h>
-
-/* Struct that defines a queue. Not to be used directly. */
-struct __attribute__((__packed__)) sprt_queue {
- uint32_t entry_num; /* Number of entries */
- uint32_t entry_size; /* Size of an entry */
- uint32_t idx_write; /* Index of first empty entry */
- uint32_t idx_read; /* Index of first entry to read */
- uint8_t data[0]; /* Start of data */
-};
-
-#define SPRT_QUEUE_HEADER_SIZE (sizeof(struct sprt_queue))
-
-/*
- * Initializes a memory region to be used as a queue of the given number of
- * entries with the specified size.
- */
-void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size);
-
-/* Returns 1 if the queue is empty, 0 otherwise */
-int sprt_queue_is_empty(void *queue_base);
-
-/* Returns 1 if the queue is full, 0 otherwise */
-int sprt_queue_is_full(void *queue_base);
-
-/*
- * Pushes a new entry intro the queue. Returns 0 on success, -ENOMEM if the
- * queue is full.
- */
-int sprt_queue_push(void *queue_base, const void *entry);
-
-/*
- * Pops an entry from the queue. Returns 0 on success, -ENOENT if the queue is
- * empty.
- */
-int sprt_queue_pop(void *queue_base, void *entry);
-
-#endif /* SPRT_QUEUE_H */
diff --git a/make_helpers/build_macros.mk b/make_helpers/build_macros.mk
index b89d87ea60..47f3ebd861 100644
--- a/make_helpers/build_macros.mk
+++ b/make_helpers/build_macros.mk
@@ -236,7 +236,7 @@ $(eval BL_CFLAGS := $(BL$(call uppercase,$(3))_CFLAGS))
$(OBJ): $(2) $(filter-out %.d,$(MAKEFILE_LIST)) | bl$(3)_dirs
$$(ECHO) " CC $$<"
- $$(Q)$$(CC) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
+ $$(Q)$$(CC) $$(LTO_CFLAGS) $$(TF_CFLAGS) $$(CFLAGS) $(BL_CFLAGS) -D$(IMAGE) $(MAKE_DEP) -c $$< -o $$@
-include $(DEP)
@@ -433,6 +433,10 @@ ifneq ($(findstring armlink,$(notdir $(LD))),)
--map --list="$(MAPFILE)" --scatter=${PLAT_DIR}/scat/bl${1}.scat \
$(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS) \
$(BUILD_DIR)/build_message.o $(OBJS)
+else ifneq ($(findstring gcc,$(notdir $(LD))),)
+ $$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Wl,-Map=$(MAPFILE) \
+ -Wl,-T$(LINKERFILE) $(BUILD_DIR)/build_message.o \
+ $(OBJS) $(LDPATHS) $(LIBWRAPPER) $(LDLIBS) $(BL_LIBS)
else
$$(Q)$$(LD) -o $$@ $$(TF_LDFLAGS) $$(LDFLAGS) -Map=$(MAPFILE) \
--script $(LINKERFILE) $(BUILD_DIR)/build_message.o \
diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk
index b7fb173b16..53832c5611 100644
--- a/make_helpers/defaults.mk
+++ b/make_helpers/defaults.mk
@@ -171,6 +171,10 @@ SDEI_SUPPORT := 0
# platform Makefile is free to override this value.
SEPARATE_CODE_AND_RODATA := 0
+# Put NOBITS sections (.bss, stacks, page tables, and coherent memory) in a
+# separate memory region, which may be discontiguous from the rest of BL31.
+SEPARATE_NOBITS_REGION := 0
+
# If the BL31 image initialisation code is recalimed after use for the secondary
# cores stack
RECLAIM_INIT_CODE := 0
@@ -178,11 +182,8 @@ RECLAIM_INIT_CODE := 0
# SPD choice
SPD := none
-# For including the Secure Partition Manager
-ENABLE_SPM := 0
-
-# Use the SPM based on MM
-SPM_MM := 1
+# Enable the Management Mode (MM)-based Secure Partition Manager implementation
+SPM_MM := 0
# Flag to introduce an infinite loop in BL1 just before it exits into the next
# image. This is meant to help debugging the post-BL2 phase.
@@ -194,6 +195,9 @@ TRUSTED_BOARD_BOOT := 0
# Build option to choose whether Trusted Firmware uses Coherent memory or not.
USE_COHERENT_MEM := 1
+# Build option to add debugfs support
+USE_DEBUGFS := 0
+
# Build option to choose whether Trusted Firmware uses library at ROM
USE_ROMLIB := 0
@@ -239,3 +243,6 @@ SANITIZE_UB := off
# implementation variant using the ARMv8.1-LSE compare-and-swap instruction.
# Default: disabled
USE_SPINLOCK_CAS := 0
+
+# Enable Link Time Optimization
+ENABLE_LTO := 0
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk
index 6866bd65aa..98bcf3e225 100644
--- a/plat/allwinner/common/allwinner-common.mk
+++ b/plat/allwinner/common/allwinner-common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -8,8 +8,7 @@ include lib/xlat_tables_v2/xlat_tables.mk
AW_PLAT := plat/allwinner
-PLAT_INCLUDES := -Iinclude/plat/arm/common \
- -Iinclude/plat/arm/common/aarch64 \
+PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64 \
-I${AW_PLAT}/common/include \
-I${AW_PLAT}/${PLAT}/include
@@ -20,7 +19,8 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \
${AW_PLAT}/common/plat_helpers.S \
${AW_PLAT}/common/sunxi_common.c
-BL31_SOURCES += drivers/arm/gic/common/gic_common.c \
+BL31_SOURCES += drivers/allwinner/axp/common.c \
+ drivers/arm/gic/common/gic_common.c \
drivers/arm/gic/v2/gicv2_helpers.c \
drivers/arm/gic/v2/gicv2_main.c \
drivers/delay_timer/delay_timer.c \
@@ -55,11 +55,11 @@ PROGRAMMABLE_RESET_ADDRESS := 1
# Allow mapping read-only data as execute-never.
SEPARATE_CODE_AND_RODATA := 1
+# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL.
+SEPARATE_NOBITS_REGION := 1
+
# BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL
RESET_TO_BL31 := 1
-# We are short on memory, so save 3.5KB by not having an extra coherent page.
-USE_COHERENT_MEM := 0
-
# This platform is single-cluster and does not require coherency setup.
WARMBOOT_ENABLE_DCACHE_EARLY := 1
diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h
index ede3881a7d..0a00076679 100644
--- a/plat/allwinner/common/include/platform_def.h
+++ b/plat/allwinner/common/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,6 +16,10 @@
#define BL31_BASE SUNXI_SRAM_A2_BASE
#define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE)
+/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */
+#define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000)
+#define BL31_NOBITS_LIMIT (SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE)
+
/* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */
#define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 20))
@@ -28,7 +32,7 @@
#define CACHE_WRITEBACK_SHIFT 6
#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT)
-#define MAX_MMAP_REGIONS (3 + PLATFORM_MMAP_REGIONS)
+#define MAX_MMAP_REGIONS (4 + PLATFORM_MMAP_REGIONS)
#define MAX_XLAT_TABLES 1
#define PLAT_MAX_PWR_LVL_STATES U(2)
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h
index 11668797b6..dcf3dc965c 100644
--- a/plat/allwinner/common/include/sunxi_private.h
+++ b/plat/allwinner/common/include/sunxi_private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,7 +12,7 @@ void sunxi_configure_mmu_el3(int flags);
void sunxi_cpu_on(u_register_t mpidr);
void sunxi_cpu_off(u_register_t mpidr);
void sunxi_disable_secondary_cpus(u_register_t primary_mpidr);
-void __dead2 sunxi_power_down(void);
+void sunxi_power_down(void);
int sunxi_pmic_setup(uint16_t socid, const void *fdt);
void sunxi_security_setup(void);
@@ -20,7 +20,6 @@ void sunxi_security_setup(void);
uint16_t sunxi_read_soc_id(void);
void sunxi_set_gpio_out(char port, int pin, bool level_high);
int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb);
-void sunxi_execute_arisc_code(uint32_t *code, size_t size,
- int patch_offset, uint16_t param);
+void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param);
#endif /* SUNXI_PRIVATE_H */
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c
index 3b44aab685..cff8268199 100644
--- a/plat/allwinner/common/sunxi_common.c
+++ b/plat/allwinner/common/sunxi_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -57,6 +57,10 @@ void sunxi_configure_mmu_el3(int flags)
mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE,
BL_RO_DATA_END - BL_RO_DATA_BASE,
MT_RO_DATA | MT_SECURE);
+ mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE,
+ BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
+ MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER);
+
mmap_add(sunxi_mmap);
init_xlat_tables();
@@ -150,16 +154,16 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb)
/* set both pins to pull-up */
mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U);
- /* assert, then de-assert reset of I2C/RSB controller */
- mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
- mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
-
/* un-gate clock */
if (socid != SUNXI_SOC_H6)
mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit);
else
mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0));
+ /* assert, then de-assert reset of I2C/RSB controller */
+ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+ mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit);
+
return 0;
}
@@ -172,8 +176,7 @@ DEFINE_BAKERY_LOCK(arisc_lock);
* in SRAM, put the address of that into the reset vector and release the
* arisc reset line. The SCP will execute that code and pull the line up again.
*/
-void sunxi_execute_arisc_code(uint32_t *code, size_t size,
- int patch_offset, uint16_t param)
+void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param)
{
uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100;
@@ -187,8 +190,7 @@ void sunxi_execute_arisc_code(uint32_t *code, size_t size,
} while (1);
/* Patch up the code to feed in an input parameter. */
- if (patch_offset >= 0 && patch_offset <= (size - 4))
- code[patch_offset] = (code[patch_offset] & ~0xffff) | param;
+ code[0] = (code[0] & ~0xffff) | param;
clean_dcache_range((uintptr_t)code, size);
/*
diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c
index b4c9fcc189..6e29b69bfc 100644
--- a/plat/allwinner/common/sunxi_cpu_ops.c
+++ b/plat/allwinner/common/sunxi_cpu_ops.c
@@ -78,7 +78,7 @@ void sunxi_cpu_off(u_register_t mpidr)
* patched into the first instruction.
*/
sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off),
- 0, BIT_32(core));
+ BIT_32(core));
}
void sunxi_cpu_on(u_register_t mpidr)
diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c
index 13e1353258..9b074d2acd 100644
--- a/plat/allwinner/common/sunxi_pm.c
+++ b/plat/allwinner/common/sunxi_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -65,6 +65,11 @@ static void __dead2 sunxi_system_off(void)
sunxi_disable_secondary_cpus(read_mpidr());
sunxi_power_down();
+
+ udelay(1000);
+ ERROR("PSCI: Cannot turn off system, halting\n");
+ wfi();
+ panic();
}
static void __dead2 sunxi_system_reset(void)
diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk
index b46fbc2d1a..f6d5aa9f84 100644
--- a/plat/allwinner/sun50i_a64/platform.mk
+++ b/plat/allwinner/sun50i_a64/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,4 +7,5 @@
# The differences between the platform are covered by the include files.
include plat/allwinner/common/allwinner-common.mk
-PLAT_BL_COMMON_SOURCES += drivers/allwinner/sunxi_rsb.c
+BL31_SOURCES += drivers/allwinner/axp/axp803.c \
+ drivers/allwinner/sunxi_rsb.c
diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c
index 07a37167ff..5b7d76ae91 100644
--- a/plat/allwinner/sun50i_a64/sunxi_power.c
+++ b/plat/allwinner/sun50i_a64/sunxi_power.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -7,14 +7,11 @@
#include <errno.h>
-#include <libfdt.h>
-
#include <platform_def.h>
-#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
#include <drivers/allwinner/sunxi_rsb.h>
-#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <sunxi_def.h>
@@ -22,6 +19,7 @@
#include <sunxi_private.h>
static enum pmic_type {
+ UNKNOWN,
GENERIC_H5,
GENERIC_A64,
REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */
@@ -38,7 +36,7 @@ static enum pmic_type {
* disabled.
* This function only cares about peripherals.
*/
-void sunxi_turn_off_soc(uint16_t socid)
+static void sunxi_turn_off_soc(uint16_t socid)
{
int i;
@@ -113,174 +111,22 @@ static int rsb_init(void)
return ret;
/* Associate the 8-bit runtime address with the 12-bit bus address. */
- return rsb_assign_runtime_address(AXP803_HW_ADDR,
- AXP803_RT_ADDR);
-}
-
-static int axp_write(uint8_t reg, uint8_t val)
-{
- return rsb_write(AXP803_RT_ADDR, reg, val);
-}
-
-static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask)
-{
- uint8_t regval;
- int ret;
-
- ret = rsb_read(AXP803_RT_ADDR, reg);
- if (ret < 0)
+ ret = rsb_assign_runtime_address(AXP803_HW_ADDR,
+ AXP803_RT_ADDR);
+ if (ret)
return ret;
- regval = (ret & ~clr_mask) | set_mask;
-
- return rsb_write(AXP803_RT_ADDR, reg, regval);
+ return axp_check_id();
}
-#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0)
-#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask)
-
-static bool should_enable_regulator(const void *fdt, int node)
+int axp_read(uint8_t reg)
{
- if (fdt_getprop(fdt, node, "phandle", NULL) != NULL)
- return true;
- if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL)
- return true;
- return false;
+ return rsb_read(AXP803_RT_ADDR, reg);
}
-/*
- * Retrieve the voltage from a given regulator DTB node.
- * Both the regulator-{min,max}-microvolt properties must be present and
- * have the same value. Return that value in millivolts.
- */
-static int fdt_get_regulator_millivolt(const void *fdt, int node)
-{
- const fdt32_t *prop;
- uint32_t min_volt;
-
- prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL);
- if (prop == NULL)
- return -EINVAL;
- min_volt = fdt32_to_cpu(*prop);
-
- prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL);
- if (prop == NULL)
- return -EINVAL;
-
- if (fdt32_to_cpu(*prop) != min_volt)
- return -EINVAL;
-
- return min_volt / 1000;
-}
-
-#define NO_SPLIT 0xff
-
-static const struct axp_regulator {
- char *dt_name;
- uint16_t min_volt;
- uint16_t max_volt;
- uint16_t step;
- unsigned char split;
- unsigned char volt_reg;
- unsigned char switch_reg;
- unsigned char switch_bit;
-} regulators[] = {
- {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0},
- {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4},
- {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5},
- {"dldo1", 700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3},
- {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4},
- {"dldo3", 700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5},
- {"fldo1", 700, 1450, 50, NO_SPLIT, 0x1c, 0x13, 2},
- {}
-};
-
-static int setup_regulator(const void *fdt, int node,
- const struct axp_regulator *reg)
+int axp_write(uint8_t reg, uint8_t val)
{
- int mvolt;
- uint8_t regval;
-
- if (!should_enable_regulator(fdt, node))
- return -ENOENT;
-
- mvolt = fdt_get_regulator_millivolt(fdt, node);
- if (mvolt < reg->min_volt || mvolt > reg->max_volt)
- return -EINVAL;
-
- regval = (mvolt / reg->step) - (reg->min_volt / reg->step);
- if (regval > reg->split)
- regval = ((regval - reg->split) / 2) + reg->split;
-
- axp_write(reg->volt_reg, regval);
- if (reg->switch_reg < 0xff)
- axp_setbits(reg->switch_reg, BIT(reg->switch_bit));
-
- INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name,
- mvolt / 1000, mvolt % 1000);
-
- return 0;
-}
-
-static void setup_axp803_rails(const void *fdt)
-{
- int node;
- bool dc1sw = false;
-
- /* locate the PMIC DT node, bail out if not found */
- node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803");
- if (node < 0) {
- WARN("BL31: PMIC: Cannot find AXP803 DT node, skipping initial setup.\n");
- return;
- }
-
- if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) {
- axp_clrbits(0x8f, BIT(4));
- axp_setbits(0x30, BIT(2));
- INFO("PMIC: AXP803: Enabling DRIVEVBUS\n");
- }
-
- /* descend into the "regulators" subnode */
- node = fdt_subnode_offset(fdt, node, "regulators");
- if (node < 0) {
- WARN("BL31: PMIC: Cannot find regulators subnode, skipping initial setup.\n");
- return;
- }
-
- /* iterate over all regulators to find used ones */
- for (node = fdt_first_subnode(fdt, node);
- node >= 0;
- node = fdt_next_subnode(fdt, node)) {
- const struct axp_regulator *reg;
- const char *name;
- int length;
-
- /* We only care if it's always on or referenced. */
- if (!should_enable_regulator(fdt, node))
- continue;
-
- name = fdt_get_name(fdt, node, &length);
- for (reg = regulators; reg->dt_name; reg++) {
- if (!strncmp(name, reg->dt_name, length)) {
- setup_regulator(fdt, node, reg);
- break;
- }
- }
-
- if (!strncmp(name, "dc1sw", length)) {
- /* Delay DC1SW enablement to avoid overheating. */
- dc1sw = true;
- continue;
- }
- }
- /*
- * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts
- * down. So always enable DC1SW as the very last regulator.
- */
- if (dc1sw) {
- INFO("PMIC: AXP803: Enabling DC1SW\n");
- axp_setbits(0x12, BIT(7));
- }
+ return rsb_write(AXP803_RT_ADDR, reg, val);
}
int sunxi_pmic_setup(uint16_t socid, const void *fdt)
@@ -289,11 +135,16 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
switch (socid) {
case SUNXI_SOC_H5:
+ NOTICE("PMIC: Assuming H5 reference regulator design\n");
+
pmic = REF_DESIGN_H5;
- NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n");
+
break;
case SUNXI_SOC_A64:
pmic = GENERIC_A64;
+
+ INFO("PMIC: Probing AXP803 on RSB\n");
+
ret = sunxi_init_platform_r_twi(socid, true);
if (ret)
return ret;
@@ -303,20 +154,16 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
return ret;
pmic = AXP803_RSB;
- NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n");
-
- if (fdt)
- setup_axp803_rails(fdt);
+ axp_setup_regulators(fdt);
break;
default:
- NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid);
return -ENODEV;
}
return 0;
}
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
{
switch (pmic) {
case GENERIC_H5:
@@ -354,16 +201,10 @@ void __dead2 sunxi_power_down(void)
/* (Re-)init RSB in case the rich OS has disabled it. */
sunxi_init_platform_r_twi(SUNXI_SOC_A64, true);
rsb_init();
-
- /* Set "power disable control" bit */
- axp_setbits(0x32, BIT(7));
+ axp_power_off();
break;
default:
break;
}
- udelay(1000);
- ERROR("PSCI: Cannot turn off system, halting.\n");
- wfi();
- panic();
}
diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk
index 5c21eadb2f..4ecc57cf07 100644
--- a/plat/allwinner/sun50i_h6/platform.mk
+++ b/plat/allwinner/sun50i_h6/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,4 +7,5 @@
# The differences between the platform are covered by the include files.
include plat/allwinner/common/allwinner-common.mk
-PLAT_BL_COMMON_SOURCES += drivers/mentor/i2c/mi2cv.c
+BL31_SOURCES += drivers/allwinner/axp/axp805.c \
+ drivers/mentor/i2c/mi2cv.c
diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c
index 5b5bad1771..443015bacf 100644
--- a/plat/allwinner/sun50i_h6/sunxi_power.c
+++ b/plat/allwinner/sun50i_h6/sunxi_power.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io>
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -10,6 +10,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <drivers/allwinner/axp.h>
#include <drivers/delay_timer.h>
#include <drivers/mentor/mi2cv.h>
#include <lib/mmio.h>
@@ -19,53 +20,51 @@
#include <sunxi_private.h>
#define AXP805_ADDR 0x36
-#define AXP805_ID 0x03
-enum pmic_type {
- NO_PMIC,
+static enum pmic_type {
+ UNKNOWN,
AXP805,
-};
+} pmic;
-enum pmic_type pmic;
-
-int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val)
+int axp_read(uint8_t reg)
{
+ uint8_t val;
int ret;
- ret = i2c_write(chip, 0, 0, &reg, 1);
- if (ret)
+ ret = i2c_write(AXP805_ADDR, 0, 0, &reg, 1);
+ if (ret == 0)
+ ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1);
+ if (ret) {
+ ERROR("PMIC: Cannot read AXP805 register %02x\n", reg);
return ret;
+ }
- return i2c_read(chip, 0, 0, val, 1);
+ return val;
}
-int axp_i2c_write(uint8_t chip, uint8_t reg, uint8_t val)
+int axp_write(uint8_t reg, uint8_t val)
{
- return i2c_write(chip, reg, 1, &val, 1);
+ int ret;
+
+ ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1);
+ if (ret)
+ ERROR("PMIC: Cannot write AXP805 register %02x\n", reg);
+
+ return ret;
}
static int axp805_probe(void)
{
int ret;
- uint8_t val;
- ret = axp_i2c_write(AXP805_ADDR, 0xff, 0x0);
- if (ret) {
- ERROR("PMIC: Cannot put AXP805 to master mode.\n");
- return -EPERM;
- }
-
- ret = axp_i2c_read(AXP805_ADDR, AXP805_ID, &val);
+ /* Switch the AXP805 to master/single-PMIC mode. */
+ ret = axp_write(0xff, 0x0);
+ if (ret)
+ return ret;
- if (!ret && ((val & 0xcf) == 0x40))
- NOTICE("PMIC: AXP805 detected\n");
- else if (ret) {
- ERROR("PMIC: Cannot communicate with AXP805.\n");
- return -EPERM;
- } else {
- ERROR("PMIC: Non-AXP805 chip attached at AXP805's address.\n");
- return -EINVAL;
- }
+ ret = axp_check_id();
+ if (ret)
+ return ret;
return 0;
}
@@ -74,41 +73,36 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt)
{
int ret;
- sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ INFO("PMIC: Probing AXP805 on I2C\n");
+
+ ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
+ if (ret)
+ return ret;
+
/* initialise mi2cv driver */
i2c_init((void *)SUNXI_R_I2C_BASE);
- NOTICE("PMIC: Probing AXP805\n");
- pmic = AXP805;
-
ret = axp805_probe();
if (ret)
- pmic = NO_PMIC;
- else
- pmic = AXP805;
+ return ret;
+
+ pmic = AXP805;
+ axp_setup_regulators(fdt);
return 0;
}
-void __dead2 sunxi_power_down(void)
+void sunxi_power_down(void)
{
- uint8_t val;
-
switch (pmic) {
case AXP805:
/* Re-initialise after rich OS might have used it. */
sunxi_init_platform_r_twi(SUNXI_SOC_H6, false);
/* initialise mi2cv driver */
i2c_init((void *)SUNXI_R_I2C_BASE);
- axp_i2c_read(AXP805_ADDR, 0x32, &val);
- axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80);
+ axp_power_off();
break;
default:
break;
}
-
- udelay(1000);
- ERROR("PSCI: Cannot communicate with PMIC, halting\n");
- wfi();
- panic();
}
diff --git a/plat/arm/board/a5ds/a5ds_common.c b/plat/arm/board/a5ds/a5ds_common.c
index e462fa16e5..a4a0cff929 100644
--- a/plat/arm/board/a5ds/a5ds_common.c
+++ b/plat/arm/board/a5ds/a5ds_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,18 +23,18 @@
#ifdef IMAGE_BL1
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
- MAP_FLASH1_RW,
MAP_PERIPHBASE,
MAP_A5_PERIPHERALS,
+ MAP_BOOT_RW,
{0}
};
#endif
#ifdef IMAGE_BL2
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
- MAP_FLASH1_RW,
MAP_PERIPHBASE,
MAP_A5_PERIPHERALS,
+ MAP_BOOT_RW,
ARM_MAP_NS_DRAM1,
{0}
};
diff --git a/plat/arm/board/a5ds/a5ds_pm.c b/plat/arm/board/a5ds/a5ds_pm.c
index cc734b0054..7774002e6b 100644
--- a/plat/arm/board/a5ds/a5ds_pm.c
+++ b/plat/arm/board/a5ds/a5ds_pm.c
@@ -4,11 +4,10 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
-
+#include <drivers/arm/gicv2.h>
#include <lib/psci/psci.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <drivers/arm/gicv2.h>
/*******************************************************************************
* Platform handler called when a power domain is about to be turned on. The
diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
index 9ab2d96566..7b3aa11448 100644
--- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
+++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,7 @@
/* Platform Config */
plat_arm_bl2 {
compatible = "arm,tb_fw";
- hw_config_addr = <0x0 0x82000000>;
+ hw_config_addr = <0x0 0x83000000>;
hw_config_max_size = <0x01000000>;
/* Disable authentication for development */
disable_auth = <0x0>;
diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h
index e9e4b9aef7..31dfb1cf16 100644
--- a/plat/arm/board/a5ds/include/platform_def.h
+++ b/plat/arm/board/a5ds/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,14 +21,6 @@
#define ARM_DRAM1_END (ARM_DRAM1_BASE + \
ARM_DRAM1_SIZE - 1)
-#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE
-/*
- * The last 2MB is meant to be NOLOAD and will not be zero
- * initialized.
- */
-#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
- 0x00200000)
-
#define SRAM_BASE 0x2000000
#define SRAM_SIZE 0x200000
@@ -47,7 +39,7 @@
#define A5_PERIPHERALS_BASE 0x1c000000
#define A5_PERIPHERALS_SIZE 0x10000
-#define ARM_CACHE_WRITEBACK_SHIFT 6
+#define ARM_CACHE_WRITEBACK_SHIFT 5
#define ARM_IRQ_SEC_PHY_TIMER 29
@@ -89,28 +81,34 @@
#define A5DS_IRQ_SEC_SYS_TIMER 57
/* Default cluster count for A5DS */
-#define A5DS_CLUSTER_COUNT 1
+#define A5DS_CLUSTER_COUNT U(1)
/* Default number of CPUs per cluster on A5DS */
-#define A5DS_MAX_CPUS_PER_CLUSTER 4
+#define A5DS_MAX_CPUS_PER_CLUSTER U(4)
/* Default number of threads per CPU on A5DS */
-#define A5DS_MAX_PE_PER_CPU 1
+#define A5DS_MAX_PE_PER_CPU U(1)
-#define A5DS_CORE_COUNT 4
+#define A5DS_CORE_COUNT U(4)
#define A5DS_PRIMARY_CPU 0x0
-#define FLASH1_BASE UL(0x8000000)
-#define FLASH1_SIZE UL(0x2800000)
+#define BOOT_BASE ARM_DRAM1_BASE
+#define BOOT_SIZE UL(0x2800000)
-#define MAP_FLASH1_RW MAP_REGION_FLAT(FLASH1_BASE,\
- FLASH1_SIZE, \
- MT_DEVICE | MT_RW | MT_SECURE)
+#define ARM_NS_DRAM1_BASE (ARM_DRAM1_BASE + BOOT_SIZE)
+/*
+ * The last 2MB is meant to be NOLOAD and will not be zero
+ * initialized.
+ */
+#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \
+ BOOT_SIZE - \
+ 0x00200000)
-#define MAP_FLASH1_RO MAP_REGION_FLAT(FLASH1_BASE,\
- FLASH1_SIZE, \
- MT_RO_DATA | MT_SECURE)
+#define MAP_BOOT_RW MAP_REGION_FLAT( \
+ BOOT_BASE, \
+ BOOT_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \
A5DS_SHARED_RAM_BASE, \
@@ -122,9 +120,9 @@
ARM_NS_DRAM1_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
-#define ARM_MAP_SRAM MAP_REGION_FLAT( \
- SRAM_BASE, \
- SRAM_SIZE, \
+#define ARM_MAP_SRAM MAP_REGION_FLAT( \
+ SRAM_BASE, \
+ SRAM_SIZE, \
MT_MEMORY | MT_RW | MT_NS)
/*
@@ -162,7 +160,7 @@
ARM_BL_REGIONS)
/* Memory mapped Generic timer interfaces */
-#define A5DS_TIMER_BASE_FREQUENCY UL(24000000)
+#define A5DS_TIMER_BASE_FREQUENCY UL(7500000)
#define ARM_CONSOLE_BAUDRATE 115200
@@ -231,7 +229,7 @@
/* Required platform porting definitions */
#define PLATFORM_CORE_COUNT A5DS_CORE_COUNT
#define PLAT_NUM_PWR_DOMAINS (A5DS_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT) + 1
+ PLATFORM_CORE_COUNT) + U(1)
#define PLAT_MAX_PWR_LVL 2
@@ -300,25 +298,25 @@
#define MAX_IO_HANDLES 4
/* Reserve the last block of flash for PSCI MEM PROTECT flag */
-#define PLAT_ARM_FIP_BASE FLASH1_BASE
-#define PLAT_ARM_FIP_MAX_SIZE (FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_FIP_BASE BOOT_BASE
+#define PLAT_ARM_FIP_MAX_SIZE (BOOT_SIZE - V2M_FLASH_BLOCK_SIZE)
-#define PLAT_ARM_NVM_BASE FLASH1_BASE
-#define PLAT_ARM_NVM_SIZE (FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE)
+#define PLAT_ARM_NVM_BASE BOOT_BASE
+#define PLAT_ARM_NVM_SIZE (BOOT_SIZE - V2M_FLASH_BLOCK_SIZE)
/*
* PL011 related constants
*/
#define PLAT_ARM_BOOT_UART_BASE 0x1A200000
-#define PLAT_ARM_BOOT_UART_CLK_IN_HZ 24000000
+#define PLAT_ARM_BOOT_UART_CLK_IN_HZ UL(7500000)
#define PLAT_ARM_RUN_UART_BASE 0x1A210000
-#define PLAT_ARM_RUN_UART_CLK_IN_HZ 24000000
+#define PLAT_ARM_RUN_UART_CLK_IN_HZ UL(7500000)
#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE
#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ
-#define A5DS_TIMER_BASE_FREQUENCY UL(24000000)
+#define A5DS_TIMER_BASE_FREQUENCY UL(7500000)
/* System timer related constants */
#define PLAT_ARM_NSTIMER_FRAME_ID 1
@@ -334,6 +332,9 @@
#define A5DS_HOLD_STATE_WAIT 0
#define A5DS_HOLD_STATE_GO 1
+/* Snoop Control Unit base address */
+#define A5DS_SCU_BASE 0x1C000000
+
/*
* GIC related constants to cater for GICv2
*/
diff --git a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
index 8b45af85b9..a951dc7b4e 100644
--- a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
+++ b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c
@@ -4,12 +4,17 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <drivers/arm/scu.h>
#include <plat/arm/common/plat_arm.h>
+
void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
+
+ /* enable snoop control unit */
+ enable_snoop_ctrl_unit(A5DS_SCU_BASE);
}
/*
diff --git a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
index da1d785c2a..4b0c97dfd3 100644
--- a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
+++ b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk
@@ -5,7 +5,8 @@
#
# SP_MIN source files specific to A5DS platform
-BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \
+BL32_SOURCES += drivers/arm/scu/scu.c \
+ drivers/cfi/v2m/v2m_flash.c \
lib/utils/mem_region.c \
lib/aarch32/arm32_aeabi_divmod.c \
lib/aarch32/arm32_aeabi_divmod_a32.S \
diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h
index de99b06ad8..8dff3ec3fb 100644
--- a/plat/arm/board/corstone700/include/platform_def.h
+++ b/plat/arm/board/corstone700/include/platform_def.h
@@ -14,9 +14,9 @@
#include <plat/common/common_def.h>
/* Core/Cluster/Thread counts for Corstone700 */
-#define CORSTONE700_CLUSTER_COUNT 1
-#define CORSTONE700_MAX_CPUS_PER_CLUSTER 4
-#define CORSTONE700_MAX_PE_PER_CPU 1
+#define CORSTONE700_CLUSTER_COUNT U(1)
+#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4)
+#define CORSTONE700_MAX_PE_PER_CPU U(1)
#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \
CORSTONE700_MAX_CPUS_PER_CLUSTER * \
CORSTONE700_MAX_PE_PER_CPU)
diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c
index a94879624f..ffaa93de4d 100644
--- a/plat/arm/board/fvp/fvp_common.c
+++ b/plat/arm/board/fvp/fvp_common.c
@@ -18,7 +18,7 @@
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
#include "fvp_private.h"
@@ -96,12 +96,9 @@ const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_BL1_RW,
#endif
#endif /* TRUSTED_BOARD_BOOT */
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
ARM_SP_IMAGE_MMAP,
#endif
-#if ENABLE_SPM && !SPM_MM
- PLAT_MAP_SP_PACKAGE_MEM_RW,
-#endif
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
@@ -122,21 +119,22 @@ const mmap_region_t plat_arm_mmap[] = {
#ifdef IMAGE_BL31
const mmap_region_t plat_arm_mmap[] = {
ARM_MAP_SHARED_RAM,
+#if USE_DEBUGFS
+ /* Required by devfip, can be removed if devfip is not used */
+ V2M_MAP_FLASH0_RW,
+#endif /* USE_DEBUGFS */
ARM_MAP_EL3_TZC_DRAM,
V2M_MAP_IOFPGA,
MAP_DEVICE0,
MAP_DEVICE1,
ARM_V2M_MAP_MEM_PROTECT,
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
-#if ENABLE_SPM && !SPM_MM
- PLAT_MAP_SP_PACKAGE_MEM_RO,
-#endif
{0}
};
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
+#if defined(IMAGE_BL31) && SPM_MM
const mmap_region_t plat_arm_secure_partition_mmap[] = {
V2M_MAP_IOFPGA_EL0, /* for the UART */
MAP_REGION_FLAT(DEVICE0_BASE, \
@@ -190,12 +188,12 @@ static unsigned int get_interconnect_master(void)
}
#endif
-#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM
+#if defined(IMAGE_BL31) && SPM_MM
/*
* 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[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
[0] = {0x80000000, 0},
[1] = {0x80000001, 0},
[2] = {0x80000002, 0},
@@ -206,10 +204,10 @@ static secure_partition_mp_info_t sp_mp_info[] = {
[7] = {0x80000103, 0},
};
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_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.size = sizeof(spm_mm_boot_info_t),
.h.attr = 0,
.sp_mem_base = ARM_SP_IMAGE_BASE,
.sp_mem_limit = ARM_SP_IMAGE_LIMIT,
@@ -233,7 +231,7 @@ 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(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
void *cookie)
{
return &plat_arm_secure_partition_boot_info;
diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h
index 1b9f84b001..347ba2e1e6 100644
--- a/plat/arm/board/fvp/fvp_def.h
+++ b/plat/arm/board/fvp/fvp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,15 +10,15 @@
#include <lib/utils_def.h>
#ifndef FVP_CLUSTER_COUNT
-#define FVP_CLUSTER_COUNT 2
+#error "FVP_CLUSTER_COUNT is not set in makefile"
#endif
#ifndef FVP_MAX_CPUS_PER_CLUSTER
-#define FVP_MAX_CPUS_PER_CLUSTER 4
+#error "FVP_MAX_CPUS_PER_CLUSTER is not set in makefile"
#endif
#ifndef FVP_MAX_PE_PER_CPU
-# define FVP_MAX_PE_PER_CPU 1
+#error "FVP_MAX_PE_PER_CPU is not set in makefile"
#endif
#define FVP_PRIMARY_CPU 0x0
diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S
index f024f551ae..7c8bf06550 100644
--- a/plat/arm/board/fvp/include/plat.ld.S
+++ b/plat/arm/board/fvp/include/plat.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,9 @@
#define PLAT_LD_S
#include <plat/arm/common/arm_tzc_dram.ld.S>
+
+#if RECLAIM_INIT_CODE
#include <plat/arm/common/arm_reclaim_init.ld.S>
+#endif /* RECLAIM_INIT_CODE */
#endif /* PLAT_LD_S */
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index 98dd0a97f7..c2b7b98d4d 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -17,11 +17,12 @@
#include "../fvp_def.h"
/* Required platform porting definitions */
-#define PLATFORM_CORE_COUNT \
- (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)
+#define PLATFORM_CORE_COUNT (U(FVP_CLUSTER_COUNT) * \
+ U(FVP_MAX_CPUS_PER_CLUSTER) * \
+ U(FVP_MAX_PE_PER_CPU))
-#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT) + 1
+#define PLAT_NUM_PWR_DOMAINS (U(FVP_CLUSTER_COUNT) + \
+ PLATFORM_CORE_COUNT + U(1))
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
@@ -32,7 +33,7 @@
/*
* Required ARM standard platform porting definitions
*/
-#define PLAT_ARM_CLUSTER_COUNT FVP_CLUSTER_COUNT
+#define PLAT_ARM_CLUSTER_COUNT U(FVP_CLUSTER_COUNT)
#define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */
@@ -61,14 +62,18 @@
* plat_arm_mmap array defined for each BL stage.
*/
#if defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES 9
# define MAX_XLAT_TABLES 9
# define PLAT_SP_IMAGE_MMAP_REGIONS 30
# define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10
# else
# define PLAT_ARM_MMAP_ENTRIES 8
-# define MAX_XLAT_TABLES 5
+# if USE_DEBUGFS
+# define MAX_XLAT_TABLES 6
+# else
+# define MAX_XLAT_TABLES 5
+# endif
# endif
#elif defined(IMAGE_BL32)
# define PLAT_ARM_MMAP_ENTRIES 8
@@ -116,11 +121,7 @@
* calculated using the current BL31 PROGBITS debug size plus the sizes of
* BL2 and BL1-RW
*/
-#if ENABLE_SPM && !SPM_MM
-#define PLAT_ARM_MAX_BL31_SIZE UL(0x60000)
-#else
#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000)
-#endif
#ifndef __aarch64__
/*
diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk
index 3a9972bb4b..97a326c092 100644
--- a/plat/arm/board/fvp/platform.mk
+++ b/plat/arm/board/fvp/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -245,10 +245,12 @@ ENABLE_AMU := 1
DYNAMIC_WORKAROUND_CVE_2018_3639 := 1
# Enable reclaiming of BL31 initialisation code for secondary cores
-# stacks for FVP.
+# stacks for FVP. However, don't enable reclaiming for clang.
ifneq (${RESET_TO_BL31},1)
+ifeq ($(findstring clang,$(notdir $(CC))),)
RECLAIM_INIT_CODE := 1
endif
+endif
ifeq (${ENABLE_AMU},1)
BL31_SOURCES += lib/cpus/aarch64/cpuamu.c \
@@ -281,16 +283,15 @@ else # if AArch64
ifeq (${RESET_TO_BL31},1)
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
- ifeq (${ENABLE_SPM},1)
- ifeq (${SPM_MM},0)
- BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
- endif
- endif
ifeq (${SPD},trusty)
BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
endif
endif
+ifeq (${USE_DEBUGFS},1)
+ BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1
+endif
+
# Add support for platform supplied linker script for BL31 build
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
diff --git a/plat/arm/board/fvp_ve/fvp_ve_def.h b/plat/arm/board/fvp_ve/fvp_ve_def.h
index 565753ae79..98de5f66e0 100644
--- a/plat/arm/board/fvp_ve/fvp_ve_def.h
+++ b/plat/arm/board/fvp_ve/fvp_ve_def.h
@@ -10,17 +10,17 @@
#include <lib/utils_def.h>
/* Default cluster count for FVP VE */
-#define FVP_VE_CLUSTER_COUNT 1
+#define FVP_VE_CLUSTER_COUNT U(1)
/* Default number of CPUs per cluster on FVP VE */
-#define FVP_VE_MAX_CPUS_PER_CLUSTER 1
+#define FVP_VE_MAX_CPUS_PER_CLUSTER U(1)
/* Default number of threads per CPU on FVP VE */
-#define FVP_VE_MAX_PE_PER_CPU 1
+#define FVP_VE_MAX_PE_PER_CPU U(1)
-#define FVP_VE_CORE_COUNT 1
+#define FVP_VE_CORE_COUNT U(1)
-#define FVP_VE_PRIMARY_CPU 0x0
+#define FVP_VE_PRIMARY_CPU 0x0
/*******************************************************************************
* FVP memory map related constants
diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h
index 4e575e1ab0..1b07a9b421 100644
--- a/plat/arm/board/fvp_ve/include/platform_def.h
+++ b/plat/arm/board/fvp_ve/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -211,9 +211,9 @@
#define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE)
/* Required platform porting definitions */
-#define PLATFORM_CORE_COUNT 1
+#define PLATFORM_CORE_COUNT FVP_VE_CLUSTER_COUNT
#define PLAT_NUM_PWR_DOMAINS ((FVP_VE_CLUSTER_COUNT + \
- PLATFORM_CORE_COUNT) + 1)
+ PLATFORM_CORE_COUNT) + U(1))
#define PLAT_MAX_PWR_LVL 2
diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h
index 7a8bedf5ab..3b34a9f6a9 100644
--- a/plat/arm/board/juno/juno_def.h
+++ b/plat/arm/board/juno/juno_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,9 +32,9 @@
/*******************************************************************************
* Juno topology related constants
******************************************************************************/
-#define JUNO_CLUSTER_COUNT 2
-#define JUNO_CLUSTER0_CORE_COUNT 2
-#define JUNO_CLUSTER1_CORE_COUNT 4
+#define JUNO_CLUSTER_COUNT U(2)
+#define JUNO_CLUSTER0_CORE_COUNT U(2)
+#define JUNO_CLUSTER1_CORE_COUNT U(4)
/*******************************************************************************
* TZC-400 related constants
diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h
index 50b04f0494..2be3f8852f 100644
--- a/plat/arm/board/rde1edge/include/platform_def.h
+++ b/plat/arm/board/rde1edge/include/platform_def.h
@@ -11,9 +11,9 @@
#include <sgi_base_platform_def.h>
-#define PLAT_ARM_CLUSTER_COUNT 2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER 8
-#define CSS_SGI_MAX_PE_PER_CPU 2
+#define PLAT_ARM_CLUSTER_COUNT U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(8)
+#define CSS_SGI_MAX_PE_PER_CPU U(2)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h
index 580ab8e6f1..c635faa441 100644
--- a/plat/arm/board/rdn1edge/include/platform_def.h
+++ b/plat/arm/board/rdn1edge/include/platform_def.h
@@ -11,9 +11,9 @@
#include <sgi_base_platform_def.h>
-#define PLAT_ARM_CLUSTER_COUNT 2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
-#define CSS_SGI_MAX_PE_PER_CPU 1
+#define PLAT_ARM_CLUSTER_COUNT U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45400000)
#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h
index f00146f99f..fd59e5277e 100644
--- a/plat/arm/board/sgi575/include/platform_def.h
+++ b/plat/arm/board/sgi575/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,9 +11,9 @@
#include <sgi_base_platform_def.h>
-#define PLAT_ARM_CLUSTER_COUNT 2
-#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4
-#define CSS_SGI_MAX_PE_PER_CPU 1
+#define PLAT_ARM_CLUSTER_COUNT U(2)
+#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4)
+#define CSS_SGI_MAX_PE_PER_CPU U(1)
#define PLAT_CSS_MHU_BASE UL(0x45000000)
#define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE
diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h
index 27d1b3304b..d165ff9ed0 100644
--- a/plat/arm/board/sgm775/include/platform_def.h
+++ b/plat/arm/board/sgm775/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -9,8 +9,8 @@
#include <sgm_base_platform_def.h>
-#define PLAT_MAX_CPUS_PER_CLUSTER 8
-#define PLAT_MAX_PE_PER_CPU 1
+#define PLAT_MAX_CPUS_PER_CLUSTER U(8)
+#define PLAT_MAX_PE_PER_CPU U(1)
/*
* Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes
diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c
index 4ae992c95e..69ebd798fb 100644
--- a/plat/arm/common/aarch64/arm_ehf.c
+++ b/plat/arm/common/aarch64/arm_ehf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -24,7 +24,7 @@ ehf_pri_desc_t arm_exceptions[] = {
/* Normal priority SDEI */
EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI),
#endif
-#if ENABLE_SPM
+#if SPM_MM
EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI),
#endif
};
diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c
index 00ac16ef06..8835fa1352 100644
--- a/plat/arm/common/execution_state_switch.c
+++ b/plat/arm/common/aarch64/execution_state_switch.c
@@ -39,8 +39,6 @@ int arm_execution_state_switch(unsigned int smc_fid,
uint32_t cookie_lo,
void *handle)
{
- /* Execution state can be switched only if EL3 is AArch64 */
-#ifdef __aarch64__
bool caller_64, thumb = false, from_el2;
unsigned int el, endianness;
u_register_t spsr, pc, scr, sctlr;
@@ -48,6 +46,11 @@ int arm_execution_state_switch(unsigned int smc_fid,
cpu_context_t *ctx = (cpu_context_t *) handle;
el3_state_t *el3_ctx = get_el3state_ctx(ctx);
+ /* Validate supplied entry point */
+ pc = (u_register_t) (((uint64_t) pc_hi << 32) | pc_lo);
+ if (arm_validate_ns_entrypoint(pc) != 0)
+ goto invalid_param;
+
/* That the SMC originated from NS is already validated by the caller */
/*
@@ -173,7 +176,6 @@ invalid_param:
SMC_RET1(handle, STATE_SW_E_PARAM);
exec_denied:
-#endif /* __aarch64__ */
/* State switch denied */
SMC_RET1(handle, STATE_SW_E_DENIED);
}
diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c
index ab90f46a89..939885f984 100644
--- a/plat/arm/common/arm_bl31_setup.c
+++ b/plat/arm/common/arm_bl31_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,6 +11,7 @@
#include <common/bl_common.h>
#include <common/debug.h>
#include <drivers/console.h>
+#include <lib/debugfs.h>
#include <lib/extensions/ras.h>
#include <lib/mmio.h>
#include <lib/utils.h>
@@ -231,6 +232,10 @@ void arm_bl31_platform_setup(void)
#if RAS_EXTENSION
ras_init();
#endif
+
+#if USE_DEBUGFS
+ debugfs_init();
+#endif /* USE_DEBUGFS */
}
/*******************************************************************************
diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c
index bc0cf9a857..03d842a511 100644
--- a/plat/arm/common/arm_common.c
+++ b/plat/arm/common/arm_common.c
@@ -16,7 +16,7 @@
#include <lib/xlat_tables/xlat_tables_compat.h>
#include <plat/arm/common/plat_arm.h>
#include <plat/common/platform.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
/* Weak definitions may be overridden in specific ARM standard platform */
#pragma weak plat_get_ns_image_entrypoint
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index acc3797977..9d4f05e9e3 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -215,13 +215,18 @@ BL2U_SOURCES += drivers/delay_timer/delay_timer.c \
BL31_SOURCES += plat/arm/common/arm_bl31_setup.c \
plat/arm/common/arm_pm.c \
plat/arm/common/arm_topology.c \
- plat/arm/common/execution_state_switch.c \
plat/common/plat_psci_common.c
ifeq (${ENABLE_PMF}, 1)
-BL31_SOURCES += plat/arm/common/arm_sip_svc.c \
+ifeq (${ARCH}, aarch64)
+BL31_SOURCES += plat/arm/common/aarch64/execution_state_switch.c\
+ plat/arm/common/arm_sip_svc.c \
+ lib/pmf/pmf_smc.c
+else
+BL32_SOURCES += plat/arm/common/arm_sip_svc.c \
lib/pmf/pmf_smc.c
endif
+endif
ifeq (${EL3_EXCEPTION_HANDLING},1)
BL31_SOURCES += plat/arm/common/aarch64/arm_ehf.c
@@ -243,16 +248,6 @@ PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \
lib/extensions/pauth/pauth_helpers.S
endif
-# SPM uses libfdt in Arm platforms
-ifeq (${SPM_MM},0)
-ifeq (${ENABLE_SPM},1)
-BL31_SOURCES += common/fdt_wrappers.c \
- plat/common/plat_spm_rd.c \
- plat/common/plat_spm_sp.c \
- ${LIBFDT_SRCS}
-endif
-endif
-
ifneq (${TRUSTED_BOARD_BOOT},0)
# Include common TBB sources
diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c
index 9a53649520..e6c5a73615 100644
--- a/plat/arm/common/arm_dyn_cfg.c
+++ b/plat/arm/common/arm_dyn_cfg.c
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <assert.h>
#include <string.h>
+#include <libfdt.h>
#include <platform_def.h>
@@ -21,8 +22,6 @@
/* Variable to store the address to TB_FW_CONFIG passed from BL1 */
static void *tb_fw_cfg_dtb;
-static size_t tb_fw_cfg_dtb_size;
-
#if TRUSTED_BOARD_BOOT
@@ -110,7 +109,7 @@ void arm_bl1_set_mbedtls_heap(void)
* without the heap info.
*/
flush_dcache_range((uintptr_t)tb_fw_cfg_dtb,
- tb_fw_cfg_dtb_size);
+ fdt_totalsize(tb_fw_cfg_dtb));
}
}
@@ -146,7 +145,6 @@ void arm_load_tb_fw_config(void)
/* At this point we know that a DTB is indeed available */
config_base = arm_tb_fw_info.image_info.image_base;
tb_fw_cfg_dtb = (void *)config_base;
- tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_info.image_max_size;
/* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */
desc = bl1_plat_get_image_desc(BL2_IMAGE_ID);
@@ -245,7 +243,8 @@ void arm_bl2_dyn_cfg_init(void)
#ifdef BL31_BASE
/* Ensure the configs don't overlap with BL31 */
- if ((image_base > BL31_BASE) || ((image_base + image_size) > BL31_BASE))
+ if ((image_base >= BL31_BASE) &&
+ (image_base <= BL31_LIMIT))
continue;
#endif
/* Ensure the configs are loaded in a valid address */
@@ -256,7 +255,8 @@ void arm_bl2_dyn_cfg_init(void)
* If BL32 is present, ensure that the configs don't
* overlap with it.
*/
- if (image_base >= BL32_BASE && image_base <= BL32_LIMIT)
+ if ((image_base >= BL32_BASE) &&
+ (image_base <= BL32_LIMIT))
continue;
#endif
}
@@ -265,7 +265,10 @@ void arm_bl2_dyn_cfg_init(void)
cfg_mem_params->image_info.image_base = (uintptr_t)image_base;
cfg_mem_params->image_info.image_max_size = image_size;
- /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */
+ /*
+ * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from
+ * HW_CONFIG or FW_CONFIG nodes
+ */
cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING;
}
diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c
index cfc535939c..4a3a22ec0b 100644
--- a/plat/arm/common/arm_gicv3.c
+++ b/plat/arm/common/arm_gicv3.c
@@ -44,12 +44,11 @@ static const interrupt_prop_t arm_interrupt_props[] = {
/*
* We save and restore the GICv3 context on system suspend. Allocate the
- * data in the designated EL3 Secure carve-out memory. The `volatile`
- * is used to prevent the compiler from removing the gicv3 contexts even
- * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it.
+ * data in the designated EL3 Secure carve-out memory. The `used` attribute
+ * is used to prevent the compiler from removing the gicv3 contexts.
*/
-static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram");
-static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram");
+static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram") __used;
+static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram") __used;
/* Define accessor function to get reference to the GICv3 context */
DEFINE_LOAD_SYM_ADDR(rdist_ctx)
diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c
index 3d308a3351..9f5d4557c6 100644
--- a/plat/arm/common/arm_sip_svc.c
+++ b/plat/arm/common/arm_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,6 +8,7 @@
#include <common/debug.h>
#include <common/runtime_svc.h>
+#include <lib/debugfs.h>
#include <lib/pmf/pmf.h>
#include <plat/arm/common/arm_sip_svc.h>
#include <plat/arm/common/plat_arm.h>
@@ -20,8 +21,18 @@ DEFINE_SVC_UUID2(arm_sip_svc_uid,
static int arm_sip_setup(void)
{
- if (pmf_setup() != 0)
+ if (pmf_setup() != 0) {
return 1;
+ }
+
+#if USE_DEBUGFS
+
+ if (debugfs_smc_setup() != 0) {
+ return 1;
+ }
+
+#endif /* USE_DEBUGFS */
+
return 0;
}
@@ -48,25 +59,33 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid,
handle, flags);
}
+#if USE_DEBUGFS
+
+ if (is_debugfs_fid(smc_fid)) {
+ return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+ }
+
+#endif /* USE_DEBUGFS */
+
switch (smc_fid) {
case ARM_SIP_SVC_EXE_STATE_SWITCH: {
- u_register_t pc;
-
+ /* Execution state can be switched only if EL3 is AArch64 */
+#ifdef __aarch64__
/* Allow calls from non-secure only */
if (!is_caller_non_secure(flags))
SMC_RET1(handle, STATE_SW_E_DENIED);
- /* Validate supplied entry point */
- pc = (u_register_t) ((x1 << 32) | (uint32_t) x2);
- if (arm_validate_ns_entrypoint(pc) != 0)
- SMC_RET1(handle, STATE_SW_E_PARAM);
-
/*
* Pointers used in execution state switch are all 32 bits wide
*/
return (uintptr_t) arm_execution_state_switch(smc_fid,
(uint32_t) x1, (uint32_t) x2, (uint32_t) x3,
(uint32_t) x4, handle);
+#else
+ /* State switch denied */
+ SMC_RET1(handle, STATE_SW_E_DENIED);
+#endif /* __aarch64__ */
}
case ARM_SIP_SVC_CALL_COUNT:
diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h
index a9cc852789..e21457304b 100644
--- a/plat/arm/css/sgi/include/sgi_base_platform_def.h
+++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -28,7 +28,7 @@
* plat_arm_mmap array defined for each BL stage.
*/
#if defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
# define PLAT_ARM_MMAP_ENTRIES 9
# define MAX_XLAT_TABLES 7
# define PLAT_SP_IMAGE_MMAP_REGIONS 7
@@ -101,7 +101,7 @@
#elif defined(IMAGE_BL2U)
# define PLATFORM_STACK_SIZE 0x400
#elif defined(IMAGE_BL31)
-# if ENABLE_SPM
+# if SPM_MM
# define PLATFORM_STACK_SIZE 0x500
# else
# define PLATFORM_STACK_SIZE 0x400
diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk
index b736b0bb6e..71601118f6 100644
--- a/plat/arm/css/sgi/sgi-common.mk
+++ b/plat/arm/css/sgi/sgi-common.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,8 +10,6 @@ CSS_ENT_BASE := plat/arm/css/sgi
RAS_EXTENSION := 0
-ENABLE_SPM := 0
-
SDEI_SUPPORT := 0
EL3_EXCEPTION_HANDLING := 0
diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c
index 3e207ecc2a..b611eaff54 100644
--- a/plat/arm/css/sgi/sgi_plat.c
+++ b/plat/arm/css/sgi/sgi_plat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -15,7 +15,7 @@
#include <plat/common/platform.h>
#include <drivers/arm/sbsa.h>
#include <sgi_base_platform_def.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
#define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\
V2M_FLASH0_SIZE, \
@@ -46,7 +46,7 @@ const mmap_region_t plat_arm_mmap[] = {
#if ARM_BL31_IN_DRAM
ARM_MAP_BL31_SEC_DRAM,
#endif
-#if ENABLE_SPM
+#if SPM_MM
ARM_SP_IMAGE_MMAP,
#endif
#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3
@@ -61,13 +61,13 @@ const mmap_region_t plat_arm_mmap[] = {
V2M_MAP_IOFPGA,
CSS_SGI_MAP_DEVICE,
SOC_CSS_MAP_DEVICE,
-#if ENABLE_SPM
+#if SPM_MM
ARM_SPM_BUF_EL3_MMAP,
#endif
{0}
};
-#if ENABLE_SPM && defined(IMAGE_BL31)
+#if SPM_MM && defined(IMAGE_BL31)
const mmap_region_t plat_arm_secure_partition_mmap[] = {
PLAT_ARM_SECURE_MAP_DEVICE,
ARM_SP_IMAGE_MMAP,
@@ -77,17 +77,17 @@ const mmap_region_t plat_arm_secure_partition_mmap[] = {
ARM_SPM_BUF_EL0_MMAP,
{0}
};
-#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
+#endif /* SPM_MM && defined(IMAGE_BL31) */
#endif
ARM_CASSERT_MMAP
-#if ENABLE_SPM && defined(IMAGE_BL31)
+#if SPM_MM && 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[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
[0] = {0x81000000, 0},
[1] = {0x81000100, 0},
[2] = {0x81000200, 0},
@@ -98,10 +98,10 @@ static secure_partition_mp_info_t sp_mp_info[] = {
[7] = {0x81010300, 0},
};
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_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.size = sizeof(spm_mm_boot_info_t),
.h.attr = 0,
.sp_mem_base = ARM_SP_IMAGE_BASE,
.sp_mem_limit = ARM_SP_IMAGE_LIMIT,
@@ -125,12 +125,12 @@ 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(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
void *cookie)
{
return &plat_arm_secure_partition_boot_info;
}
-#endif /* ENABLE_SPM && defined(IMAGE_BL31) */
+#endif /* SPM_MM && defined(IMAGE_BL31) */
#if TRUSTED_BOARD_BOOT
int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size)
diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c
index 0001ffdde9..f56544e72a 100644
--- a/plat/arm/css/sgi/sgi_ras.c
+++ b/plat/arm/css/sgi/sgi_ras.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,9 +12,8 @@
#include <lib/extensions/ras.h>
#include <plat/arm/common/arm_spm_def.h>
#include <plat/common/platform.h>
-#include <services/mm_svc.h>
#include <services/sdei.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_svc.h>
#include <sgi_ras.h>
@@ -142,11 +141,11 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec,
sizeof(ras_map->ras_ev_num));
header->message_len = 4;
- spm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
- plat_my_core_pos());
+ spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0,
+ plat_my_core_pos());
/*
- * Do an EOI of the RAS interuupt. This allows the
+ * Do an EOI of the RAS interrupt. This allows the
* sdei event to be dispatched at the SDEI event's
* priority.
*/
diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h
index f349c196dd..24bbed513f 100644
--- a/plat/arm/css/sgm/include/sgm_base_platform_def.h
+++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,8 +17,8 @@
#include <plat/common/common_def.h>
/* CPU topology */
-#define PLAT_ARM_CLUSTER_COUNT 1
-#define PLAT_ARM_CLUSTER_CORE_COUNT 8
+#define PLAT_ARM_CLUSTER_COUNT U(1)
+#define PLAT_ARM_CLUSTER_CORE_COUNT U(8)
#define PLATFORM_CORE_COUNT PLAT_ARM_CLUSTER_CORE_COUNT
#define PLAT_MAX_PWR_LVL ARM_PWR_LVL2
diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c
index 16bec7972a..80ed8198b2 100644
--- a/plat/common/plat_psci_common.c
+++ b/plat/common/plat_psci_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -31,6 +31,8 @@
#define PSCI_STAT_ID_EXIT_LOW_PWR 1
#define PSCI_STAT_TOTAL_IDS 2
+PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc)
+PMF_DECLARE_GET_TIMESTAMP(psci_svc)
PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS,
PMF_STORE_ENABLE)
@@ -92,7 +94,7 @@ void plat_psci_stat_accounting_stop(
*/
u_register_t plat_psci_stat_get_residency(unsigned int lvl,
const psci_power_state_t *state_info,
- int last_cpu_idx)
+ unsigned int last_cpu_idx)
{
plat_local_state_t state;
unsigned long long pwrup_ts = 0, pwrdn_ts = 0;
@@ -103,7 +105,7 @@ u_register_t plat_psci_stat_get_residency(unsigned int lvl,
assert(last_cpu_idx <= PLATFORM_CORE_COUNT);
if (lvl == PSCI_CPU_PWR_LVL)
- assert((unsigned int)last_cpu_idx == plat_my_core_pos());
+ assert(last_cpu_idx == plat_my_core_pos());
/*
* If power down is requested, then timestamp capture will
diff --git a/plat/common/plat_spm_rd.c b/plat/common/plat_spm_rd.c
deleted file mode 100644
index ebd3e6dc6b..0000000000
--- a/plat/common/plat_spm_rd.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <libfdt.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <common/fdt_wrappers.h>
-#include <lib/object_pool.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-
-/*******************************************************************************
- * Resource pool
- ******************************************************************************/
-static struct sp_rd_sect_mem_region rd_mem_regions[PLAT_SPM_MEM_REGIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_mem_regions_pool, rd_mem_regions);
-
-static struct sp_rd_sect_notification rd_notifs[PLAT_SPM_NOTIFICATIONS_MAX];
-static OBJECT_POOL_ARRAY(rd_notifs_pool, rd_notifs);
-
-static struct sp_rd_sect_service rd_services[PLAT_SPM_SERVICES_MAX];
-static OBJECT_POOL_ARRAY(rd_services_pool, rd_services);
-
-/*******************************************************************************
- * Attribute section handler
- ******************************************************************************/
-static void rd_parse_attribute(struct sp_rd_sect_attribute *attr,
- const void *fdt, int node)
-{
- int rc = 0;
-
- /* The minimum size that can be read from the DTB is 32-bit. */
- uint32_t version, sp_type, runtime_el, exec_type;
- uint32_t panic_policy, xlat_granule;
-
- rc |= fdtw_read_cells(fdt, node, "version", 1, &version);
-
- if (version != 1) {
- ERROR("Unsupported resource description version: 0x%x\n",
- version);
- panic();
- }
-
- rc |= fdtw_read_cells(fdt, node, "sp_type", 1, &sp_type);
- rc |= fdtw_read_cells(fdt, node, "pe_mpidr", 1, &attr->pe_mpidr);
- rc |= fdtw_read_cells(fdt, node, "runtime_el", 1, &runtime_el);
- rc |= fdtw_read_cells(fdt, node, "exec_type", 1, &exec_type);
- rc |= fdtw_read_cells(fdt, node, "panic_policy", 1, &panic_policy);
- rc |= fdtw_read_cells(fdt, node, "xlat_granule", 1, &xlat_granule);
- rc |= fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size);
- rc |= fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address);
- rc |= fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint);
-
- attr->version = version;
- attr->sp_type = sp_type;
- attr->runtime_el = runtime_el;
- attr->exec_type = exec_type;
- attr->panic_policy = panic_policy;
- attr->xlat_granule = xlat_granule;
-
- VERBOSE(" Attribute Section:\n");
- VERBOSE(" version: 0x%x\n", version);
- VERBOSE(" sp_type: 0x%x\n", sp_type);
- VERBOSE(" pe_mpidr: 0x%x\n", attr->pe_mpidr);
- VERBOSE(" runtime_el: 0x%x\n", runtime_el);
- VERBOSE(" exec_type: 0x%x\n", exec_type);
- VERBOSE(" panic_policy: 0x%x\n", panic_policy);
- VERBOSE(" xlat_granule: 0x%x\n", xlat_granule);
- VERBOSE(" binary_size: 0x%x\n", attr->binary_size);
- VERBOSE(" load_address: 0x%llx\n", attr->load_address);
- VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint);
-
- if (rc) {
- ERROR("Failed to read attribute node elements.\n");
- panic();
- }
-}
-
-/*******************************************************************************
- * Memory regions section handlers
- ******************************************************************************/
-static void rd_parse_memory_region(struct sp_rd_sect_mem_region *rdmem,
- const void *fdt, int node)
-{
- int rc = 0;
- char name[RD_MEM_REGION_NAME_LEN];
-
- rc |= fdtw_read_string(fdt, node, "str", (char *)&name, sizeof(name));
- rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdmem->attr);
- rc |= fdtw_read_cells(fdt, node, "base", 2, &rdmem->base);
- rc |= fdtw_read_cells(fdt, node, "size", 2, &rdmem->size);
-
- size_t len = strlcpy(rdmem->name, name, RD_MEM_REGION_NAME_LEN);
-
- if (len >= RD_MEM_REGION_NAME_LEN) {
- WARN("Memory region name truncated: '%s'\n", name);
- }
-
- VERBOSE(" Memory Region:\n");
- VERBOSE(" name: '%s'\n", rdmem->name);
- VERBOSE(" attr: 0x%x\n", rdmem->attr);
- VERBOSE(" base: 0x%llx\n", rdmem->base);
- VERBOSE(" size: 0x%llx\n", rdmem->size);
-
- if (rc) {
- ERROR("Failed to read mem_region node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_memory_regions(struct sp_res_desc *rd, const void *fdt,
- int node)
-{
- int child;
- struct sp_rd_sect_mem_region *rdmem, *old_rdmem;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdmem = pool_alloc(&rd_mem_regions_pool);
-
- /* Add element to the start of the list */
- old_rdmem = rd->mem_region;
- rd->mem_region = rdmem;
- rdmem->next = old_rdmem;
-
- rd_parse_memory_region(rdmem, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
- panic();
- }
-}
-
-/*******************************************************************************
- * Notifications section handlers
- ******************************************************************************/
-static void rd_parse_notification(struct sp_rd_sect_notification *rdnot,
- const void *fdt, int node)
-{
- int rc = 0;
-
- rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdnot->attr);
- rc |= fdtw_read_cells(fdt, node, "pe", 1, &rdnot->pe);
-
- VERBOSE(" Notification:\n");
- VERBOSE(" attr: 0x%x\n", rdnot->attr);
- VERBOSE(" pe: 0x%x\n", rdnot->pe);
-
- if (rc) {
- ERROR("Failed to read notification node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_notifications(struct sp_res_desc *rd, const void *fdt, int node)
-{
- int child;
- struct sp_rd_sect_notification *rdnot, *old_rdnot;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdnot = pool_alloc(&rd_notifs_pool);
-
- /* Add element to the start of the list */
- old_rdnot = rd->notification;
- rd->notification = rdnot;
- rdnot->next = old_rdnot;
-
- rd_parse_notification(rdnot, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, child);
- panic();
- }
-}
-
-/*******************************************************************************
- * Services section handlers
- ******************************************************************************/
-static void rd_parse_service(struct sp_rd_sect_service *rdsvc, const void *fdt,
- int node)
-{
- int rc = 0;
-
- /* The minimum size that can be read from the DTB is 32-bit. */
- uint32_t accessibility, request_type, connection_quota;
-
- rc |= fdtw_read_array(fdt, node, "uuid", 4, &rdsvc->uuid);
- rc |= fdtw_read_cells(fdt, node, "accessibility", 1, &accessibility);
- rc |= fdtw_read_cells(fdt, node, "request_type", 1, &request_type);
- rc |= fdtw_read_cells(fdt, node, "connection_quota", 1, &connection_quota);
- rc |= fdtw_read_cells(fdt, node, "sec_mem_size", 1, &rdsvc->secure_mem_size);
- rc |= fdtw_read_cells(fdt, node, "interrupt_num", 1, &rdsvc->interrupt_num);
-
- rdsvc->accessibility = accessibility;
- rdsvc->request_type = request_type;
- rdsvc->connection_quota = connection_quota;
-
- VERBOSE(" Service:\n");
- VERBOSE(" uuid: 0x%08x 0x%08x 0x%08x 0x%08x\n", rdsvc->uuid[0],
- rdsvc->uuid[1], rdsvc->uuid[2], rdsvc->uuid[3]);
- VERBOSE(" accessibility: 0x%x\n", accessibility);
- VERBOSE(" request_type: 0x%x\n", request_type);
- VERBOSE(" connection_quota: 0x%x\n", connection_quota);
- VERBOSE(" secure_memory_size: 0x%x\n", rdsvc->secure_mem_size);
- VERBOSE(" interrupt_num: 0x%x\n", rdsvc->interrupt_num);
-
- if (rc) {
- ERROR("Failed to read attribute node elements.\n");
- panic();
- }
-}
-
-static void rd_parse_services(struct sp_res_desc *rd, const void *fdt, int node)
-{
- int child;
- struct sp_rd_sect_service *rdsvc, *old_rdsvc;
-
- fdt_for_each_subnode(child, fdt, node) {
- rdsvc = pool_alloc(&rd_services_pool);
-
- /* Add element to the start of the list */
- old_rdsvc = rd->service;
- rd->service = rdsvc;
- rdsvc->next = old_rdsvc;
-
- rd_parse_service(rdsvc, fdt, child);
- }
-
- if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) {
- ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node);
- panic();
- }
-}
-
-/*******************************************************************************
- * Root node handler
- ******************************************************************************/
-static void rd_parse_root(struct sp_res_desc *rd, const void *fdt, int root)
-{
- int node;
- char *str;
-
- str = "attribute";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- ERROR("Root node doesn't contain subnode '%s'\n", str);
- panic();
- } else {
- rd_parse_attribute(&rd->attribute, fdt, node);
- }
-
- str = "memory_regions";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- ERROR("Root node doesn't contain subnode '%s'\n", str);
- panic();
- } else {
- rd_parse_memory_regions(rd, fdt, node);
- }
-
- str = "notifications";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- WARN("Root node doesn't contain subnode '%s'\n", str);
- } else {
- rd_parse_notifications(rd, fdt, node);
- }
-
- str = "services";
- node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str));
- if (node < 0) {
- WARN("Root node doesn't contain subnode '%s'\n", str);
- } else {
- rd_parse_services(rd, fdt, node);
- }
-}
-
-/*******************************************************************************
- * Platform handler to load resource descriptor blobs into the active Secure
- * Partition context.
- ******************************************************************************/
-int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size)
-{
- int rc;
- int root_node;
-
- assert(rd != NULL);
- assert(ptr != NULL);
-
- INFO("Reading RD blob at address %p\n", ptr);
-
- rc = fdt_check_header(ptr);
- if (rc != 0) {
- ERROR("Wrong format for resource descriptor blob (%d).\n", rc);
- return -1;
- }
-
- root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,sp_rd");
- if (root_node < 0) {
- ERROR("Unrecognized resource descriptor blob (%d)\n", rc);
- return -1;
- }
-
- rd_parse_root(rd, ptr, root_node);
-
- return 0;
-}
diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c
deleted file mode 100644
index bc3d6a0151..0000000000
--- a/plat/common/plat_spm_sp.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-
-#include <platform_def.h>
-
-#include <common/debug.h>
-#include <plat/common/platform.h>
-#include <tools_share/sptool.h>
-
-static unsigned int sp_next;
-
-/*******************************************************************************
- * Platform handler get the address of a Secure Partition and its resource
- * description blob. It iterates through all SPs detected by the platform. If
- * there is information for another SP, it returns 0. If there are no more SPs,
- * it returns -1.
- ******************************************************************************/
-int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size,
- void **rd_base, size_t *rd_size)
-{
- assert((sp_base != NULL) && (sp_size != NULL));
- assert((rd_base != NULL) && (rd_base != NULL));
-
- const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE;
-
- struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base;
-
- if (sp_next == 0) {
- if (pkg_header->version != 0x1) {
- ERROR("SP package has an unsupported version 0x%llx\n",
- pkg_header->version);
- panic();
- }
- }
-
- if (sp_next >= pkg_header->number_of_sp) {
- /* No more partitions in the package */
- return -1;
- }
-
- const struct sp_pkg_entry *entry_list =
- (const struct sp_pkg_entry *)((uintptr_t)pkg_base
- + sizeof(struct sp_pkg_header));
-
- const struct sp_pkg_entry *entry = &(entry_list[sp_next]);
-
- uint64_t sp_offset = entry->sp_offset;
- uint64_t rd_offset = entry->rd_offset;
-
- uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset);
- uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset);
-
- uint64_t pkg_sp_size = entry->sp_size;
- uint64_t pkg_rd_size = entry->rd_size;
-
- uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE
- + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U;
-
- /*
- * Check for overflows. The package header isn't trusted, so assert()
- * can't be used here.
- */
-
- uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U;
- uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U;
-
- if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) {
- ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size);
- panic();
- }
-
- if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) {
- ERROR("Invalid Resource Description blob size (0x%llx)\n",
- pkg_rd_size);
- panic();
- }
-
- /* Return location of the binaries. */
-
- *sp_base = (void *)pkg_sp_base;
- *sp_size = pkg_sp_size;
- *rd_base = (void *)pkg_rd_base;
- *rd_size = pkg_rd_size;
-
- sp_next++;
-
- return 0;
-}
diff --git a/plat/imx/common/include/imx_caam.h b/plat/imx/common/include/imx_caam.h
index 335bd0f8bc..61005b51cc 100644
--- a/plat/imx/common/include/imx_caam.h
+++ b/plat/imx/common/include/imx_caam.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#ifndef IMX_CAAM_H
#define IMX_CAAM_H
+#include <cdefs.h>
#include <stdint.h>
#include <arch.h>
#include <imx_regs.h>
diff --git a/plat/imx/common/include/imx_snvs.h b/plat/imx/common/include/imx_snvs.h
index 0b3d1085f7..565c451dd8 100644
--- a/plat/imx/common/include/imx_snvs.h
+++ b/plat/imx/common/include/imx_snvs.h
@@ -1,11 +1,12 @@
/*
- * Copyright (C) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (C) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef IMX_SNVS_H
#define IMX_SNVS_H
+#include <cdefs.h>
#include <stdint.h>
#include <arch.h>
diff --git a/plat/imx/common/include/sci/sci_ipc.h b/plat/imx/common/include/sci/sci_ipc.h
index 1167ea367d..39e9012bc4 100644
--- a/plat/imx/common/include/sci/sci_ipc.h
+++ b/plat/imx/common/include/sci/sci_ipc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -62,6 +62,6 @@ void sc_ipc_read(sc_ipc_t ipc, void *data);
*/
void sc_ipc_write(sc_ipc_t ipc, void *data);
-sc_ipc_t ipc_handle;
+extern sc_ipc_t ipc_handle;
#endif /* SCI_IPC_H */
diff --git a/plat/imx/common/sci/ipc.c b/plat/imx/common/sci/ipc.c
index 6491ca575f..5769119254 100644
--- a/plat/imx/common/sci/ipc.c
+++ b/plat/imx/common/sci/ipc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,8 @@
#include <sci/sci_rpc.h>
#include "imx8_mu.h"
+sc_ipc_t ipc_handle;
+
DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock);
#define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock)
#define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock)
diff --git a/plat/imx/imx8m/include/imx8m_psci.h b/plat/imx/imx8m/include/imx8m_psci.h
index 496640383b..c33d25e824 100644
--- a/plat/imx/imx8m/include/imx8m_psci.h
+++ b/plat/imx/imx8m/include/imx8m_psci.h
@@ -15,13 +15,9 @@ int imx_pwr_domain_on(u_register_t mpidr);
void imx_pwr_domain_on_finish(const psci_power_state_t *target_state);
void imx_pwr_domain_off(const psci_power_state_t *target_state);
int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint);
-int imx_validate_power_state(unsigned int power_state, psci_power_state_t *rq_state);
void imx_cpu_standby(plat_local_state_t cpu_state);
void imx_domain_suspend(const psci_power_state_t *target_state);
void imx_domain_suspend_finish(const psci_power_state_t *target_state);
-void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
-void __dead2 imx_system_reset(void);
-void __dead2 imx_system_off(void);
void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state);
#endif /* IMX8M_PSCI_H */
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index e9ab92850e..86b7ab88fe 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -14,20 +14,17 @@
#include <drivers/synopsys/dw_mmc.h>
#include <drivers/ti/uart/uart_16550.h>
#include <lib/xlat_tables/xlat_tables.h>
-#include <platform_def.h>
-#include <socfpga_private.h>
#include "agilex_clock_manager.h"
-#include "agilex_handoff.h"
-#include "agilex_mailbox.h"
#include "agilex_memory_controller.h"
#include "agilex_pinmux.h"
-#include "agilex_private.h"
#include "agilex_reset_manager.h"
#include "agilex_system_manager.h"
-
#include "ccu/ncore_ccu.h"
#include "qspi/cadence_qspi.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
#include "wdt/watchdog.h"
@@ -59,7 +56,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
generic_delay_timer_init();
- if (agilex_get_handoff(&reverse_handoff_ptr))
+ if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
boot_source = reverse_handoff_ptr.boot_source;
diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c
index c8765e8577..375483dd44 100644
--- a/plat/intel/soc/agilex/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex/bl31_plat_setup.c
@@ -12,7 +12,6 @@
#include <drivers/arm/gicv2.h>
#include <drivers/ti/uart/uart_16550.h>
#include <lib/xlat_tables/xlat_tables.h>
-#include <platform_def.h>
static entry_point_info_t bl32_image_ep_info;
@@ -67,15 +66,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
}
static const interrupt_prop_t s10_interrupt_props[] = {
- PLAT_INTEL_AGX_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
- PLAT_INTEL_AGX_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+ PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
};
static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
static const gicv2_driver_data_t plat_gicv2_gic_data = {
- .gicd_base = PLAT_INTEL_AGX_GICD_BASE,
- .gicc_base = PLAT_INTEL_AGX_GICC_BASE,
+ .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+ .gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE,
.interrupt_props = s10_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(s10_interrupt_props),
.target_masks = target_mask_array,
@@ -104,7 +103,7 @@ const mmap_region_t plat_agilex_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS),
MAP_REGION_FLAT(DEVICE4_BASE, DEVICE4_SIZE, MT_DEVICE | MT_RW | MT_NS),
- {0},
+ {0}
};
/*******************************************************************************
@@ -126,7 +125,7 @@ void bl31_plat_arch_setup(void)
BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
MT_DEVICE | MT_RW | MT_SECURE),
#endif
- {0},
+ {0}
};
setup_page_tables(bl_regions, plat_agilex_mmap);
diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h
index 0822290aa0..8af6a60bca 100644
--- a/plat/intel/soc/agilex/include/agilex_clock_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h
@@ -7,7 +7,7 @@
#ifndef CLOCKMANAGER_H
#define CLOCKMANAGER_H
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
/* Clock Manager Registers */
#define CLKMGR_OFFSET 0xffd10000
diff --git a/plat/intel/soc/agilex/include/agilex_pinmux.h b/plat/intel/soc/agilex/include/agilex_pinmux.h
index e6a7b341dc..fe01062c09 100644
--- a/plat/intel/soc/agilex/include/agilex_pinmux.h
+++ b/plat/intel/soc/agilex/include/agilex_pinmux.h
@@ -12,7 +12,7 @@
#define AGX_PINMUX_PINMUX_EMAC0_USEFPGA 0xffd13300
#define AGX_PINMUX_IO0_DELAY 0xffd13400
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
void config_pinmux(handoff *handoff);
diff --git a/plat/intel/soc/agilex/include/agilex_private.h b/plat/intel/soc/agilex/include/agilex_private.h
deleted file mode 100644
index fc0e9fddff..0000000000
--- a/plat/intel/soc/agilex/include/agilex_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef AGX_PRIVATE_H
-#define AGX_PRIVATE_H
-
-#define AGX_MMC_REG_BASE 0xff808000
-
-#define EMMC_DESC_SIZE (1<<20)
-#define EMMC_INIT_PARAMS(base, clk) \
- { .bus_width = MMC_BUS_WIDTH_4, \
- .clk_rate = (clk), \
- .desc_base = (base), \
- .desc_size = EMMC_DESC_SIZE, \
- .flags = 0, \
- .reg_base = AGX_MMC_REG_BASE \
- }
-
-typedef enum {
- BOOT_SOURCE_FPGA = 0,
- BOOT_SOURCE_SDMMC,
- BOOT_SOURCE_NAND,
- BOOT_SOURCE_RSVD,
- BOOT_SOURCE_QSPI
-} boot_source_type;
-
-void enable_nonsecure_access(void);
-void socfpga_io_setup(int boot_source);
-
-#endif
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index 381c2d3551..be2953664e 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -73,7 +73,6 @@
#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101
#define DISABLE_L4_FIREWALL (BIT(0) | BIT(16) | BIT(24))
-void enable_nonsecure_access(void);
void enable_ns_bridge_access(void);
#endif
diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h
new file mode 100644
index 0000000000..a346cb5f82
--- /dev/null
+++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX
+
+/* Register Mapping */
+#define SOCFPGA_MMC_REG_BASE 0xff808000
+
+#define SOCFPGA_RSTMGR_OFST 0xffd11000
+#define SOCFPGA_RSTMGR_MPUMODRST_OFST 0xffd11020
+
+#endif /* PLAT_SOCFPGA_DEF_H */
+
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index d1ea62915c..ef02a8dfba 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: BSD-3-Clause
#
-#
+
PLAT_INCLUDES := \
-Iplat/intel/soc/agilex/include/ \
-Iplat/intel/soc/common/drivers/ \
@@ -25,48 +25,41 @@ PLAT_BL_COMMON_SOURCES := \
BL2_SOURCES += \
common/desc_image_load.c \
- drivers/partition/partition.c \
- drivers/partition/gpt.c \
- drivers/arm/pl061/pl061_gpio.c \
drivers/mmc/mmc.c \
- drivers/synopsys/emmc/dw_mmc.c \
+ drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
- drivers/gpio/gpio.c \
- drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \
+ drivers/partition/partition.c \
+ drivers/partition/gpt.c \
+ drivers/synopsys/emmc/dw_mmc.c \
lib/cpus/aarch64/cortex_a53.S \
plat/intel/soc/agilex/bl2_plat_setup.c \
- plat/intel/soc/agilex/socfpga_storage.c \
- plat/intel/soc/common/bl2_plat_mem_params_desc.c \
- plat/intel/soc/agilex/soc/agilex_reset_manager.c \
- plat/intel/soc/agilex/soc/agilex_handoff.c \
plat/intel/soc/agilex/soc/agilex_clock_manager.c \
- plat/intel/soc/agilex/soc/agilex_pinmux.c \
plat/intel/soc/agilex/soc/agilex_memory_controller.c \
+ plat/intel/soc/agilex/soc/agilex_pinmux.c \
+ plat/intel/soc/agilex/soc/agilex_reset_manager.c \
+ plat/intel/soc/agilex/soc/agilex_system_manager.c \
+ plat/intel/soc/common/bl2_plat_mem_params_desc.c \
plat/intel/soc/common/socfpga_delay_timer.c \
plat/intel/soc/common/socfpga_image_load.c \
- plat/intel/soc/agilex/soc/agilex_system_manager.c \
- plat/intel/soc/agilex/soc/agilex_mailbox.c \
+ plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_handoff.c \
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
plat/intel/soc/common/drivers/wdt/watchdog.c \
plat/intel/soc/common/drivers/ccu/ncore_ccu.c
BL31_SOURCES += \
drivers/arm/cci/cci.c \
- lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/aem_generic.S \
+ lib/cpus/aarch64/cortex_a53.S \
plat/common/plat_psci_common.c \
- plat/intel/soc/agilex/socfpga_sip_svc.c \
plat/intel/soc/agilex/bl31_plat_setup.c \
- plat/intel/soc/agilex/socfpga_psci.c \
+ plat/intel/soc/common/socfpga_psci.c \
+ plat/intel/soc/common/socfpga_sip_svc.c \
plat/intel/soc/common/socfpga_topology.c \
- plat/intel/soc/common/socfpga_delay_timer.c \
- plat/intel/soc/agilex/soc/agilex_reset_manager.c \
- plat/intel/soc/agilex/soc/agilex_pinmux.c \
- plat/intel/soc/agilex/soc/agilex_clock_manager.c \
- plat/intel/soc/agilex/soc/agilex_handoff.c \
- plat/intel/soc/agilex/soc/agilex_mailbox.c
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
PROGRAMMABLE_RESET_ADDRESS := 0
BL2_AT_EL3 := 1
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index 06891ff936..96b669cfd6 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -11,8 +11,8 @@
#include <lib/mmio.h>
#include "agilex_clock_manager.h"
-#include "agilex_handoff.h"
#include "agilex_system_manager.h"
+#include "socfpga_handoff.h"
uint32_t wait_pll_lock(void)
diff --git a/plat/intel/soc/agilex/soc/agilex_memory_controller.c b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
index 5f3cae7be8..2aabe87cc1 100644
--- a/plat/intel/soc/agilex/soc/agilex_memory_controller.c
+++ b/plat/intel/soc/agilex/soc/agilex_memory_controller.c
@@ -20,9 +20,8 @@
#define PRE_CALIBRATION_DELAY 1
#define POST_CALIBRATION_DELAY 1
#define TIMEOUT_EMIF_CALIBRATION 1000
-#define CLEAR_EMIF_DELAY 50000
-#define CLEAR_EMIF_TIMEOUT 0x100000
-#define TIMEOUT_INT_RESP 10000
+#define CLEAR_EMIF_DELAY 1000
+#define CLEAR_EMIF_TIMEOUT 1000
#define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
#define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t))
@@ -125,7 +124,7 @@ static int mem_calibration(void)
data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT);
if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
break;
- mdelay(1);
+ udelay(500);
} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S
index 00fe2d9990..5cb9b699aa 100644
--- a/plat/intel/soc/common/aarch64/plat_helpers.S
+++ b/plat/intel/soc/common/aarch64/plat_helpers.S
@@ -8,6 +8,7 @@
#include <asm_macros.S>
#include <cpu_macros.S>
#include <platform_def.h>
+#include <el3_common_macros.S>
.globl plat_secondary_cold_boot_setup
.globl platform_is_primary_cpu
@@ -17,6 +18,7 @@
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl platform_mem_init
+ .globl plat_secondary_cpus_bl31_entry
.globl plat_get_my_entrypoint
@@ -33,7 +35,6 @@ func plat_secondary_cold_boot_setup
/* Wait until the it gets reset signal from rstmgr gets populated */
poll_mailbox:
wfi
-
mov_imm x0, PLAT_SEC_ENTRY
ldr x1, [x0]
mov_imm x2, PLAT_CPUID_RELEASE
@@ -65,12 +66,34 @@ func plat_my_core_pos
ret
endfunc plat_my_core_pos
+func warm_reset_req
+ str xzr, [x4]
+ bl plat_is_my_cpu_primary
+ cbz x0, cpu_in_wfi
+ mov_imm x1, PLAT_SEC_ENTRY
+ str xzr, [x1]
+ mrs x1, rmr_el3
+ orr x1, x1, #0x02
+ msr rmr_el3, x1
+ isb
+ dsb sy
+cpu_in_wfi:
+ wfi
+ b cpu_in_wfi
+endfunc warm_reset_req
+
func plat_get_my_entrypoint
+ ldr x4, =L2_RESET_DONE_REG
+ ldr x5, [x4]
+ ldr x1, =L2_RESET_DONE_STATUS
+ cmp x1, x5
+ b.eq warm_reset_req
mov_imm x1, PLAT_SEC_ENTRY
ldr x0, [x1]
ret
endfunc plat_get_my_entrypoint
+
/* ---------------------------------------------
* int plat_crash_console_init(void)
* Function to initialize the crash console
@@ -114,3 +137,14 @@ func platform_mem_init
mov x0, #0
ret
endfunc platform_mem_init
+
+func plat_secondary_cpus_bl31_entry
+ el3_entrypoint_common \
+ _init_sctlr=0 \
+ _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \
+ _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \
+ _init_memory=1 \
+ _init_c_runtime=1 \
+ _exception_vectors=runtime_exceptions \
+ _pie_fixup_size=BL31_LIMIT - BL31_BASE
+endfunc plat_secondary_cpus_bl31_entry
diff --git a/plat/intel/soc/common/aarch64/platform_common.c b/plat/intel/soc/common/aarch64/platform_common.c
index 6d3d817d6f..b79a63c863 100644
--- a/plat/intel/soc/common/aarch64/platform_common.c
+++ b/plat/intel/soc/common/aarch64/platform_common.c
@@ -8,7 +8,8 @@
#include <arch_helpers.h>
#include <platform_def.h>
#include <plat/common/platform.h>
-#include <socfpga_private.h>
+
+#include "socfpga_private.h"
unsigned int plat_get_syscnt_freq2(void)
diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
index ac8218ecd9..fce816b655 100644
--- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
+++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c
@@ -10,7 +10,6 @@
#include <lib/mmio.h>
#include "ncore_ccu.h"
-#include <platform_def.h>
uint32_t poll_active_bit(uint32_t dir);
diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
index 0fd11ec780..cecf56088f 100644
--- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
+++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c
@@ -13,7 +13,6 @@
#include <drivers/console.h>
#include "cadence_qspi.h"
-#include <platform_def.h>
#define LESS(a, b) (((a) < (b)) ? (a) : (b))
#define MORE(a, b) (((a) > (b)) ? (a) : (b))
@@ -689,10 +688,7 @@ int cad_qspi_read(void *buffer, uint32_t offset, uint32_t size)
if ((offset >= qspi_device_size) ||
(offset + size - 1 >= qspi_device_size) ||
- (size == 0) ||
- ((long) ((int *)buffer) & 0x3) ||
- (offset & 0x3) ||
- (size & 0x3)) {
+ (size == 0)) {
ERROR("Invalid read parameter\n");
return -1;
}
@@ -767,11 +763,9 @@ int cad_qspi_write(void *buffer, uint32_t offset, uint32_t size)
if ((offset >= qspi_device_size) ||
(offset + size - 1 >= qspi_device_size) ||
- (size == 0) ||
- ((long)buffer & 0x3) ||
- (offset & 0x3) ||
- (size & 0x3))
+ (size == 0)) {
return -2;
+ }
if (CAD_QSPI_INDWR_RDSTAT(mmio_read_32(CAD_QSPI_OFFSET +
CAD_QSPI_INDWR))) {
diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.c b/plat/intel/soc/common/drivers/wdt/watchdog.c
index 0f89b4fd3b..651189b124 100644
--- a/plat/intel/soc/common/drivers/wdt/watchdog.c
+++ b/plat/intel/soc/common/drivers/wdt/watchdog.c
@@ -6,7 +6,6 @@
#include <common/debug.h>
#include <lib/mmio.h>
-#include <platform_def.h>
#include "watchdog.h"
diff --git a/plat/intel/soc/agilex/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h
index 277862a307..8d04479df7 100644
--- a/plat/intel/soc/agilex/include/platform_def.h
+++ b/plat/intel/soc/common/include/platform_def.h
@@ -13,12 +13,23 @@
#include <common/tbbr/tbbr_img_def.h>
#include <plat/common/common_def.h>
+#define PLAT_SOCFPGA_STRATIX10 1
+#define PLAT_SOCFPGA_AGILEX 2
-#define PLAT_CPUID_RELEASE 0xffe1b000
-#define PLAT_SEC_ENTRY 0xffe1b008
+/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */
+#define PLAT_CPU_RELEASE_ADDR 0xffd12210
+
+/*
+ * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset
+ * is done and HPS should trigger warm reset via RMR_EL3.
+ */
+#define L2_RESET_DONE_REG 0xFFD12218
+
+/* Magic word to indicate L2 reset is completed */
+#define L2_RESET_DONE_STATUS 0x1228E5E7
/* Define next boot image name and offset */
-#define PLAT_NS_IMAGE_OFFSET 0x50000
+#define PLAT_NS_IMAGE_OFFSET 0x10000000
#define PLAT_HANDOFF_OFFSET 0xFFE3F000
/*******************************************************************************
@@ -27,7 +38,7 @@
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
-/* Agilex supports up to 124GB RAM */
+/* SoCFPGA supports up to 124GB RAM */
#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 39)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 39)
@@ -56,18 +67,18 @@
/* Interrupt related constant */
-#define INTEL_AGX_IRQ_SEC_PHY_TIMER 29
+#define INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER 29
-#define INTEL_AGX_IRQ_SEC_SGI_0 8
-#define INTEL_AGX_IRQ_SEC_SGI_1 9
-#define INTEL_AGX_IRQ_SEC_SGI_2 10
-#define INTEL_AGX_IRQ_SEC_SGI_3 11
-#define INTEL_AGX_IRQ_SEC_SGI_4 12
-#define INTEL_AGX_IRQ_SEC_SGI_5 13
-#define INTEL_AGX_IRQ_SEC_SGI_6 14
-#define INTEL_AGX_IRQ_SEC_SGI_7 15
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_0 8
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_1 9
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_2 10
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_3 11
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_4 12
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_5 13
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_6 14
+#define INTEL_SOCFPGA_IRQ_SEC_SGI_7 15
-#define TSP_IRQ_SEC_PHY_TIMER INTEL_AGX_IRQ_SEC_PHY_TIMER
+#define TSP_IRQ_SEC_PHY_TIMER INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER
#define TSP_SEC_MEM_BASE BL32_BASE
#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE + 1)
/*******************************************************************************
@@ -104,19 +115,24 @@
*/
-#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
+#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
-#define BL1_RO_BASE (0xffe00000)
-#define BL1_RO_LIMIT (0xffe0f000)
-#define BL1_RW_BASE (0xffe10000)
-#define BL1_RW_LIMIT (0xffe1ffff)
-#define BL1_RW_SIZE (0x14000)
+#define BL1_RO_BASE (0xffe00000)
+#define BL1_RO_LIMIT (0xffe0f000)
+#define BL1_RW_BASE (0xffe10000)
+#define BL1_RW_LIMIT (0xffe1ffff)
+#define BL1_RW_SIZE (0x14000)
-#define BL2_BASE (0xffe00000)
-#define BL2_LIMIT (0xffe1b000)
+#define BL2_BASE (0xffe00000)
+#define BL2_LIMIT (0xffe1b000)
-#define BL31_BASE (0xffe1c000)
-#define BL31_LIMIT (0xffe3bfff)
+#define BL31_BASE (0x1000)
+#define BL31_LIMIT (0x81000)
+
+#define BL_DATA_LIMIT PLAT_HANDOFF_OFFSET
+
+#define PLAT_CPUID_RELEASE (BL_DATA_LIMIT - 16)
+#define PLAT_SEC_ENTRY (BL_DATA_LIMIT - 8)
/*******************************************************************************
* Platform specific page table and MMU setup constants
@@ -158,39 +174,50 @@
#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400)
-#define PLAT_INTEL_AGX_GICD_BASE PLAT_GICD_BASE
-#define PLAT_INTEL_AGX_GICC_BASE PLAT_GICC_BASE
+#define PLAT_INTEL_SOCFPGA_GICD_BASE PLAT_GICD_BASE
+#define PLAT_INTEL_SOCFPGA_GICC_BASE PLAT_GICC_BASE
/*
* 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_INTEL_AGX_G1S_IRQ_PROPS(grp) \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
- grp, GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE)
-
-#define PLAT_INTEL_AGX_G0_IRQ_PROPS(grp)
+#define PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(grp) \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_0, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_1, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_2, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_3, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_4, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_5, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_6, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \
+ INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_7, \
+ GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE)
+
+#define PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(grp)
#define MAX_IO_HANDLES 4
#define MAX_IO_DEVICES 4
#define MAX_IO_BLOCK_DEVICES 2
+#ifndef __ASSEMBLER__
+struct socfpga_bl31_params {
+ param_header_t h;
+ image_info_t *bl31_image_info;
+ entry_point_info_t *bl32_ep_info;
+ image_info_t *bl32_image_info;
+ entry_point_info_t *bl33_ep_info;
+ image_info_t *bl33_image_info;
+};
+#endif
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/intel/soc/agilex/include/agilex_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h
index 201640611a..889d137679 100644
--- a/plat/intel/soc/agilex/include/agilex_handoff.h
+++ b/plat/intel/soc/common/include/socfpga_handoff.h
@@ -15,6 +15,8 @@
#define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */
#define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */
+#include <socfpga_plat_def.h>
+
typedef struct handoff_t {
/* header */
uint32_t header_magic;
@@ -47,6 +49,44 @@ typedef struct handoff_t {
uint32_t pinmux_iodelay_array[96]; /* offset, value */
/* clock configuration */
+
+#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
+ uint32_t clock_magic;
+ uint32_t clock_length;
+ uint32_t _pad_0x588_0x590[2];
+ uint32_t main_pll_mpuclk;
+ uint32_t main_pll_nocclk;
+ uint32_t main_pll_cntr2clk;
+ uint32_t main_pll_cntr3clk;
+ uint32_t main_pll_cntr4clk;
+ uint32_t main_pll_cntr5clk;
+ uint32_t main_pll_cntr6clk;
+ uint32_t main_pll_cntr7clk;
+ uint32_t main_pll_cntr8clk;
+ uint32_t main_pll_cntr9clk;
+ uint32_t main_pll_nocdiv;
+ uint32_t main_pll_pllglob;
+ uint32_t main_pll_fdbck;
+ uint32_t main_pll_pllc0;
+ uint32_t main_pll_pllc1;
+ uint32_t _pad_0x5cc_0x5d0[1];
+ uint32_t per_pll_cntr2clk;
+ uint32_t per_pll_cntr3clk;
+ uint32_t per_pll_cntr4clk;
+ uint32_t per_pll_cntr5clk;
+ uint32_t per_pll_cntr6clk;
+ uint32_t per_pll_cntr7clk;
+ uint32_t per_pll_cntr8clk;
+ uint32_t per_pll_cntr9clk;
+ uint32_t per_pll_emacctl;
+ uint32_t per_pll_gpiodiv;
+ uint32_t per_pll_pllglob;
+ uint32_t per_pll_fdbck;
+ uint32_t per_pll_pllc0;
+ uint32_t per_pll_pllc1;
+ uint32_t hps_osc_clk_h;
+ uint32_t fpga_clk_hz;
+#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX
uint32_t clock_magic;
uint32_t clock_length;
uint32_t _pad_0x588_0x590[2];
@@ -80,7 +120,7 @@ typedef struct handoff_t {
uint32_t hps_osc_clk_h;
uint32_t fpga_clk_hz;
uint32_t _pad_0x604_0x610[3];
-
+#endif
/* misc configuration */
uint32_t misc_magic;
uint32_t misc_length;
@@ -89,7 +129,7 @@ typedef struct handoff_t {
} handoff;
int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
-int agilex_get_handoff(handoff *hoff_ptr);
+int socfpga_get_handoff(handoff *hoff_ptr);
#endif
diff --git a/plat/intel/soc/agilex/include/agilex_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index cd8be2894f..c5f2fbe77d 100644
--- a/plat/intel/soc/agilex/include/agilex_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -4,13 +4,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef AGX_MBOX_H
-#define AGX_MBOX_H
+#ifndef SOCFPGA_MBOX_H
+#define SOCFPGA_MBOX_H
#include <lib/utils_def.h>
#define MBOX_OFFSET 0xffa30000
+#define MBOX_MAX_JOB_ID 0xf
#define MBOX_ATF_CLIENT_ID 0x1
#define MBOX_JOB_ID 0x1
@@ -66,6 +67,9 @@
#define MBOX_CMD_GET_IDCODE 16
#define MBOX_CMD_QSPI_SET_CS 52
+/* Mailbox CANCEL command */
+#define MBOX_CMD_CANCEL 0x3
+
/* Mailbox REBOOT commands */
#define MBOX_CMD_REBOOT_HPS 71
@@ -75,41 +79,31 @@
#define MBOX_WRONG_ID -3
/* Mailbox status */
-#define RECONFIG_STATUS_STATE 0
-#define RECONFIG_STATUS_PIN_STATUS 2
-#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
-#define PIN_STATUS_NSTATUS (U(1) << 31)
-#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3)
-#define SOFTFUNC_STATUS_INIT_DONE (1 << 1)
-#define SOFTFUNC_STATUS_CONF_DONE (1 << 0)
-#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000
-
-/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-#define SIP_SVC_VERSION 0x8200ff03
-
-/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR 0
-#define SIP_SVC_VERSION_MINOR 1
+#define RECONFIG_STATUS_STATE 0
+#define RECONFIG_STATUS_PIN_STATUS 2
+#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
+#define PIN_STATUS_NSTATUS (U(1) << 31)
+#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3)
+#define SOFTFUNC_STATUS_INIT_DONE (1 << 1)
+#define SOFTFUNC_STATUS_CONF_DONE (1 << 0)
+#define MBOX_CFGSTAT_STATE_IDLE 0x00000000
+#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000
+#define MBOX_CFGSTAT_STATE_FAILACK 0x08000000
+#define MBOX_CFGSTAT_STATE_ERROR_INVALID 0xf0000001
+#define MBOX_CFGSTAT_STATE_ERROR_CORRUPT 0xf0000002
+#define MBOX_CFGSTAT_STATE_ERROR_AUTH 0xf0000003
+#define MBOX_CFGSTAT_STATE_ERROR_CORE_IO 0xf0000004
+#define MBOX_CFGSTAT_STATE_ERROR_HARDWARE 0xf0000005
+#define MBOX_CFGSTAT_STATE_ERROR_FAKE 0xf0000006
+#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007
+#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008
/* Mailbox reconfiguration commands */
+#define MBOX_CONFIG_STATUS 4
#define MBOX_RECONFIG 6
#define MBOX_RECONFIG_DATA 8
#define MBOX_RECONFIG_STATUS 9
-/* Sip get memory */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
-#define INTEL_SIP_SMC_STATUS_OK 0
-#define INTEL_SIP_SMC_STATUS_ERROR 0x4
-#define INTEL_SIP_SMC_STATUS_BUSY 0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x1000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216
void mailbox_set_int(int interrupt_input);
int mailbox_init(void);
@@ -117,11 +111,14 @@ void mailbox_set_qspi_close(void);
void mailbox_set_qspi_open(void);
void mailbox_set_qspi_direct(void);
int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response);
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
+ int len, int urgent, uint32_t *response, int resp_len);
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent);
-int mailbox_read_response(int job_id, uint32_t *response);
+int mailbox_read_response(int job_id, uint32_t *response, int resp_len);
int mailbox_get_qspi_clock(void);
void mailbox_reset_cold(void);
+void mailbox_clear_response(void);
+
+uint32_t intel_mailbox_get_config_status(uint32_t cmd);
-#endif
+#endif /* SOCFPGA_MBOX_H */
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index 6ab14090fe..ca38f62d80 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -4,12 +4,38 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef PLATFORM_PRIVATE_H
-#define PLATFORM_PRIVATE_H
+#ifndef SOCFPGA_PRIVATE_H
+#define SOCFPGA_PRIVATE_H
+
+#include "socfpga_plat_def.h"
+
+#define EMMC_DESC_SIZE (1<<20)
+
+#define EMMC_INIT_PARAMS(base, clk) \
+ { .bus_width = MMC_BUS_WIDTH_4, \
+ .clk_rate = (clk), \
+ .desc_base = (base), \
+ .desc_size = EMMC_DESC_SIZE, \
+ .flags = 0, \
+ .reg_base = SOCFPGA_MMC_REG_BASE \
+ }
+
+typedef enum {
+ BOOT_SOURCE_FPGA = 0,
+ BOOT_SOURCE_SDMMC,
+ BOOT_SOURCE_NAND,
+ BOOT_SOURCE_RSVD,
+ BOOT_SOURCE_QSPI
+} boot_source_type;
/*******************************************************************************
* Function and variable prototypes
******************************************************************************/
+
+void enable_nonsecure_access(void);
+
+void socfpga_io_setup(int boot_source);
+
void socfgpa_configure_mmu_el3(unsigned long total_base,
unsigned long total_size,
unsigned long ro_start,
@@ -35,5 +61,6 @@ uint32_t socfpga_get_spsr_for_bl33_entry(void);
unsigned long socfpga_get_ns_image_entrypoint(void);
+void plat_secondary_cpus_bl31_entry(void);
-#endif /* PLATFORM_PRIVATE_H */
+#endif /* SOCFPGA_PRIVATE_H */
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
new file mode 100644
index 0000000000..3fbf242f42
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_RESETMANAGER_H
+#define SOCFPGA_RESETMANAGER_H
+
+#define SOCFPGA_RSTMGR_STAT 0xffd11000
+#define SOCFPGA_RSTMGR_HDSKEN 0xffd11010
+#define SOCFPGA_RSTMGR_COLDMODRST 0xffd11034
+#define SOCFPGA_RSTMGR_HDSKTIMEOUT 0xffd11064
+
+#define SOCFPGA_RSTMGR_HDSKEN_SET 0x0000010D
+#define SOCFPGA_RSTMGR_SDMWARMRST 0x00000002
+
+#endif /* SOCFPGA_RESETMANAGER_H */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
new file mode 100644
index 0000000000..6bb41f31b6
--- /dev/null
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SOCFPGA_SIP_SVC_H
+#define SOCFPGA_SIP_SVC_H
+
+
+/* SiP status response */
+#define INTEL_SIP_SMC_STATUS_OK 0
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_STATUS_BUSY 0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+
+/* SMC SiP service function identifier */
+#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+#define INTEL_SIP_SMC_REG_READ 0xC2000007
+#define INTEL_SIP_SMC_REG_WRITE 0xC2000008
+#define INTEL_SIP_SMC_REG_UPDATE 0xC2000009
+#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
+#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D
+#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
+
+/* FPGA config helpers */
+#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000
+#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_CALL_COUNT 0x8200ff00
+#define SIP_SVC_UID 0x8200ff01
+#define SIP_SVC_VERSION 0x8200ff03
+
+/* SiP Service Calls version numbers */
+#define SIP_SVC_VERSION_MAJOR 0
+#define SIP_SVC_VERSION_MINOR 1
+
+#endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/agilex/soc/agilex_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c
index a458686f13..4bb3a9619d 100644
--- a/plat/intel/soc/agilex/soc/agilex_handoff.c
+++ b/plat/intel/soc/common/soc/socfpga_handoff.c
@@ -4,15 +4,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <platform_def.h>
#include <string.h>
-#include "agilex_handoff.h"
+#include "socfpga_handoff.h"
#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | \
(((x) & 0x0000FF00) << 8) | ((x) << 24))
-int agilex_get_handoff(handoff *reverse_hoff_ptr)
+int socfpga_get_handoff(handoff *reverse_hoff_ptr)
{
int i;
uint32_t *buffer;
diff --git a/plat/intel/soc/agilex/soc/agilex_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index ebfea61480..eb35c4a08b 100644
--- a/plat/intel/soc/agilex/soc/agilex_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -6,8 +6,10 @@
#include <lib/mmio.h>
#include <common/debug.h>
+#include <drivers/delay_timer.h>
-#include "agilex_mailbox.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
int len)
@@ -17,12 +19,6 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
- if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) {
- INFO("Insufficient buffer in mailbox\n");
- return MBOX_INSUFFICIENT_BUFFER;
- }
-
-
mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4),
header_cmd);
@@ -39,28 +35,21 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
return 0;
}
-int mailbox_read_response(int job_id, uint32_t *response)
+int mailbox_read_response(int job_id, uint32_t *response, int resp_len)
{
int rin = 0;
int rout = 0;
int response_length = 0;
int resp = 0;
int total_resp_len = 0;
- int timeout = 100000;
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
- while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
- if (timeout-- < 0)
- return MBOX_NO_RESPONSE;
- }
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
+ if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM))
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
- while (rout != rin) {
+ if (rout != rin) {
resp = mmio_read_32(MBOX_OFFSET +
MBOX_RESP_BUFFER + ((rout++)*4));
@@ -84,8 +73,9 @@ int mailbox_read_response(int job_id, uint32_t *response)
resp = mmio_read_32(MBOX_OFFSET +
MBOX_RESP_BUFFER +
(rout)*4);
- if (response) {
+ if (response && resp_len) {
*(response + total_resp_len) = resp;
+ resp_len--;
total_resp_len++;
}
rout++;
@@ -99,25 +89,25 @@ int mailbox_read_response(int job_id, uint32_t *response)
}
-int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
+int mailbox_poll_response(int job_id, int urgent, uint32_t *response,
+ int resp_len)
{
- int timeout = 80000;
+ int timeout = 0xFFFFFF;
int rin = 0;
int rout = 0;
int response_length = 0;
int resp = 0;
int total_resp_len = 0;
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
while (1) {
+
while (timeout > 0 &&
- mmio_read_32(MBOX_OFFSET +
- MBOX_DOORBELL_FROM_SDM) != 1) {
+ !(mmio_read_32(MBOX_OFFSET +
+ MBOX_DOORBELL_FROM_SDM) & 1)) {
timeout--;
}
- if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
+ if (!timeout) {
INFO("Timed out waiting for SDM");
return MBOX_TIMEOUT;
}
@@ -125,6 +115,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
if (urgent & 1) {
+ mdelay(5);
if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
MBOX_STATUS_UA_MASK) ^
(urgent & MBOX_STATUS_UA_MASK)) {
@@ -158,13 +149,13 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
response_length = MBOX_RESP_LEN(resp);
while (response_length) {
-
response_length--;
resp = mmio_read_32(MBOX_OFFSET +
MBOX_RESP_BUFFER +
(rout)*4);
- if (response) {
+ if (response && resp_len) {
*(response + total_resp_len) = resp;
+ resp_len--;
total_resp_len++;
}
rout++;
@@ -176,7 +167,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
}
}
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
+int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
int len, int urgent)
{
if (urgent)
@@ -187,29 +178,44 @@ void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
MBOX_CMD_LEN_CMD(len) |
MBOX_INDIRECT |
cmd, args, len);
+
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
+
+ return 0;
}
int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response)
+ int len, int urgent, uint32_t *response, int resp_len)
{
- int status;
+ int status = 0;
if (urgent) {
urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
MBOX_STATUS_UA_MASK;
mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
- status = 0;
- } else {
+ }
+
+ else {
status = fill_mailbox_circular_buffer(
MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
MBOX_JOB_ID_CMD(job_id) |
+ MBOX_CMD_LEN_CMD(len) |
cmd, args, len);
}
if (status)
return status;
- return mailbox_poll_response(job_id, urgent, response);
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
+ status = mailbox_poll_response(job_id, urgent, response, resp_len);
+
+ return status;
+}
+
+void mailbox_clear_response(void)
+{
+ mmio_write_32(MBOX_OFFSET + MBOX_ROUT,
+ mmio_read_32(MBOX_OFFSET + MBOX_RIN));
}
void mailbox_set_int(int interrupt)
@@ -223,24 +229,25 @@ void mailbox_set_int(int interrupt)
void mailbox_set_qspi_open(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0);
}
void mailbox_set_qspi_direct(void)
{
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0);
}
void mailbox_set_qspi_close(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0);
}
int mailbox_get_qspi_clock(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
+ return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0,
+ NULL, 0);
}
void mailbox_qspi_set_cs(int device_select)
@@ -251,13 +258,13 @@ void mailbox_qspi_set_cs(int device_select)
cs_setting = (cs_setting << 28);
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
- 1, 0, 0);
+ 1, 0, NULL, 0);
}
void mailbox_reset_cold(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0);
+ mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0);
}
int mailbox_init(void)
@@ -268,13 +275,44 @@ int mailbox_init(void)
MBOX_INT_FLAG_UAE);
mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
- status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0);
+
+ status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0);
if (status)
return status;
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
+ mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
+ MBOX_INT_FLAG_UAE);
return 0;
}
+uint32_t intel_mailbox_get_config_status(uint32_t cmd)
+{
+ uint32_t status, res;
+ uint32_t response[6];
+
+ status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response,
+ sizeof(response) / sizeof(response[0]));
+
+ if (status < 0)
+ return status;
+
+ res = response[RECONFIG_STATUS_STATE];
+ if (res && res != MBOX_CFGSTAT_STATE_CONFIG)
+ return res;
+
+ res = response[RECONFIG_STATUS_PIN_STATUS];
+ if (!(res & PIN_STATUS_NSTATUS))
+ return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+ res = response[RECONFIG_STATUS_SOFTFUNC_STATUS];
+ if (res & SOFTFUNC_STATUS_SEU_ERROR)
+ return MBOX_CFGSTAT_STATE_ERROR_HARDWARE;
+
+ if ((res & SOFTFUNC_STATUS_CONF_DONE) &&
+ (res & SOFTFUNC_STATUS_INIT_DONE))
+ return 0;
+
+ return MBOX_CFGSTAT_STATE_CONFIG;
+}
diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c
index 67c02bc7de..a5c327990f 100644
--- a/plat/intel/soc/common/socfpga_image_load.c
+++ b/plat/intel/soc/common/socfpga_image_load.c
@@ -28,5 +28,31 @@ bl_load_info_t *plat_get_bl_image_load_info(void)
******************************************************************************/
bl_params_t *plat_get_next_bl_params(void)
{
+ unsigned int count;
+ unsigned int img_id = 0U;
+ unsigned int link_index = 0U;
+ bl_params_node_t *bl_exec_node = NULL;
+ bl_mem_params_node_t *desc_ptr;
+
+ /* If there is no image to start with, return NULL */
+ if (bl_mem_params_desc_num == 0U)
+ return NULL;
+
+ /* Clean next_params_info in BL image node */
+ for (count = 0U; count < bl_mem_params_desc_num; count++) {
+
+ desc_ptr = &bl_mem_params_desc_ptr[link_index];
+ bl_exec_node = &desc_ptr->params_node_mem;
+ bl_exec_node->next_params_info = NULL;
+
+ /* If no next hand-off image then break out */
+ img_id = desc_ptr->next_handoff_image_id;
+ if (img_id == INVALID_IMAGE_ID)
+ break;
+
+ /* Get the index for the next hand-off image */
+ link_index = get_bl_params_node_index(img_id);
+ }
+
return get_next_bl_params_from_mem_params_desc();
}
diff --git a/plat/intel/soc/agilex/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c
index 12060ef08f..1ba48eae16 100644
--- a/plat/intel/soc/agilex/socfpga_psci.c
+++ b/plat/intel/soc/common/socfpga_psci.c
@@ -11,14 +11,11 @@
#include <lib/psci/psci.h>
#include <plat/common/platform.h>
-#include "agilex_reset_manager.h"
-#include "agilex_mailbox.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_plat_def.h"
+#include "socfpga_reset_manager.h"
-#define AGX_RSTMGR_OFST 0xffd11000
-#define AGX_RSTMGR_MPUMODRST_OFST 0x20
-uintptr_t *agilex_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY;
-uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE;
/*******************************************************************************
* plat handler called when a CPU is about to enter standby.
@@ -47,11 +44,10 @@ int socfpga_pwr_domain_on(u_register_t mpidr)
if (cpu_id == -1)
return PSCI_E_INTERN_FAIL;
- *cpuid_release = cpu_id;
+ mmio_write_64(PLAT_CPUID_RELEASE, cpu_id);
/* release core reset */
- mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
+ mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
return PSCI_E_SUCCESS;
}
@@ -80,9 +76,9 @@ void socfpga_pwr_domain_suspend(const psci_power_state_t *target_state)
for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
__func__, i, target_state->pwr_domain_state[i]);
+
/* assert core reset */
- mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
+ mmio_setbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
}
@@ -121,8 +117,7 @@ void socfpga_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
__func__, i, target_state->pwr_domain_state[i]);
/* release core reset */
- mmio_clrbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
+ mmio_clrbits_32(SOCFPGA_RSTMGR_MPUMODRST_OFST, 1 << cpu_id);
}
/*******************************************************************************
@@ -137,15 +132,37 @@ static void __dead2 socfpga_system_off(void)
static void __dead2 socfpga_system_reset(void)
{
- INFO("assert Peripheral from Reset\r\n");
-
- deassert_peripheral_reset();
mailbox_reset_cold();
while (1)
wfi();
}
+static int socfpga_system_reset2(int is_vendor, int reset_type,
+ u_register_t cookie)
+{
+ /* disable cpuif */
+ gicv2_cpuif_disable();
+
+ /* Store magic number */
+ mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS);
+
+ /* Increase timeout */
+ mmio_write_32(SOCFPGA_RSTMGR_HDSKTIMEOUT, 0xffffff);
+
+ /* Enable handshakes */
+ mmio_setbits_32(SOCFPGA_RSTMGR_HDSKEN, SOCFPGA_RSTMGR_HDSKEN_SET);
+
+ /* Reset L2 module */
+ mmio_setbits_32(SOCFPGA_RSTMGR_COLDMODRST, 0x100);
+
+ while (1)
+ wfi();
+
+ /* Should not reach here */
+ return 0;
+}
+
int socfpga_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state)
{
@@ -179,6 +196,7 @@ const plat_psci_ops_t socfpga_psci_pm_ops = {
.pwr_domain_suspend_finish = socfpga_pwr_domain_suspend_finish,
.system_off = socfpga_system_off,
.system_reset = socfpga_system_reset,
+ .system_reset2 = socfpga_system_reset2,
.validate_power_state = socfpga_validate_power_state,
.validate_ns_entrypoint = socfpga_validate_ns_entrypoint,
.get_sys_suspend_power_state = socfpga_get_sys_suspend_power_state
@@ -191,8 +209,8 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
/* Save warm boot entrypoint.*/
- *agilex_sec_entry = sec_entrypoint;
-
+ mmio_write_64(PLAT_SEC_ENTRY, sec_entrypoint);
*psci_ops = &socfpga_psci_pm_ops;
+
return 0;
}
diff --git a/plat/intel/soc/agilex/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 6a1c957c30..ce88fb489c 100644
--- a/plat/intel/soc/agilex/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -7,9 +7,11 @@
#include <assert.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
+#include <lib/mmio.h>
#include <tools_share/uuid.h>
-#include "agilex_mailbox.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
/* Number of SiP Calls implemented */
#define SIP_NUM_CALLS 0x3
@@ -17,13 +19,14 @@
/* Total buffer the driver can hold */
#define FPGA_CONFIG_BUFFER_SIZE 4
-int current_block;
-int current_buffer;
-int current_id = 1;
-int max_blocks;
-uint32_t bytes_per_block;
-uint32_t blocks_submitted;
-uint32_t blocks_completed;
+static int current_block;
+static int read_block;
+static int current_buffer;
+static int send_id;
+static int rcv_id;
+static int max_blocks;
+static uint32_t bytes_per_block;
+static uint32_t blocks_submitted;
struct fpga_config_info {
uint32_t addr;
@@ -39,7 +42,7 @@ DEFINE_SVC_UUID2(intl_svc_uid,
0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
-uint64_t socfpga_sip_handler(uint32_t smc_fid,
+static uint64_t socfpga_sip_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
@@ -54,79 +57,54 @@ uint64_t socfpga_sip_handler(uint32_t smc_fid,
struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
-static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
+static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
{
uint32_t args[3];
while (max_blocks > 0 && buffer->size > buffer->size_written) {
- if (buffer->size - buffer->size_written <=
- bytes_per_block) {
- args[0] = (1<<8);
- args[1] = buffer->addr + buffer->size_written;
+ args[0] = (1<<8);
+ args[1] = buffer->addr + buffer->size_written;
+ if (buffer->size - buffer->size_written <= bytes_per_block) {
args[2] = buffer->size - buffer->size_written;
- buffer->size_written +=
- buffer->size - buffer->size_written;
- buffer->subblocks_sent++;
- mailbox_send_cmd_async(0x4,
- MBOX_RECONFIG_DATA,
- args, 3, 0);
current_buffer++;
current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
- } else {
- args[0] = (1<<8);
- args[1] = buffer->addr + buffer->size_written;
+ } else
args[2] = bytes_per_block;
- buffer->size_written += bytes_per_block;
- mailbox_send_cmd_async(0x4,
- MBOX_RECONFIG_DATA,
- args, 3, 0);
- buffer->subblocks_sent++;
- }
+
+ buffer->size_written += args[2];
+ mailbox_send_cmd_async(
+ send_id++ % MBOX_MAX_JOB_ID,
+ MBOX_RECONFIG_DATA,
+ args, 3, 0);
+
+ buffer->subblocks_sent++;
max_blocks--;
}
+
+ return !max_blocks;
}
static int intel_fpga_sdm_write_all(void)
{
- int i;
-
- for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
- intel_fpga_sdm_write_buffer(
- &fpga_config_buffers[current_buffer]);
-
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+ if (intel_fpga_sdm_write_buffer(
+ &fpga_config_buffers[current_buffer]))
+ break;
return 0;
}
-uint32_t intel_mailbox_fpga_config_isdone(void)
+static uint32_t intel_mailbox_fpga_config_isdone(void)
{
- uint32_t args[2];
- uint32_t response[6];
- int status;
-
- status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0,
- response);
-
- if (status < 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
+ uint32_t ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS);
- if (response[RECONFIG_STATUS_STATE] &&
- response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS))
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_SEU_ERROR)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_CONF_DONE) &&
- (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_INIT_DONE))
- return INTEL_SIP_SMC_STATUS_OK;
+ if (ret) {
+ if (ret == MBOX_CFGSTAT_STATE_CONFIG)
+ return INTEL_SIP_SMC_STATUS_BUSY;
+ else
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
- return INTEL_SIP_SMC_STATUS_ERROR;
+ return INTEL_SIP_SMC_STATUS_OK;
}
static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
@@ -151,16 +129,7 @@ static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
return -1;
}
-unsigned int address_in_ddr(uint32_t *addr)
-{
- if (((unsigned long long)addr > DRAM_BASE) &&
- ((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
- return 0;
-
- return -1;
-}
-
-int intel_fpga_config_completed_write(uint32_t *completed_addr,
+static int intel_fpga_config_completed_write(uint32_t *completed_addr,
uint32_t *count)
{
uint32_t status = INTEL_SIP_SMC_STATUS_OK;
@@ -168,30 +137,29 @@ int intel_fpga_config_completed_write(uint32_t *completed_addr,
int resp_len = 0;
uint32_t resp[5];
int all_completed = 1;
- int count_check = 0;
- if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
+ while (*count < 3) {
- for (count_check = 0; count_check < 3; count_check++)
- if (address_in_ddr(&completed_addr[*count + count_check]) != 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
+ resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID,
+ resp, sizeof(resp) / sizeof(resp[0]));
- resp_len = mailbox_read_response(0x4, resp);
+ if (resp_len < 0)
+ break;
- while (resp_len >= 0 && *count < 3) {
max_blocks++;
+ rcv_id++;
+
if (mark_last_buffer_xfer_completed(
&completed_addr[*count]) == 0)
*count = *count + 1;
else
break;
- resp_len = mailbox_read_response(0x4, resp);
}
if (*count <= 0) {
if (resp_len != MBOX_NO_RESPONSE &&
resp_len != MBOX_TIMEOUT && resp_len != 0) {
+ mailbox_clear_response();
return INTEL_SIP_SMC_STATUS_ERROR;
}
@@ -218,13 +186,17 @@ int intel_fpga_config_completed_write(uint32_t *completed_addr,
return status;
}
-int intel_fpga_config_start(uint32_t config_type)
+static int intel_fpga_config_start(uint32_t config_type)
{
uint32_t response[3];
int status = 0;
- status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0,
- response);
+ mailbox_clear_response();
+
+ mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0);
+
+ status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0,
+ response, sizeof(response) / sizeof(response[0]));
if (status < 0)
return status;
@@ -243,47 +215,133 @@ int intel_fpga_config_start(uint32_t config_type)
blocks_submitted = 0;
current_block = 0;
+ read_block = 0;
current_buffer = 0;
+ send_id = 0;
+ rcv_id = 0;
return 0;
}
+static bool is_fpga_config_buffer_full(void)
+{
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+ if (!fpga_config_buffers[i].write_requested)
+ return false;
+ return true;
+}
+
+static bool is_address_in_ddr_range(uint64_t addr)
+{
+ if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE)
+ return true;
+
+ return false;
+}
-uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
+static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
{
- int i = 0;
- uint32_t status = INTEL_SIP_SMC_STATUS_OK;
+ int i;
- if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
- status = INTEL_SIP_SMC_STATUS_REJECTED;
+ intel_fpga_sdm_write_all();
- if (mem + size > DRAM_BASE + DRAM_SIZE)
- status = INTEL_SIP_SMC_STATUS_REJECTED;
+ if (!is_address_in_ddr_range(mem) ||
+ !is_address_in_ddr_range(mem + size) ||
+ is_fpga_config_buffer_full())
+ return INTEL_SIP_SMC_STATUS_REJECTED;
for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
- if (!fpga_config_buffers[i].write_requested) {
- fpga_config_buffers[i].addr = mem;
- fpga_config_buffers[i].size = size;
- fpga_config_buffers[i].size_written = 0;
- fpga_config_buffers[i].write_requested = 1;
- fpga_config_buffers[i].block_number =
+ int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE;
+
+ if (!fpga_config_buffers[j].write_requested) {
+ fpga_config_buffers[j].addr = mem;
+ fpga_config_buffers[j].size = size;
+ fpga_config_buffers[j].size_written = 0;
+ fpga_config_buffers[j].write_requested = 1;
+ fpga_config_buffers[j].block_number =
blocks_submitted++;
- fpga_config_buffers[i].subblocks_sent = 0;
+ fpga_config_buffers[j].subblocks_sent = 0;
break;
}
}
+ if (is_fpga_config_buffer_full())
+ return INTEL_SIP_SMC_STATUS_BUSY;
- if (i == FPGA_CONFIG_BUFFER_SIZE) {
- status = INTEL_SIP_SMC_STATUS_REJECTED;
- return status;
- } else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
- status = INTEL_SIP_SMC_STATUS_BUSY;
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+static int is_out_of_sec_range(uint64_t reg_addr)
+{
+ switch (reg_addr) {
+ case(0xF8011100): /* ECCCTRL1 */
+ case(0xF8011104): /* ECCCTRL2 */
+ case(0xF8011110): /* ERRINTEN */
+ case(0xF8011114): /* ERRINTENS */
+ case(0xF8011118): /* ERRINTENR */
+ case(0xF801111C): /* INTMODE */
+ case(0xF8011120): /* INTSTAT */
+ case(0xF8011124): /* DIAGINTTEST */
+ case(0xF801112C): /* DERRADDRA */
+ case(0xFFD12028): /* SDMMCGRP_CTRL */
+ case(0xFFD12044): /* EMAC0 */
+ case(0xFFD12048): /* EMAC1 */
+ case(0xFFD1204C): /* EMAC2 */
+ case(0xFFD12090): /* ECC_INT_MASK_VALUE */
+ case(0xFFD12094): /* ECC_INT_MASK_SET */
+ case(0xFFD12098): /* ECC_INT_MASK_CLEAR */
+ case(0xFFD1209C): /* ECC_INTSTATUS_SERR */
+ case(0xFFD120A0): /* ECC_INTSTATUS_DERR */
+ case(0xFFD120C0): /* NOC_TIMEOUT */
+ case(0xFFD120C4): /* NOC_IDLEREQ_SET */
+ case(0xFFD120C8): /* NOC_IDLEREQ_CLR */
+ case(0xFFD120D0): /* NOC_IDLEACK */
+ case(0xFFD120D4): /* NOC_IDLESTATUS */
+ case(0xFFD12200): /* BOOT_SCRATCH_COLD0 */
+ case(0xFFD12204): /* BOOT_SCRATCH_COLD1 */
+ case(0xFFD12220): /* BOOT_SCRATCH_COLD8 */
+ case(0xFFD12224): /* BOOT_SCRATCH_COLD9 */
+ return 0;
+
+ default:
+ break;
}
- intel_fpga_sdm_write_all();
+ return -1;
+}
- return status;
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval)
+{
+ if (is_out_of_sec_range(reg_addr))
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ *retval = mmio_read_32(reg_addr);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+ uint32_t *retval)
+{
+ if (is_out_of_sec_range(reg_addr))
+ return INTEL_SIP_SMC_STATUS_ERROR;
+
+ mmio_write_32(reg_addr, val);
+
+ return intel_secure_reg_read(reg_addr, retval);
+}
+
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+ uint32_t val, uint32_t *retval)
+{
+ if (!intel_secure_reg_read(reg_addr, retval)) {
+ *retval &= ~mask;
+ *retval |= val;
+ return intel_secure_reg_write(reg_addr, *retval, retval);
+ }
+
+ return INTEL_SIP_SMC_STATUS_ERROR;
}
/*
@@ -299,6 +357,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
+ uint32_t val = 0;
uint32_t status = INTEL_SIP_SMC_STATUS_OK;
uint32_t completed_addr[3];
uint32_t count = 0;
@@ -307,25 +366,25 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
case SIP_SVC_UID:
/* Return UID to the caller */
SMC_UUID_RET(handle, intl_svc_uid);
- break;
+
case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
status = intel_mailbox_fpga_config_isdone();
SMC_RET4(handle, status, 0, 0, 0);
- break;
+
case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
- break;
+
case INTEL_SIP_SMC_FPGA_CONFIG_START:
status = intel_fpga_config_start(x1);
SMC_RET4(handle, status, 0, 0, 0);
- break;
+
case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
status = intel_fpga_config_write(x1, x2);
SMC_RET4(handle, status, 0, 0, 0);
- break;
+
case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
status = intel_fpga_config_completed_write(completed_addr,
&count);
@@ -333,25 +392,38 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
case 1:
SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
completed_addr[0], 0, 0);
- break;
+
case 2:
SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
completed_addr[0],
completed_addr[1], 0);
- break;
+
case 3:
SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
completed_addr[0],
completed_addr[1],
completed_addr[2]);
- break;
+
case 0:
SMC_RET4(handle, status, 0, 0, 0);
- break;
+
default:
+ mailbox_clear_response();
SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
}
- break;
+
+ case INTEL_SIP_SMC_REG_READ:
+ status = intel_secure_reg_read(x1, &val);
+ SMC_RET3(handle, status, val, x1);
+
+ case INTEL_SIP_SMC_REG_WRITE:
+ status = intel_secure_reg_write(x1, (uint32_t)x2, &val);
+ SMC_RET3(handle, status, val, x1);
+
+ case INTEL_SIP_SMC_REG_UPDATE:
+ status = intel_secure_reg_update(x1, (uint32_t)x2,
+ (uint32_t)x3, &val);
+ SMC_RET3(handle, status, val, x1);
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
@@ -360,7 +432,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
}
DECLARE_RT_SVC(
- agilex_sip_svc,
+ socfpga_sip_svc,
OEN_SIP_START,
OEN_SIP_END,
SMC_TYPE_FAST,
@@ -369,7 +441,7 @@ DECLARE_RT_SVC(
);
DECLARE_RT_SVC(
- agilex_sip_svc_std,
+ socfpga_sip_svc_std,
OEN_SIP_START,
OEN_SIP_END,
SMC_TYPE_YIELD,
diff --git a/plat/intel/soc/agilex/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c
index 76dd81f756..a2f2c184c6 100644
--- a/plat/intel/soc/agilex/socfpga_storage.c
+++ b/plat/intel/soc/common/socfpga_storage.c
@@ -19,7 +19,7 @@
#include <lib/mmio.h>
#include <tools_share/firmware_image_package.h>
-#include "agilex_private.h"
+#include "socfpga_private.h"
#define PLAT_FIP_BASE (0)
#define PLAT_FIP_MAX_SIZE (0x1000000)
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index f24bbdec48..85a60d651c 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -1,37 +1,29 @@
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
-#include <drivers/arm/gicv2.h>
-
-#include <drivers/generic_delay_timer.h>
-#include <drivers/console.h>
-#include <drivers/ti/uart/uart_16550.h>
#include <common/bl_common.h>
#include <common/debug.h>
#include <common/desc_image_load.h>
-#include <errno.h>
-#include <drivers/io/io_storage.h>
-#include <common/image_decompress.h>
-#include <plat/common/platform.h>
-#include <platform_def.h>
-#include <socfpga_private.h>
+#include <drivers/generic_delay_timer.h>
#include <drivers/synopsys/dw_mmc.h>
-#include <lib/mmio.h>
+#include <drivers/ti/uart/uart_16550.h>
#include <lib/xlat_tables/xlat_tables.h>
-#include "s10_memory_controller.h"
-#include "s10_reset_manager.h"
+#include "qspi/cadence_qspi.h"
+#include "socfpga_handoff.h"
+#include "socfpga_mailbox.h"
+#include "socfpga_private.h"
#include "s10_clock_manager.h"
-#include "s10_handoff.h"
+#include "s10_memory_controller.h"
#include "s10_pinmux.h"
-#include "stratix10_private.h"
-#include "include/s10_mailbox.h"
-#include "qspi/cadence_qspi.h"
+#include "s10_reset_manager.h"
+#include "s10_system_manager.h"
#include "wdt/watchdog.h"
@@ -63,7 +55,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1,
generic_delay_timer_init();
- if (s10_get_handoff(&reverse_handoff_ptr))
+ if (socfpga_get_handoff(&reverse_handoff_ptr))
return;
config_pinmux(&reverse_handoff_ptr);
boot_source = reverse_handoff_ptr.boot_source;
@@ -115,7 +107,7 @@ void bl2_el3_plat_arch_setup(void)
switch (boot_source) {
case BOOT_SOURCE_SDMMC:
dw_mmc_init(&params, &info);
- stratix10_io_setup(boot_source);
+ socfpga_io_setup(boot_source);
break;
case BOOT_SOURCE_QSPI:
@@ -124,7 +116,7 @@ void bl2_el3_plat_arch_setup(void)
cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL,
QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS,
QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0);
- stratix10_io_setup(boot_source);
+ socfpga_io_setup(boot_source);
break;
default:
diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c
index 7c9833b338..29bd1763fb 100644
--- a/plat/intel/soc/stratix10/bl31_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl31_plat_setup.c
@@ -1,29 +1,22 @@
/*
* Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019, Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <assert.h>
#include <arch.h>
#include <arch_helpers.h>
+#include <assert.h>
#include <common/bl_common.h>
-#include <common/debug.h>
-#include <drivers/console.h>
-#include <drivers/delay_timer.h>
-#include <drivers/arm/gic_common.h>
#include <drivers/arm/gicv2.h>
#include <drivers/ti/uart/uart_16550.h>
-#include <drivers/generic_delay_timer.h>
-#include <drivers/arm/gicv2.h>
-#include <s10_mailbox.h>
#include <lib/xlat_tables/xlat_tables.h>
#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <platform_def.h>
-#include "stratix10_private.h"
-#include "s10_handoff.h"
+#include "socfpga_private.h"
#include "s10_reset_manager.h"
#include "s10_memory_controller.h"
#include "s10_pinmux.h"
@@ -60,37 +53,47 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
void *from_bl2 = (void *) arg0;
bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
-
assert(params_from_bl2 != NULL);
- assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
- assert(params_from_bl2->h.version >= VERSION_2);
/*
* Copy BL32 (if populated by BL31) and BL33 entry point information.
* They are stored in Secure RAM, in BL31's address space.
*/
- bl_params_node_t *bl_params = params_from_bl2->head;
+ if (params_from_bl2->h.type == PARAM_BL_PARAMS &&
+ params_from_bl2->h.version >= VERSION_2) {
- while (bl_params) {
- if (bl_params->image_id == BL33_IMAGE_ID)
- bl33_image_ep_info = *bl_params->ep_info;
+ bl_params_node_t *bl_params = params_from_bl2->head;
- bl_params = bl_params->next_params_info;
+ while (bl_params) {
+ if (bl_params->image_id == BL33_IMAGE_ID)
+ bl33_image_ep_info = *bl_params->ep_info;
+
+ bl_params = bl_params->next_params_info;
+ }
+ } else {
+ struct socfpga_bl31_params *arg_from_bl2 =
+ (struct socfpga_bl31_params *) from_bl2;
+
+ assert(arg_from_bl2->h.type == PARAM_BL31);
+ assert(arg_from_bl2->h.version >= VERSION_1);
+
+ bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
+ bl33_image_ep_info = *arg_from_bl2->bl33_ep_info;
}
SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
}
static const interrupt_prop_t s10_interrupt_props[] = {
- PLAT_INTEL_S10_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
- PLAT_INTEL_S10_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
+ PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0),
+ PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0)
};
static unsigned int target_mask_array[PLATFORM_CORE_COUNT];
static const gicv2_driver_data_t plat_gicv2_gic_data = {
- .gicd_base = PLAT_INTEL_S10_GICD_BASE,
- .gicc_base = PLAT_INTEL_S10_GICC_BASE,
+ .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE,
+ .gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE,
.interrupt_props = s10_interrupt_props,
.interrupt_props_num = ARRAY_SIZE(s10_interrupt_props),
.target_masks = target_mask_array,
@@ -107,6 +110,10 @@ void bl31_platform_setup(void)
gicv2_distif_init();
gicv2_pcpu_distif_init();
gicv2_cpuif_enable();
+
+ /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */
+ mmio_write_64(PLAT_CPU_RELEASE_ADDR,
+ (uint64_t)plat_secondary_cpus_bl31_entry);
}
const mmap_region_t plat_stratix10_mmap[] = {
diff --git a/plat/intel/soc/stratix10/include/platform_def.h b/plat/intel/soc/stratix10/include/platform_def.h
deleted file mode 100644
index a753acd20e..0000000000
--- a/plat/intel/soc/stratix10/include/platform_def.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (c) 2019, 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/bl_common.h>
-#include <common/interrupt_props.h>
-#include <common/tbbr/tbbr_img_def.h>
-#include <drivers/arm/gic_common.h>
-#include <plat/common/common_def.h>
-
-
-#define PLAT_CPUID_RELEASE 0xffe1b000
-#define PLAT_SEC_ENTRY 0xffe1b008
-
-/* Define next boot image name and offset */
-#define PLAT_NS_IMAGE_OFFSET 0x50000
-#define PLAT_HANDOFF_OFFSET 0xFFE3F000
-
-/*******************************************************************************
- * Platform binary types for linking
- ******************************************************************************/
-#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
-#define PLATFORM_LINKER_ARCH aarch64
-
-/* Stratix 10 supports up to 124GB RAM */
-#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 39)
-#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 39)
-
-
-/*******************************************************************************
- * Generic platform constants
- ******************************************************************************/
-#define PLAT_PRIMARY_CPU 0
-#define PLAT_SECONDARY_ENTRY_BASE 0x01f78bf0
-
-/* Size of cacheable stacks */
-#define PLATFORM_STACK_SIZE 0x2000
-
-/* PSCI related constant */
-#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 PLATFORM_SYSTEM_COUNT 1
-#define PLATFORM_CLUSTER_COUNT 1
-#define PLATFORM_CLUSTER0_CORE_COUNT 4
-#define PLATFORM_CLUSTER1_CORE_COUNT 0
-#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \
- PLATFORM_CLUSTER0_CORE_COUNT)
-#define PLATFORM_MAX_CPUS_PER_CLUSTER 4
-
-/* Interrupt related constant */
-
-#define INTEL_S10_IRQ_SEC_PHY_TIMER 29
-
-#define INTEL_S10_IRQ_SEC_SGI_0 8
-#define INTEL_S10_IRQ_SEC_SGI_1 9
-#define INTEL_S10_IRQ_SEC_SGI_2 10
-#define INTEL_S10_IRQ_SEC_SGI_3 11
-#define INTEL_S10_IRQ_SEC_SGI_4 12
-#define INTEL_S10_IRQ_SEC_SGI_5 13
-#define INTEL_S10_IRQ_SEC_SGI_6 14
-#define INTEL_S10_IRQ_SEC_SGI_7 15
-
-#define TSP_IRQ_SEC_PHY_TIMER INTEL_S10_IRQ_SEC_PHY_TIMER
-#define TSP_SEC_MEM_BASE BL32_BASE
-#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE + 1)
-/*******************************************************************************
- * Platform memory map related constants
- ******************************************************************************/
-#define DRAM_BASE (0x0)
-#define DRAM_SIZE (0x80000000)
-
-#define OCRAM_BASE (0xFFE00000)
-#define OCRAM_SIZE (0x00040000)
-
-#define MEM64_BASE (0x0100000000)
-#define MEM64_SIZE (0x1F00000000)
-
-#define DEVICE1_BASE (0x80000000)
-#define DEVICE1_SIZE (0x60000000)
-
-#define DEVICE2_BASE (0xF7000000)
-#define DEVICE2_SIZE (0x08E00000)
-
-#define DEVICE3_BASE (0xFFFC0000)
-#define DEVICE3_SIZE (0x00008000)
-
-#define DEVICE4_BASE (0x2000000000)
-#define DEVICE4_SIZE (0x0100000000)
-
-/*******************************************************************************
- * BL31 specific defines.
- ******************************************************************************/
-/*
- * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if
- * present). BL31_BASE is calculated using the current BL3-1 debug size plus a
- * little space for growth.
- */
-
-
-#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n"
-
-#define BL1_RO_BASE (0xffe00000)
-#define BL1_RO_LIMIT (0xffe0f000)
-#define BL1_RW_BASE (0xffe10000)
-#define BL1_RW_LIMIT (0xffe1ffff)
-#define BL1_RW_SIZE (0x14000)
-
-#define BL2_BASE (0xffe00000)
-#define BL2_LIMIT (0xffe1b000)
-
-#define BL31_BASE (0xffe1c000)
-#define BL31_LIMIT (0xffe3bfff)
-
-/*******************************************************************************
- * Platform specific page table and MMU setup constants
- ******************************************************************************/
-#define MAX_XLAT_TABLES 8
-#define MAX_MMAP_REGIONS 16
-
-/*******************************************************************************
- * 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 (1 << CACHE_WRITEBACK_SHIFT)
-
-#define PLAT_GIC_BASE (0xFFFC0000)
-#define PLAT_GICC_BASE (PLAT_GIC_BASE + 0x2000)
-#define PLAT_GICD_BASE (PLAT_GIC_BASE + 0x1000)
-#define PLAT_GICR_BASE 0
-
-/*******************************************************************************
- * UART related constants
- ******************************************************************************/
-#define PLAT_UART0_BASE (0xFFC02000)
-#define PLAT_UART1_BASE (0xFFC02100)
-
-#define CRASH_CONSOLE_BASE PLAT_UART0_BASE
-
-#define PLAT_BAUDRATE (115200)
-#define PLAT_UART_CLOCK (100000000)
-
-/*******************************************************************************
- * System counter frequency related constants
- ******************************************************************************/
-#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000)
-#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400)
-
-#define PLAT_INTEL_S10_GICD_BASE PLAT_GICD_BASE
-#define PLAT_INTEL_S10_GICC_BASE PLAT_GICC_BASE
-
-/*
- * 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_INTEL_S10_G1S_IRQ_PROPS(grp) \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \
- grp, GIC_INTR_CFG_LEVEL), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE), \
- INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \
- GIC_INTR_CFG_EDGE)
-
-#define PLAT_INTEL_S10_G0_IRQ_PROPS(grp)
-
-#define MAX_IO_HANDLES 4
-#define MAX_IO_DEVICES 4
-#define MAX_IO_BLOCK_DEVICES 2
-
-
-#endif /* __PLATFORM_DEF_H__ */
-
diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h
index c800b9cf70..acc700a07b 100644
--- a/plat/intel/soc/stratix10/include/s10_clock_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h
@@ -7,7 +7,7 @@
#ifndef __CLOCKMANAGER_H__
#define __CLOCKMANAGER_H__
-#include "s10_handoff.h"
+#include "socfpga_handoff.h"
#define ALT_CLKMGR 0xffd10000
diff --git a/plat/intel/soc/stratix10/include/s10_handoff.h b/plat/intel/soc/stratix10/include/s10_handoff.h
deleted file mode 100644
index 1cc8d09d2f..0000000000
--- a/plat/intel/soc/stratix10/include/s10_handoff.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef _HANDOFF_H_
-#define _HANDOFF_H_
-
-#define HANDOFF_MAGIC_HEADER 0x424f4f54 /* BOOT */
-#define HANDOFF_MAGIC_PINMUX_SEL 0x504d5558 /* PMUX */
-#define HANDOFF_MAGIC_IOCTLR 0x494f4354 /* IOCT */
-#define HANDOFF_MAGIC_FPGA 0x46504741 /* FPGA */
-#define HANDOFF_MAGIC_IODELAY 0x444c4159 /* DLAY */
-#define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */
-#define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */
-
-typedef struct handoff_t {
- /* header */
- uint32_t header_magic;
- uint32_t header_device;
- uint32_t _pad_0x08_0x10[2];
-
- /* pinmux configuration - select */
- uint32_t pinmux_sel_magic;
- uint32_t pinmux_sel_length;
- uint32_t _pad_0x18_0x20[2];
- uint32_t pinmux_sel_array[96]; /* offset, value */
-
- /* pinmux configuration - io control */
- uint32_t pinmux_io_magic;
- uint32_t pinmux_io_length;
- uint32_t _pad_0x1a8_0x1b0[2];
- uint32_t pinmux_io_array[96]; /* offset, value */
-
- /* pinmux configuration - use fpga switch */
- uint32_t pinmux_fpga_magic;
- uint32_t pinmux_fpga_length;
- uint32_t _pad_0x338_0x340[2];
- uint32_t pinmux_fpga_array[42]; /* offset, value */
- uint32_t _pad_0x3e8_0x3f0[2];
-
- /* pinmux configuration - io delay */
- uint32_t pinmux_delay_magic;
- uint32_t pinmux_delay_length;
- uint32_t _pad_0x3f8_0x400[2];
- uint32_t pinmux_iodelay_array[96]; /* offset, value */
-
- /* clock configuration */
- uint32_t clock_magic;
- uint32_t clock_length;
- uint32_t _pad_0x588_0x590[2];
- uint32_t main_pll_mpuclk;
- uint32_t main_pll_nocclk;
- uint32_t main_pll_cntr2clk;
- uint32_t main_pll_cntr3clk;
- uint32_t main_pll_cntr4clk;
- uint32_t main_pll_cntr5clk;
- uint32_t main_pll_cntr6clk;
- uint32_t main_pll_cntr7clk;
- uint32_t main_pll_cntr8clk;
- uint32_t main_pll_cntr9clk;
- uint32_t main_pll_nocdiv;
- uint32_t main_pll_pllglob;
- uint32_t main_pll_fdbck;
- uint32_t main_pll_pllc0;
- uint32_t main_pll_pllc1;
- uint32_t _pad_0x5cc_0x5d0[1];
- uint32_t per_pll_cntr2clk;
- uint32_t per_pll_cntr3clk;
- uint32_t per_pll_cntr4clk;
- uint32_t per_pll_cntr5clk;
- uint32_t per_pll_cntr6clk;
- uint32_t per_pll_cntr7clk;
- uint32_t per_pll_cntr8clk;
- uint32_t per_pll_cntr9clk;
- uint32_t per_pll_emacctl;
- uint32_t per_pll_gpiodiv;
- uint32_t per_pll_pllglob;
- uint32_t per_pll_fdbck;
- uint32_t per_pll_pllc0;
- uint32_t per_pll_pllc1;
- uint32_t hps_osc_clk_h;
- uint32_t fpga_clk_hz;
-
- /* misc configuration */
- uint32_t misc_magic;
- uint32_t misc_length;
- uint32_t _pad_0x618_0x620[2];
- uint32_t boot_source;
-} handoff;
-
-int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr);
-int s10_get_handoff(handoff *hoff_ptr);
-
-#endif
-
-
diff --git a/plat/intel/soc/stratix10/include/s10_mailbox.h b/plat/intel/soc/stratix10/include/s10_mailbox.h
deleted file mode 100644
index 554c26566a..0000000000
--- a/plat/intel/soc/stratix10/include/s10_mailbox.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __S10_MBOX__
-#define __S10_MBOX__
-
-#define MBOX_OFFSET 0xffa30000
-
-#define MBOX_ATF_CLIENT_ID 0x1
-#define MBOX_JOB_ID 0x1
-
-/* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE 0x1
-#define MBOX_INT_FLAG_RIE 0x2
-#define MBOX_INT_FLAG_UAE 0x100
-#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<4)))
-
-/* Mailbox response and status */
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff)
-#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
-#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
-#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
-#define MBOX_STATUS_UA_MASK (1<<8)
-
-/* Mailbox command and response */
-#define MBOX_CMD_FREE_OFFSET 0x14
-#define MBOX_CMD_BUFFER_SIZE 32
-#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
-#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
-#define MBOX_INDIRECT (1 << 11)
-#define MBOX_INSUFFICIENT_BUFFER -2
-#define MBOX_CIN 0x00
-#define MBOX_ROUT 0x04
-#define MBOX_URG 0x08
-#define MBOX_INT 0x0C
-#define MBOX_COUT 0x20
-#define MBOX_RIN 0x24
-#define MBOX_STATUS 0x2C
-#define MBOX_CMD_BUFFER 0x40
-#define MBOX_RESP_BUFFER 0xC0
-
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_RESP_OK 0
-#define MBOX_RESP_INVALID_CMD 1
-#define MBOX_RESP_UNKNOWN_BR 2
-#define MBOX_RESP_UNKNOWN 3
-#define MBOX_RESP_NOT_CONFIGURED 256
-
-/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM 0x400
-#define MBOX_DOORBELL_FROM_SDM 0x480
-
-/* Mailbox QSPI commands */
-#define MBOX_CMD_RESTART 2
-#define MBOX_CMD_QSPI_OPEN 50
-#define MBOX_CMD_QSPI_CLOSE 51
-#define MBOX_CMD_QSPI_DIRECT 59
-#define MBOX_CMD_GET_IDCODE 16
-#define MBOX_CMD_QSPI_SET_CS 52
-
-/* Mailbox REBOOT commands */
-#define MBOX_CMD_REBOOT_HPS 71
-
-/* Generic error handling */
-#define MBOX_TIMEOUT -2047
-#define MBOX_NO_RESPONSE -2
-#define MBOX_WRONG_ID -3
-
-/* Mailbox status */
-#define RECONFIG_STATUS_STATE 0
-#define RECONFIG_STATUS_PIN_STATUS 2
-#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
-#define PIN_STATUS_NSTATUS (1U << 31)
-#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3)
-#define SOFTFUNC_STATUS_INIT_DONE (1 << 1)
-#define SOFTFUNC_STATUS_CONF_DONE (1 << 0)
-#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000
-
-/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-#define SIP_SVC_VERSION 0x8200ff03
-
-/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR 0
-#define SIP_SVC_VERSION_MINOR 1
-
-/* Mailbox reconfiguration commands */
-#define MBOX_RECONFIG 6
-#define MBOX_RECONFIG_DATA 8
-#define MBOX_RECONFIG_STATUS 9
-
-/* Sip get memory */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
-#define INTEL_SIP_SMC_STATUS_OK 0
-#define INTEL_SIP_SMC_STATUS_ERROR 0x4
-#define INTEL_SIP_SMC_STATUS_BUSY 0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
-#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x1000
-#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216
-
-void mailbox_set_int(int interrupt_input);
-int mailbox_init(void);
-void mailbox_set_qspi_close(void);
-void mailbox_set_qspi_open(void);
-void mailbox_set_qspi_direct(void);
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response);
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent);
-int mailbox_read_response(int job_id, uint32_t *response);
-int mailbox_get_qspi_clock(void);
-void mailbox_reset_cold(void);
-
-#endif
diff --git a/plat/intel/soc/stratix10/include/s10_pinmux.h b/plat/intel/soc/stratix10/include/s10_pinmux.h
index a1ba29ef93..82367d74f4 100644
--- a/plat/intel/soc/stratix10/include/s10_pinmux.h
+++ b/plat/intel/soc/stratix10/include/s10_pinmux.h
@@ -12,7 +12,7 @@
#define S10_PINMUX_PINMUX_EMAC0_USEFPGA 0xffd13300
#define S10_PINMUX_IO0_DELAY 0xffd13400
-#include "s10_handoff.h"
+#include "socfpga_handoff.h"
void config_pinmux(handoff *handoff);
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index a67d689fa8..4abfedb562 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -69,5 +69,3 @@
#define DISABLE_L4_FIREWALL (BIT(0) | BIT(16) | BIT(24))
-void enable_nonsecure_access(void);
-
diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
new file mode 100644
index 0000000000..ab723f79d8
--- /dev/null
+++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLAT_SOCFPGA_DEF_H
+#define PLAT_SOCFPGA_DEF_H
+
+#include <platform_def.h>
+
+/* Platform Setting */
+#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10
+
+/* Register Mapping */
+#define SOCFPGA_MMC_REG_BASE 0xff808000
+
+#define SOCFPGA_RSTMGR_OFST 0xffd11000
+#define SOCFPGA_RSTMGR_MPUMODRST_OFST 0xffd11020
+
+#endif /* PLATSOCFPGA_DEF_H */
+
diff --git a/plat/intel/soc/stratix10/include/stratix10_private.h b/plat/intel/soc/stratix10/include/stratix10_private.h
deleted file mode 100644
index 85aff3aa79..0000000000
--- a/plat/intel/soc/stratix10/include/stratix10_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __S10_PRIVATE_H__
-#define __S10_PRIVATE_H__
-
-#define S10_MMC_REG_BASE 0xff808000
-
-#define EMMC_DESC_SIZE (1<<20)
-#define EMMC_INIT_PARAMS(base, clk) \
- { .bus_width = MMC_BUS_WIDTH_4, \
- .clk_rate = (clk), \
- .desc_base = (base), \
- .desc_size = EMMC_DESC_SIZE, \
- .flags = 0, \
- .reg_base = S10_MMC_REG_BASE, \
- \
- }
-
-typedef enum {
- BOOT_SOURCE_FPGA = 0,
- BOOT_SOURCE_SDMMC,
- BOOT_SOURCE_NAND,
- BOOT_SOURCE_RSVD,
- BOOT_SOURCE_QSPI,
-} boot_source_type;
-
-void enable_nonsecure_access(void);
-void stratix10_io_setup(int boot_source);
-
-#endif
diff --git a/plat/intel/soc/stratix10/plat_psci.c b/plat/intel/soc/stratix10/plat_psci.c
deleted file mode 100644
index f4a970e75c..0000000000
--- a/plat/intel/soc/stratix10/plat_psci.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/debug.h>
-#include <errno.h>
-#include <lib/mmio.h>
-#include <drivers/arm/gic_common.h>
-#include <drivers/arm/gicv2.h>
-#include <plat/common/platform.h>
-#include <lib/psci/psci.h>
-
-#include "platform_def.h"
-#include "s10_reset_manager.h"
-#include "s10_mailbox.h"
-
-#define S10_RSTMGR_OFST 0xffd11000
-#define S10_RSTMGR_MPUMODRST_OFST 0x20
-
-uintptr_t *stratix10_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY;
-uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE;
-
-/*******************************************************************************
- * plat handler called when a CPU is about to enter standby.
- ******************************************************************************/
-void plat_cpu_standby(plat_local_state_t cpu_state)
-{
- /*
- * Enter standby state
- * dsb is good practice before using wfi to enter low power states
- */
- VERBOSE("%s: cpu_state: 0x%x\n", __func__, cpu_state);
- dsb();
- wfi();
-}
-
-/*******************************************************************************
- * plat handler called when a power domain is about to be turned on. The
- * mpidr determines the CPU to be turned on.
- ******************************************************************************/
-int plat_pwr_domain_on(u_register_t mpidr)
-{
- unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr);
-
- VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr);
-
- if (cpu_id == -1)
- return PSCI_E_INTERN_FAIL;
-
- *cpuid_release = cpu_id;
-
- /* release core reset */
- mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
- return PSCI_E_SUCCESS;
-}
-
-/*******************************************************************************
- * plat 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.
- ******************************************************************************/
-void plat_pwr_domain_off(const psci_power_state_t *target_state)
-{
- unsigned int cpu_id = plat_my_core_pos();
-
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
- VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
- __func__, i, target_state->pwr_domain_state[i]);
-
- /* TODO: Prevent interrupts from spuriously waking up this cpu */
- /* gicv2_cpuif_disable(); */
-
- /* assert core reset */
- mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
-}
-
-/*******************************************************************************
- * plat handler called when a power domain is about to be suspended. The
- * target_state encodes the power state that each level should transition to.
- ******************************************************************************/
-void plat_pwr_domain_suspend(const psci_power_state_t *target_state)
-{
- unsigned int cpu_id = plat_my_core_pos();
-
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
- VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
- __func__, i, target_state->pwr_domain_state[i]);
- /* assert core reset */
- mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
-
-}
-
-/*******************************************************************************
- * plat 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.
- ******************************************************************************/
-void plat_pwr_domain_on_finish(const psci_power_state_t *target_state)
-{
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
- VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
- __func__, i, target_state->pwr_domain_state[i]);
-
- /* Program the gic per-cpu distributor or re-distributor interface */
- gicv2_pcpu_distif_init();
- gicv2_set_pe_target_mask(plat_my_core_pos());
-
- /* Enable the gic cpu interface */
- gicv2_cpuif_enable();
-}
-
-/*******************************************************************************
- * plat 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.
- ******************************************************************************/
-void plat_pwr_domain_suspend_finish(const psci_power_state_t *target_state)
-{
- unsigned int cpu_id = plat_my_core_pos();
-
- for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++)
- VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n",
- __func__, i, target_state->pwr_domain_state[i]);
-
- /* release core reset */
- mmio_clrbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST,
- 1 << cpu_id);
-}
-
-/*******************************************************************************
- * plat handlers to shutdown/reboot the system
- ******************************************************************************/
-static void __dead2 plat_system_off(void)
-{
- wfi();
- ERROR("System Off: operation not handled.\n");
- panic();
-}
-
-static void __dead2 plat_system_reset(void)
-{
- INFO("assert Peripheral from Reset\r\n");
-
- deassert_peripheral_reset();
- mailbox_reset_cold();
-
- while (1)
- wfi();
-}
-
-int plat_validate_power_state(unsigned int power_state,
- psci_power_state_t *req_state)
-{
- VERBOSE("%s: power_state: 0x%x\n", __func__, power_state);
-
- return PSCI_E_SUCCESS;
-}
-
-int plat_validate_ns_entrypoint(unsigned long ns_entrypoint)
-{
- VERBOSE("%s: ns_entrypoint: 0x%lx\n", __func__, ns_entrypoint);
- return PSCI_E_SUCCESS;
-}
-
-void plat_get_sys_suspend_power_state(psci_power_state_t *req_state)
-{
- req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE;
- req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE;
-}
-
-/*******************************************************************************
- * 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_psci_pm_ops = {
- .cpu_standby = plat_cpu_standby,
- .pwr_domain_on = plat_pwr_domain_on,
- .pwr_domain_off = plat_pwr_domain_off,
- .pwr_domain_suspend = plat_pwr_domain_suspend,
- .pwr_domain_on_finish = plat_pwr_domain_on_finish,
- .pwr_domain_suspend_finish = plat_pwr_domain_suspend_finish,
- .system_off = plat_system_off,
- .system_reset = plat_system_reset,
- .validate_power_state = plat_validate_power_state,
- .validate_ns_entrypoint = plat_validate_ns_entrypoint,
- .get_sys_suspend_power_state = plat_get_sys_suspend_power_state
-};
-
-/*******************************************************************************
- * Export the platform specific power ops.
- ******************************************************************************/
-int plat_setup_psci_ops(uintptr_t sec_entrypoint,
- const struct plat_psci_ops **psci_ops)
-{
- /* Save warm boot entrypoint.*/
- *stratix10_sec_entry = sec_entrypoint;
-
- *psci_ops = &plat_psci_pm_ops;
- return 0;
-}
diff --git a/plat/intel/soc/stratix10/plat_sip_svc.c b/plat/intel/soc/stratix10/plat_sip_svc.c
deleted file mode 100644
index 2c2332ba9f..0000000000
--- a/plat/intel/soc/stratix10/plat_sip_svc.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/mmio.h>
-#include <s10_mailbox.h>
-#include <tools_share/uuid.h>
-
-/* Number of SiP Calls implemented */
-#define SIP_NUM_CALLS 0x3
-
-/* Total buffer the driver can hold */
-#define FPGA_CONFIG_BUFFER_SIZE 4
-
-int current_block;
-int current_buffer;
-int current_id = 1;
-int max_blocks;
-uint32_t bytes_per_block;
-uint32_t blocks_submitted;
-uint32_t blocks_completed;
-
-struct fpga_config_info {
- uint32_t addr;
- int size;
- int size_written;
- uint32_t write_requested;
- int subblocks_sent;
- int block_number;
-};
-
-/* SiP Service UUID */
-DEFINE_SVC_UUID2(intl_svc_uid,
- 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a,
- 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81);
-
-uint64_t plat_sip_handler(uint32_t smc_fid,
- uint64_t x1,
- uint64_t x2,
- uint64_t x3,
- uint64_t x4,
- void *cookie,
- void *handle,
- uint64_t flags)
-{
- ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
- SMC_RET1(handle, SMC_UNK);
-}
-
-struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE];
-
-static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer)
-{
- uint32_t args[3];
-
- while (max_blocks > 0 && buffer->size > buffer->size_written) {
- if (buffer->size - buffer->size_written <=
- bytes_per_block) {
- args[0] = (1<<8);
- args[1] = buffer->addr + buffer->size_written;
- args[2] = buffer->size - buffer->size_written;
- buffer->size_written +=
- buffer->size - buffer->size_written;
- buffer->subblocks_sent++;
- mailbox_send_cmd_async(0x4,
- MBOX_RECONFIG_DATA,
- args, 3, 0);
- current_buffer++;
- current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
- } else {
- args[0] = (1<<8);
- args[1] = buffer->addr + buffer->size_written;
- args[2] = bytes_per_block;
- buffer->size_written += bytes_per_block;
- mailbox_send_cmd_async(0x4,
- MBOX_RECONFIG_DATA,
- args, 3, 0);
- buffer->subblocks_sent++;
- }
- max_blocks--;
- }
-}
-
-static int intel_fpga_sdm_write_all(void)
-{
- int i;
-
- for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
- intel_fpga_sdm_write_buffer(
- &fpga_config_buffers[current_buffer]);
-
- return 0;
-}
-
-uint32_t intel_mailbox_fpga_config_isdone(void)
-{
- uint32_t args[2];
- uint32_t response[6];
- int status;
-
- status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0,
- response);
-
- if (status < 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if (response[RECONFIG_STATUS_STATE] &&
- response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS))
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_SEU_ERROR)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_CONF_DONE) &&
- (response[RECONFIG_STATUS_SOFTFUNC_STATUS] &
- SOFTFUNC_STATUS_INIT_DONE))
- return INTEL_SIP_SMC_STATUS_OK;
-
- return INTEL_SIP_SMC_STATUS_ERROR;
-}
-
-static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed)
-{
- int i;
-
- for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
- if (fpga_config_buffers[i].block_number == current_block) {
- fpga_config_buffers[i].subblocks_sent--;
- if (fpga_config_buffers[i].subblocks_sent == 0
- && fpga_config_buffers[i].size <=
- fpga_config_buffers[i].size_written) {
- fpga_config_buffers[i].write_requested = 0;
- current_block++;
- *buffer_addr_completed =
- fpga_config_buffers[i].addr;
- return 0;
- }
- }
- }
-
- return -1;
-}
-
-unsigned int address_in_ddr(uint32_t *addr)
-{
- if (((unsigned long long)addr > DRAM_BASE) &&
- ((unsigned long long)addr < DRAM_BASE + DRAM_SIZE))
- return 0;
-
- return -1;
-}
-
-int intel_fpga_config_completed_write(uint32_t *completed_addr,
- uint32_t *count)
-{
- uint32_t status = INTEL_SIP_SMC_STATUS_OK;
- *count = 0;
- int resp_len = 0;
- uint32_t resp[5];
- int all_completed = 1;
- int count_check = 0;
-
- if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- for (count_check = 0; count_check < 3; count_check++)
- if (address_in_ddr(&completed_addr[*count + count_check]) != 0)
- return INTEL_SIP_SMC_STATUS_ERROR;
-
- resp_len = mailbox_read_response(0x4, resp);
-
- while (resp_len >= 0 && *count < 3) {
- max_blocks++;
- if (mark_last_buffer_xfer_completed(
- &completed_addr[*count]) == 0)
- *count = *count + 1;
- else
- break;
- resp_len = mailbox_read_response(0x4, resp);
- }
-
- if (*count <= 0) {
- if (resp_len != MBOX_NO_RESPONSE &&
- resp_len != MBOX_TIMEOUT && resp_len != 0) {
- return INTEL_SIP_SMC_STATUS_ERROR;
- }
-
- *count = 0;
- }
-
- intel_fpga_sdm_write_all();
-
- if (*count > 0)
- status = INTEL_SIP_SMC_STATUS_OK;
- else if (*count == 0)
- status = INTEL_SIP_SMC_STATUS_BUSY;
-
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
- if (fpga_config_buffers[i].write_requested != 0) {
- all_completed = 0;
- break;
- }
- }
-
- if (all_completed == 1)
- return INTEL_SIP_SMC_STATUS_OK;
-
- return status;
-}
-
-int intel_fpga_config_start(uint32_t config_type)
-{
- uint32_t response[3];
- int status = 0;
-
- status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0,
- response);
-
- if (status < 0)
- return status;
-
- max_blocks = response[0];
- bytes_per_block = response[1];
-
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
- fpga_config_buffers[i].size = 0;
- fpga_config_buffers[i].size_written = 0;
- fpga_config_buffers[i].addr = 0;
- fpga_config_buffers[i].write_requested = 0;
- fpga_config_buffers[i].block_number = 0;
- fpga_config_buffers[i].subblocks_sent = 0;
- }
-
- blocks_submitted = 0;
- current_block = 0;
- current_buffer = 0;
-
- return 0;
-}
-
-
-uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size)
-{
- int i = 0;
- uint32_t status = INTEL_SIP_SMC_STATUS_OK;
-
- if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE)
- status = INTEL_SIP_SMC_STATUS_REJECTED;
-
- if (mem + size > DRAM_BASE + DRAM_SIZE)
- status = INTEL_SIP_SMC_STATUS_REJECTED;
-
- for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
- if (!fpga_config_buffers[i].write_requested) {
- fpga_config_buffers[i].addr = mem;
- fpga_config_buffers[i].size = size;
- fpga_config_buffers[i].size_written = 0;
- fpga_config_buffers[i].write_requested = 1;
- fpga_config_buffers[i].block_number =
- blocks_submitted++;
- fpga_config_buffers[i].subblocks_sent = 0;
- break;
- }
- }
-
-
- if (i == FPGA_CONFIG_BUFFER_SIZE) {
- status = INTEL_SIP_SMC_STATUS_REJECTED;
- return status;
- } else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) {
- status = INTEL_SIP_SMC_STATUS_BUSY;
- }
-
- intel_fpga_sdm_write_all();
-
- return status;
-}
-
-/*
- * This function is responsible for handling all SiP calls from the NS world
- */
-
-uintptr_t 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)
-{
- uint32_t status = INTEL_SIP_SMC_STATUS_OK;
- uint32_t completed_addr[3];
- uint32_t count = 0;
-
- switch (smc_fid) {
- case SIP_SVC_UID:
- /* Return UID to the caller */
- SMC_UUID_RET(handle, intl_svc_uid);
- break;
- case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE:
- status = intel_mailbox_fpga_config_isdone();
- SMC_RET4(handle, status, 0, 0, 0);
- break;
- case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM:
- SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK,
- INTEL_SIP_SMC_FPGA_CONFIG_ADDR,
- INTEL_SIP_SMC_FPGA_CONFIG_SIZE -
- INTEL_SIP_SMC_FPGA_CONFIG_ADDR);
- break;
- case INTEL_SIP_SMC_FPGA_CONFIG_START:
- status = intel_fpga_config_start(x1);
- SMC_RET4(handle, status, 0, 0, 0);
- break;
- case INTEL_SIP_SMC_FPGA_CONFIG_WRITE:
- status = intel_fpga_config_write(x1, x2);
- SMC_RET4(handle, status, 0, 0, 0);
- break;
- case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE:
- status = intel_fpga_config_completed_write(completed_addr,
- &count);
- switch (count) {
- case 1:
- SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
- completed_addr[0], 0, 0);
- break;
- case 2:
- SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
- completed_addr[0],
- completed_addr[1], 0);
- break;
- case 3:
- SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK,
- completed_addr[0],
- completed_addr[1],
- completed_addr[2]);
- break;
- case 0:
- SMC_RET4(handle, status, 0, 0, 0);
- break;
- default:
- SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR);
- }
- break;
-
- default:
- return plat_sip_handler(smc_fid, x1, x2, x3, x4,
- cookie, handle, flags);
- }
-}
-
-DECLARE_RT_SVC(
- s10_sip_svc,
- OEN_SIP_START,
- OEN_SIP_END,
- SMC_TYPE_FAST,
- NULL,
- sip_smc_handler
-);
-
-DECLARE_RT_SVC(
- s10_sip_svc_std,
- OEN_SIP_START,
- OEN_SIP_END,
- SMC_TYPE_YIELD,
- NULL,
- sip_smc_handler
-);
diff --git a/plat/intel/soc/stratix10/plat_storage.c b/plat/intel/soc/stratix10/plat_storage.c
deleted file mode 100644
index 0b8b9cd2ac..0000000000
--- a/plat/intel/soc/stratix10/plat_storage.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <assert.h>
-#include <common/debug.h>
-#include <drivers/mmc.h>
-#include <tools_share/firmware_image_package.h>
-#include <drivers/io/io_block.h>
-#include <drivers/io/io_driver.h>
-#include <drivers/io/io_fip.h>
-#include <drivers/io/io_memmap.h>
-#include <drivers/io/io_storage.h>
-#include <lib/mmio.h>
-#include <drivers/partition/partition.h>
-#include <lib/semihosting.h>
-#include <string.h>
-#include <lib/utils.h>
-#include <common/tbbr/tbbr_img_def.h>
-#include "platform_def.h"
-#include "stratix10_private.h"
-
-#define STRATIX10_FIP_BASE (0)
-#define STRATIX10_FIP_MAX_SIZE (0x1000000)
-#define STRATIX10_MMC_DATA_BASE (0xffe3c000)
-#define STRATIX10_MMC_DATA_SIZE (0x2000)
-#define STRATIX10_QSPI_DATA_BASE (0x3C00000)
-#define STRATIX10_QSPI_DATA_SIZE (0x1000000)
-
-
-static const io_dev_connector_t *fip_dev_con;
-static const io_dev_connector_t *boot_dev_con;
-
-static uintptr_t fip_dev_handle;
-static uintptr_t boot_dev_handle;
-
-static const io_uuid_spec_t bl2_uuid_spec = {
- .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
-};
-
-static const io_uuid_spec_t bl31_uuid_spec = {
- .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
-};
-
-static const io_uuid_spec_t bl33_uuid_spec = {
- .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
-};
-
-uintptr_t a2_lba_offset;
-const char a2[] = {0xa2, 0x0};
-
-static const io_block_spec_t gpt_block_spec = {
- .offset = 0,
- .length = MMC_BLOCK_SIZE
-};
-
-static int check_fip(const uintptr_t spec);
-static int check_dev(const uintptr_t spec);
-
-static io_block_dev_spec_t boot_dev_spec;
-static int (*register_io_dev)(const io_dev_connector_t **);
-
-static io_block_spec_t fip_spec = {
- .offset = STRATIX10_FIP_BASE,
- .length = STRATIX10_FIP_MAX_SIZE,
-};
-
-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[] = {
- [FIP_IMAGE_ID] = {
- &boot_dev_handle,
- (uintptr_t)&fip_spec,
- check_dev
- },
- [BL2_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl2_uuid_spec,
- check_fip
- },
- [BL31_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t)&bl31_uuid_spec,
- check_fip
- },
- [BL33_IMAGE_ID] = {
- &fip_dev_handle,
- (uintptr_t) &bl33_uuid_spec,
- check_fip
- },
- [GPT_IMAGE_ID] = {
- &boot_dev_handle,
- (uintptr_t) &gpt_block_spec,
- check_dev
- },
-};
-
-static int check_dev(const uintptr_t spec)
-{
- int result;
- uintptr_t local_handle;
-
- result = io_dev_init(boot_dev_handle, (uintptr_t)NULL);
- if (result == 0) {
- result = io_open(boot_dev_handle, spec, &local_handle);
- if (result == 0)
- io_close(local_handle);
- }
- return result;
-}
-
-static int check_fip(const uintptr_t spec)
-{
- int result;
- uintptr_t local_image_handle;
-
- 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)
- io_close(local_image_handle);
- }
- return result;
-}
-
-void stratix10_io_setup(int boot_source)
-{
- int result;
-
- switch (boot_source) {
- case BOOT_SOURCE_SDMMC:
- register_io_dev = &register_io_dev_block;
- boot_dev_spec.buffer.offset = STRATIX10_MMC_DATA_BASE;
- boot_dev_spec.buffer.length = MMC_BLOCK_SIZE;
- boot_dev_spec.ops.read = mmc_read_blocks;
- boot_dev_spec.ops.write = mmc_write_blocks;
- boot_dev_spec.block_size = MMC_BLOCK_SIZE;
- break;
-
- case BOOT_SOURCE_QSPI:
- register_io_dev = &register_io_dev_memmap;
- fip_spec.offset = fip_spec.offset + STRATIX10_QSPI_DATA_BASE;
- break;
-
- default:
- ERROR("Unsupported boot source\n");
- panic();
- break;
- }
-
- result = (*register_io_dev)(&boot_dev_con);
- assert(result == 0);
-
- result = register_io_dev_fip(&fip_dev_con);
- assert(result == 0);
-
- result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec,
- &boot_dev_handle);
- assert(result == 0);
-
- result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle);
- assert(result == 0);
-
- if (boot_source == BOOT_SOURCE_SDMMC) {
- partition_init(GPT_IMAGE_ID);
- fip_spec.offset = get_partition_entry(a2)->start;
- }
-
- (void)result;
-}
-
-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);
- assert(result == 0);
-
- *image_spec = policy->image_spec;
- *dev_handle = *(policy->dev_handle);
-
- return result;
-}
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 34674b0cdb..e7251c4288 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -1,5 +1,6 @@
#
# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2019, Intel Corporation. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -10,61 +11,54 @@ PLAT_INCLUDES := \
-Iplat/intel/soc/common/include/
PLAT_BL_COMMON_SOURCES := \
- lib/xlat_tables/xlat_tables_common.c \
- lib/xlat_tables/aarch64/xlat_tables.c \
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 \
drivers/delay_timer/delay_timer.c \
drivers/delay_timer/generic_delay_timer.c \
drivers/ti/uart/aarch64/16550_console.S \
+ lib/xlat_tables/aarch64/xlat_tables.c \
+ lib/xlat_tables/xlat_tables_common.c \
+ plat/common/plat_gicv2.c \
plat/intel/soc/common/aarch64/platform_common.c \
plat/intel/soc/common/aarch64/plat_helpers.S
BL2_SOURCES += \
- drivers/partition/partition.c \
- drivers/partition/gpt.c \
- drivers/arm/pl061/pl061_gpio.c \
+ common/desc_image_load.c \
drivers/mmc/mmc.c \
- drivers/synopsys/emmc/dw_mmc.c \
+ drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \
drivers/io/io_storage.c \
drivers/io/io_block.c \
drivers/io/io_fip.c \
- drivers/gpio/gpio.c \
- drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \
+ drivers/partition/partition.c \
+ drivers/partition/gpt.c \
+ drivers/synopsys/emmc/dw_mmc.c \
+ lib/cpus/aarch64/cortex_a53.S \
plat/intel/soc/stratix10/bl2_plat_setup.c \
- plat/intel/soc/stratix10/plat_storage.c \
- plat/intel/soc/common/bl2_plat_mem_params_desc.c \
- plat/intel/soc/stratix10/soc/s10_reset_manager.c \
- plat/intel/soc/stratix10/soc/s10_handoff.c \
plat/intel/soc/stratix10/soc/s10_clock_manager.c \
- plat/intel/soc/stratix10/soc/s10_pinmux.c \
plat/intel/soc/stratix10/soc/s10_memory_controller.c \
+ plat/intel/soc/stratix10/soc/s10_pinmux.c \
+ plat/intel/soc/stratix10/soc/s10_reset_manager.c \
+ plat/intel/soc/stratix10/soc/s10_system_manager.c \
+ plat/intel/soc/common/bl2_plat_mem_params_desc.c \
plat/intel/soc/common/socfpga_delay_timer.c \
- lib/cpus/aarch64/cortex_a53.S \
plat/intel/soc/common/socfpga_image_load.c \
- plat/intel/soc/stratix10/soc/s10_system_manager.c \
- common/desc_image_load.c \
- plat/intel/soc/stratix10/soc/s10_mailbox.c \
+ plat/intel/soc/common/socfpga_storage.c \
+ plat/intel/soc/common/soc/socfpga_handoff.c \
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
plat/intel/soc/common/drivers/qspi/cadence_qspi.c \
plat/intel/soc/common/drivers/wdt/watchdog.c
-BL31_SOURCES += drivers/arm/cci/cci.c \
+BL31_SOURCES += \
+ drivers/arm/cci/cci.c \
+ lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
- lib/cpus/aarch64/aem_generic.S \
- lib/cpus/aarch64/cortex_a53.S \
- plat/common/plat_psci_common.c \
- plat/intel/soc/stratix10/plat_sip_svc.c \
- plat/intel/soc/stratix10/bl31_plat_setup.c \
- plat/intel/soc/stratix10/plat_psci.c \
- plat/intel/soc/common/socfpga_topology.c \
- plat/intel/soc/common/socfpga_delay_timer.c \
- plat/intel/soc/stratix10/soc/s10_reset_manager.c\
- plat/intel/soc/stratix10/soc/s10_pinmux.c \
- plat/intel/soc/stratix10/soc/s10_clock_manager.c\
- plat/intel/soc/stratix10/soc/s10_handoff.c \
- plat/intel/soc/stratix10/soc/s10_mailbox.c
+ plat/common/plat_psci_common.c \
+ plat/intel/soc/stratix10/bl31_plat_setup.c \
+ plat/intel/soc/common/socfpga_psci.c \
+ plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_topology.c \
+ plat/intel/soc/common/soc/socfpga_mailbox.c \
PROGRAMMABLE_RESET_ADDRESS := 0
BL2_AT_EL3 := 1
diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
index ed65c2ba8b..e4ff7acf26 100644
--- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c
@@ -12,8 +12,8 @@
#include <platform_def.h>
#include "s10_clock_manager.h"
-#include "s10_handoff.h"
#include "s10_system_manager.h"
+#include "socfpga_handoff.h"
void wait_pll_lock(void)
diff --git a/plat/intel/soc/stratix10/soc/s10_handoff.c b/plat/intel/soc/stratix10/soc/s10_handoff.c
deleted file mode 100644
index 1a4d5c3267..0000000000
--- a/plat/intel/soc/stratix10/soc/s10_handoff.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <drivers/arm/gicv2.h>
-#include <assert.h>
-#include <common/bl_common.h>
-#include <lib/mmio.h>
-#include <string.h>
-#include <plat/common/platform.h>
-#include <platform_def.h>
-
-#include "s10_handoff.h"
-
-#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | \
- (((x) & 0x0000FF00) << 8) | ((x) << 24))
-
-int s10_get_handoff(handoff *reverse_hoff_ptr)
-{
- int i;
- uint32_t *buffer;
- handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET;
-
- memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff));
- buffer = (uint32_t *)reverse_hoff_ptr;
-
- /* convert big indian to little indian */
- for (i = 0; i < sizeof(handoff) / 4; i++)
- buffer[i] = SWAP_UINT32(buffer[i]);
-
- if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER)
- return -1;
- if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL)
- return -1;
- if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR)
- return -1;
- if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA)
- return -1;
- if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY)
- return -1;
-
- return 0;
-}
diff --git a/plat/intel/soc/stratix10/soc/s10_mailbox.c b/plat/intel/soc/stratix10/soc/s10_mailbox.c
deleted file mode 100644
index 00a07f33a4..0000000000
--- a/plat/intel/soc/stratix10/soc/s10_mailbox.c
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 2019, Intel Corporation. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <lib/mmio.h>
-#include <common/debug.h>
-#include "s10_mailbox.h"
-
-static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
- int len)
-{
- uint32_t cmd_free_offset;
- int i;
-
- cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
-
- if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) {
- INFO("Insufficient buffer in mailbox\n");
- return MBOX_INSUFFICIENT_BUFFER;
- }
-
-
- mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4),
- header_cmd);
-
-
- for (i = 0; i < len; i++) {
- cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER +
- (cmd_free_offset++ * 4), args[i]);
- }
-
- cmd_free_offset %= MBOX_CMD_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset);
-
- return 0;
-}
-
-int mailbox_read_response(int job_id, uint32_t *response)
-{
- int rin = 0;
- int rout = 0;
- int response_length = 0;
- int resp = 0;
- int total_resp_len = 0;
- int timeout = 100000;
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
- while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
- if (timeout-- < 0)
- return MBOX_NO_RESPONSE;
- }
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
-
- rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
- rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
-
- while (rout != rin) {
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER + ((rout++)*4));
-
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-
- if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
- MBOX_RESP_JOB_ID(resp) != job_id) {
- return MBOX_WRONG_ID;
- }
-
- if (MBOX_RESP_ERR(resp) > 0) {
- INFO("Error in response: %x\n", resp);
- return -resp;
- }
- response_length = MBOX_RESP_LEN(resp);
-
- while (response_length) {
-
- response_length--;
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER +
- (rout)*4);
- if (response) {
- *(response + total_resp_len) = resp;
- total_resp_len++;
- }
- rout++;
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
- }
- return total_resp_len;
- }
-
- return MBOX_NO_RESPONSE;
-}
-
-
-int mailbox_poll_response(int job_id, int urgent, uint32_t *response)
-{
- int timeout = 80000;
- int rin = 0;
- int rout = 0;
- int response_length = 0;
- int resp = 0;
- int total_resp_len = 0;
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1);
-
- while (1) {
- while (timeout > 0 &&
- mmio_read_32(MBOX_OFFSET +
- MBOX_DOORBELL_FROM_SDM) != 1) {
- timeout--;
- }
-
- if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) {
- INFO("Timed out waiting for SDM");
- return MBOX_TIMEOUT;
- }
-
- mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0);
-
- if (urgent & 1) {
- if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
- MBOX_STATUS_UA_MASK) ^
- (urgent & MBOX_STATUS_UA_MASK)) {
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
- return 0;
- }
-
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 0);
- INFO("Error: Mailbox did not get UA");
- return -1;
- }
-
- rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
- rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
-
- while (rout != rin) {
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER + ((rout++)*4));
-
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
-
- if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID ||
- MBOX_RESP_JOB_ID(resp) != job_id)
- continue;
-
- if (MBOX_RESP_ERR(resp) > 0) {
- INFO("Error in response: %x\n", resp);
- return -MBOX_RESP_ERR(resp);
- }
- response_length = MBOX_RESP_LEN(resp);
-
- while (response_length) {
-
- response_length--;
- resp = mmio_read_32(MBOX_OFFSET +
- MBOX_RESP_BUFFER +
- (rout)*4);
- if (response) {
- *(response + total_resp_len) = resp;
- total_resp_len++;
- }
- rout++;
- rout %= MBOX_RESP_BUFFER_SIZE;
- mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
- }
- return total_resp_len;
- }
- }
-}
-
-void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent)
-{
- if (urgent)
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 1);
-
- fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
- MBOX_JOB_ID_CMD(job_id) |
- MBOX_CMD_LEN_CMD(len) |
- MBOX_INDIRECT |
- cmd, args, len);
-}
-
-int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args,
- int len, int urgent, uint32_t *response)
-{
- int status;
-
- if (urgent) {
- urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
- MBOX_STATUS_UA_MASK;
- mmio_write_32(MBOX_OFFSET + MBOX_URG, 1);
- }
-
- status = fill_mailbox_circular_buffer(
- MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
- MBOX_JOB_ID_CMD(job_id) |
- cmd, args, len);
-
- if (status)
- return status;
-
- return mailbox_poll_response(job_id, urgent, response);
-}
-
-void mailbox_set_int(int interrupt)
-{
-
- mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
- MBOX_UAE_BIT(interrupt));
-}
-
-
-void mailbox_set_qspi_open(void)
-{
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0);
-}
-
-void mailbox_set_qspi_direct(void)
-{
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
-}
-
-void mailbox_set_qspi_close(void)
-{
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0);
-}
-
-int mailbox_get_qspi_clock(void)
-{
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0);
-}
-
-void mailbox_qspi_set_cs(int device_select)
-{
- uint32_t cs_setting = device_select;
-
- /* QSPI device select settings at 31:28 */
- cs_setting = (cs_setting << 28);
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting,
- 1, 0, 0);
-}
-
-void mailbox_reset_cold(void)
-{
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0);
-}
-
-int mailbox_init(void)
-{
- int status = 0;
-
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
- status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0);
-
- if (status)
- return status;
-
- mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
-
- return 0;
-}
-
diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
index ed06f5498f..cb45251491 100644
--- a/plat/intel/soc/stratix10/soc/s10_memory_controller.c
+++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
@@ -22,10 +22,9 @@
#define MAX_MEM_CAL_RETRY 3
#define PRE_CALIBRATION_DELAY 1
#define POST_CALIBRATION_DELAY 1
-#define TIMEOUT_EMIF_CALIBRATION 100
-#define CLEAR_EMIF_DELAY 50000
-#define CLEAR_EMIF_TIMEOUT 0x100000
-#define TIMEOUT_INT_RESP 10000
+#define TIMEOUT_EMIF_CALIBRATION 1000
+#define CLEAR_EMIF_DELAY 1000
+#define CLEAR_EMIF_TIMEOUT 1000
#define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R))
#define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t))
@@ -128,13 +127,13 @@ static int mem_calibration(void)
data = mmio_read_32(S10_MPFE_HMC_ADP_DDRCALSTAT);
if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1)
break;
- udelay(1);
+ udelay(500);
} while (++timeout < TIMEOUT_EMIF_CALIBRATION);
if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) {
status = clear_emif();
- if (status)
- ERROR("Failed to clear Emif\n");
+ if (status)
+ ERROR("Failed to clear Emif\n");
} else {
break;
}
diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk
index ccb662bb2c..bf79ebeec6 100644
--- a/plat/marvell/a8k/common/a8k_common.mk
+++ b/plat/marvell/a8k/common/a8k_common.mk
@@ -37,6 +37,13 @@ DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage
ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin
DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS)
+# Check whether to build system_power.c for the platform
+ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","")
+SYSTEM_POWER_SUPPORT = 1
+else
+SYSTEM_POWER_SUPPORT = 0
+endif
+
# This define specifies DDR type for BLE
$(eval $(call add_define,CONFIG_DDR4))
@@ -82,6 +89,10 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \
BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c
+ifeq ($(SYSTEM_POWER_SUPPORT),1)
+BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c
+endif
+
BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \
$(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \
$(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \
diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c
index d07601a5f7..96e95c2715 100644
--- a/plat/marvell/a8k/common/plat_pm.c
+++ b/plat/marvell/a8k/common/plat_pm.c
@@ -792,8 +792,20 @@ __dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state)
* A8K handlers to shutdown/reboot the system
*****************************************************************************
*/
+
+/* Set a weak stub for platforms that don't configure system power off */
+#pragma weak system_power_off
+int system_power_off(void)
+{
+ return 0;
+}
+
static void __dead2 a8k_system_off(void)
{
+ /* Call the platform specific system power off function */
+ system_power_off();
+
+ /* board doesn't have a system off implementation */
ERROR("%s: needs to be implemented\n", __func__);
panic();
}
diff --git a/plat/mediatek/mt8173/drivers/spm/spm.h b/plat/mediatek/mt8173/drivers/spm/spm.h
index 403303a0df..0c05410a62 100644
--- a/plat/mediatek/mt8173/drivers/spm/spm.h
+++ b/plat/mediatek/mt8173/drivers/spm/spm.h
@@ -320,7 +320,6 @@ void spm_register_init(void);
void spm_go_to_hotplug(void);
void spm_init_event_vector(const struct pcm_desc *pcmdesc);
void spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc);
-void spm_set_sysclk_settle(void);
int is_mcdi_ready(void);
int is_hotplug_ready(void);
int is_suspend_ready(void);
diff --git a/plat/mediatek/mt8183/drivers/spm/spm.c b/plat/mediatek/mt8183/drivers/spm/spm.c
index 547af57819..d6d2344c1c 100644
--- a/plat/mediatek/mt8183/drivers/spm/spm.c
+++ b/plat/mediatek/mt8183/drivers/spm/spm.c
@@ -12,6 +12,12 @@
DEFINE_BAKERY_LOCK(spm_lock);
+/* SPM_DVS_LEVEL */
+#define SPM_VMODEM_LEVEL_MASK (0xff << 16)
+#define SPM_VMODEM_LEVEL (1U << 18)
+#define SPM_VCORE_LEVEL_MASK (0xff)
+#define SPM_VCORE_LEVEL (1U << 1)
+
/* CLK_SCP_CFG_0 */
#define SPM_CK_OFF_CONTROL (0x3FF)
@@ -339,6 +345,11 @@ void spm_boot_init(void)
spm_lock_init();
mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE);
+ /* Set Vmodem / Vcore DVS init level */
+ mmio_clrsetbits_32(SPM_DVS_LEVEL,
+ SPM_VMODEM_LEVEL_MASK | SPM_VCORE_LEVEL_MASK,
+ SPM_VMODEM_LEVEL | SPM_VCORE_LEVEL);
+
/* switch ck_off/axi_26m control to SPM */
mmio_setbits_32(CLK_SCP_CFG_0, SPM_CK_OFF_CONTROL);
mmio_setbits_32(CLK_SCP_CFG_1, SPM_AXI_26M_SEL);
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index a6652766fc..25fd84cdce 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -54,8 +54,9 @@ static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info;
static plat_params_from_bl2_t plat_bl31_params_from_bl2 = {
.tzdram_size = TZDRAM_SIZE
};
-static unsigned long bl32_mem_size;
-static unsigned long bl32_boot_params;
+#ifdef SPD_trusty
+static aapcs64_params_t bl32_args;
+#endif
/*******************************************************************************
* This variable holds the non-secure image entry address
@@ -155,8 +156,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
if (arg_from_bl2->bl32_ep_info != NULL) {
bl32_image_ep_info = *arg_from_bl2->bl32_ep_info;
- bl32_mem_size = arg_from_bl2->bl32_ep_info->args.arg0;
- bl32_boot_params = arg_from_bl2->bl32_ep_info->args.arg2;
+#ifdef SPD_trusty
+ /* save BL32 boot parameters */
+ memcpy(&bl32_args, &arg_from_bl2->bl32_ep_info->args, sizeof(bl32_args));
+#endif
}
/*
@@ -273,17 +276,20 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
#ifdef SPD_trusty
void plat_trusty_set_boot_args(aapcs64_params_t *args)
{
- args->arg0 = bl32_mem_size;
- args->arg1 = bl32_boot_params;
- args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+ /*
+ * arg0 = TZDRAM aperture available for BL32
+ * arg1 = BL32 boot params
+ * arg2 = EKS Blob Length
+ * arg3 = Boot Profiler Carveout Base
+ */
+ args->arg0 = bl32_args.arg0;
+ args->arg1 = bl32_args.arg2;
/* update EKS size */
- if (args->arg4 != 0U) {
- args->arg2 = args->arg4;
- }
+ args->arg2 = bl32_args.arg4;
/* Profiler Carveout Base */
- args->arg3 = args->arg5;
+ args->arg3 = bl32_args.arg5;
}
#endif
diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c
index a8c70eaa5b..39dc42c5ba 100644
--- a/plat/nvidia/tegra/common/tegra_pm.c
+++ b/plat/nvidia/tegra/common/tegra_pm.c
@@ -244,7 +244,7 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state)
/*
* Initialize the GIC cpu and distributor interfaces
*/
- tegra_gic_init();
+ tegra_gic_pcpu_init();
/*
* Check if we are exiting from deep sleep.
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
index 0d1e405967..a0d02c9490 100644
--- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __BPMP_IPC_H__
-#define __BPMP_IPC_H__
+#ifndef BPMP_IPC_H
+#define BPMP_IPC_H
#include <lib/utils_def.h>
#include <stdbool.h>
@@ -44,4 +45,4 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id);
*/
int tegra_bpmp_ipc_disable_clock(uint32_t clk_id);
-#endif /* __BPMP_IPC_H__ */
+#endif /* BPMP_IPC_H */
diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h
index fb5486a8e5..a59df37e3f 100644
--- a/plat/nvidia/tegra/include/drivers/gpcdma.h
+++ b/plat/nvidia/tegra/include/drivers/gpcdma.h
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __GPCDMA_H__
-#define __GPCDMA_H__
+#ifndef GPCDMA_H
+#define GPCDMA_H
#include <stdint.h>
@@ -13,4 +14,4 @@ void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr,
uint32_t num_bytes);
void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes);
-#endif /* __GPCDMA_H__ */
+#endif /* GPCDMA_H */
diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h
index 4ab2f9a236..8a249249b4 100644
--- a/plat/nvidia/tegra/include/drivers/security_engine.h
+++ b/plat/nvidia/tegra/include/drivers/security_engine.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/include/drivers/tegra_gic.h b/plat/nvidia/tegra/include/drivers/tegra_gic.h
index 6106b40a72..6661dff762 100644
--- a/plat/nvidia/tegra/include/drivers/tegra_gic.h
+++ b/plat/nvidia/tegra/include/drivers/tegra_gic.h
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __TEGRA_GIC_H__
-#define __TEGRA_GIC_H__
+#ifndef TEGRA_GIC_H
+#define TEGRA_GIC_H
#include <common/interrupt_props.h>
@@ -26,4 +27,4 @@ void tegra_gic_pcpu_init(void);
void tegra_gic_setup(const interrupt_prop_t *interrupt_props,
unsigned int interrupt_props_num);
-#endif /* __TEGRA_GIC_H__ */
+#endif /* TEGRA_GIC_H */
diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h
index 60f8d804ab..684c872f07 100644
--- a/plat/nvidia/tegra/include/lib/profiler.h
+++ b/plat/nvidia/tegra/include/lib/profiler.h
@@ -1,11 +1,12 @@
/*
* Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __PROFILER_H__
-#define __PROFILER_H__
+#ifndef PROFILER_H
+#define PROFILER_H
/*******************************************************************************
* Number of bytes of memory used by the profiler on Tegra
@@ -16,4 +17,4 @@ void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base);
void boot_profiler_add_record(const char *str);
void boot_profiler_deinit(void);
-#endif /* __PROFILER_H__ */
+#endif /* PROFILER_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h
index e519cdccc6..8f1deb2a37 100644
--- a/plat/nvidia/tegra/include/t194/tegra194_private.h
+++ b/plat/nvidia/tegra/include/t194/tegra194_private.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __TEGRA194_PRIVATE_H__
-#define __TEGRA194_PRIVATE_H__
+#ifndef TEGRA194_PRIVATE_H
+#define TEGRA194_PRIVATE_H
void tegra194_cpu_reset_handler(void);
uint64_t tegra194_get_cpu_reset_handler_base(void);
@@ -13,4 +13,4 @@ uint64_t tegra194_get_cpu_reset_handler_size(void);
uint64_t tegra194_get_smmu_ctx_offset(void);
void tegra194_set_system_suspend_entry(void);
-#endif /* __TEGRA194_PRIVATE_H__ */
+#endif /* TEGRA194_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h
index 1a9ba0a842..e20b2c6343 100644
--- a/plat/nvidia/tegra/include/t194/tegra_def.h
+++ b/plat/nvidia/tegra/include/t194/tegra_def.h
@@ -1,15 +1,21 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __TEGRA_DEF_H__
-#define __TEGRA_DEF_H__
+#ifndef TEGRA_DEF_H
+#define TEGRA_DEF_H
#include <lib/utils_def.h>
/*******************************************************************************
+ * Chip specific page table and MMU setup constants
+ ******************************************************************************/
+#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 40)
+
+/*******************************************************************************
* These values are used by the PSCI implementation during the `CPU_SUSPEND`
* and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state'
* parameter.
@@ -231,4 +237,4 @@
#define TEGRA_SID_XUSB_VF2 U(0x5f)
#define TEGRA_SID_XUSB_VF3 U(0x60)
-#endif /* __TEGRA_DEF_H__ */
+#endif /* TEGRA_DEF_H */
diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
new file mode 100644
index 0000000000..1433a2ea6c
--- /dev/null
+++ b/plat/nvidia/tegra/include/t194/tegra_mc_def.h
@@ -0,0 +1,650 @@
+/*
+ * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * Memory Controller Order_id registers
+ ******************************************************************************/
+#define MC_CLIENT_ORDER_ID_9 U(0x2a24)
+#define MC_CLIENT_ORDER_ID_9_RESET_VAL 0x00000000U
+#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK (0x3U << 12)
+#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID (3U << 12)
+
+#define MC_CLIENT_ORDER_ID_27 U(0x2a6c)
+#define MC_CLIENT_ORDER_ID_27_RESET_VAL 0x00000000U
+#define MC_CLIENT_ORDER_ID_27_PCIE0W_MASK (0x3U << 4)
+#define MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID (1U << 4)
+
+#define MC_CLIENT_ORDER_ID_28 U(0x2a70)
+#define MC_CLIENT_ORDER_ID_28_RESET_VAL 0x00000000U
+#define MC_CLIENT_ORDER_ID_28_PCIE4W_MASK (0x3U << 4)
+#define MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID (3U << 4)
+#define MC_CLIENT_ORDER_ID_28_PCIE5W_MASK (0x3U << 12)
+#define MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID (2U << 12)
+
+#define mc_client_order_id(id, client) \
+ (~MC_CLIENT_ORDER_ID_##id##_##client##_MASK | \
+ MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID)
+
+/*******************************************************************************
+ * Memory Controller's VC ID configuration registers
+ ******************************************************************************/
+#define VC_NISO 0U
+#define VC_SISO 1U
+#define VC_ISO 2U
+
+#define MC_HUB_PC_VC_ID_0 U(0x2a78)
+#define MC_HUB_PC_VC_ID_0_RESET_VAL 0x00020100U
+#define MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK (0x3U << 8)
+#define MC_HUB_PC_VC_ID_0_APB_VC_ID (VC_NISO << 8)
+
+#define MC_HUB_PC_VC_ID_2 U(0x2a80)
+#define MC_HUB_PC_VC_ID_2_RESET_VAL 0x10001000U
+#define MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK (0x3U << 28)
+#define MC_HUB_PC_VC_ID_2_SD_VC_ID (VC_NISO << 28)
+
+#define MC_HUB_PC_VC_ID_4 U(0x2a88)
+#define MC_HUB_PC_VC_ID_4_RESET_VAL 0x10020011U
+#define MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK (0x3U << 28)
+#define MC_HUB_PC_VC_ID_4_NIC_VC_ID (VC_NISO << 28)
+
+#define mc_hub_vc_id(id, client) \
+ (~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK | \
+ MC_HUB_PC_VC_ID_##id##_##client##_VC_ID)
+
+/*******************************************************************************
+ * Memory Controller's PCFIFO client configuration registers
+ ******************************************************************************/
+#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U
+
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U
+#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20200000U
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED (1U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U
+#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x00002800U
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED (0U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK (1U << 21)
+
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU
+#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0x08000080U
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED (0U << 4)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK (1U << 4)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED (0U << 6)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK (1U << 6)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED (0U << 27)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK (1U << 27)
+
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U
+#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0x5552a022U
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED (0U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK (1U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED (0U << 20)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK (1U << 20)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED (0U << 24)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK (1U << 24)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED (0U << 28)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK (1U << 28)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U
+#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0x20000001U
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED (0U << 30)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK (1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG6 0xb90U
+#define MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL 0xaa280000U
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED (0U << 19)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK (1U << 19)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED (0U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK (1U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED (0U << 25)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK (1U << 25)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED (1U << 27)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK (1U << 27)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED (1U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK (1U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED (1U << 31)
+#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK (1U << 31)
+
+#define MC_PCFIFO_CLIENT_CONFIG7 0xaccU
+#define MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL 0x0000000aU
+#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED (0U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK (1U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED (0U << 3)
+#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK (1U << 3)
+
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX 0x7FU
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA 0x660U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0xe0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3f8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1 0x758U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC 0x640U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA 0x5f0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4f8U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2a0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB 0x5f8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1 0x788U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1c8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1 0x780U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U
+#define MC_STREAMID_OVERRIDE_CFG_MIU1R 0x540U
+#define MC_STREAMID_OVERRIDE_CFG_MIU0R 0x530U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1W 0x6d8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA 0x678U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPW 0x418U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1e8U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA 0x600U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3R 0x6f0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU3W 0x588U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4e8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0xb0U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U
+#define MC_STREAMID_OVERRIDE_CFG_MIU2R 0x570U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW 0x6e8U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1 0x770U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB 0x618U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4d0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR 0xa8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW 0x6a8U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2a8U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3f0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4c8U
+#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4d8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU5W 0x7e8U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD 0x6b0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4R 0x700U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0W 0x6c8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1 0x778U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA 0x610U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALW 0x720U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U
+#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR 0x6a0U
+#define MC_STREAMID_OVERRIDE_CFG_RCER 0x690U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3c8U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE4W 0x708U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U
+#define MC_STREAMID_OVERRIDE_CFG_APER 0x3d0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU7R 0x8U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD 0x7c8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU7W 0x10U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1 0x768U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC 0x688U
+#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4c0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU4W 0x598U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1a8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4a0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA 0x620U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1 0x748U
+#define MC_STREAMID_OVERRIDE_CFG_MIU1W 0x548U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4b0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR 0x7d8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC 0x658U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5R 0x710U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB 0x680U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB 0x650U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB 0x628U
+#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR 0x6b8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R 0x6c0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE3W 0x6f8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA 0x630U
+#define MC_STREAMID_OVERRIDE_CFG_MIU6W 0x7f8U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE1R 0x6d0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1 0x7d0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB 0x608U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC 0x670U
+#define MC_STREAMID_OVERRIDE_CFG_MIU0W 0x538U
+#define MC_STREAMID_OVERRIDE_CFG_MIU2W 0x578U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U
+#define MC_STREAMID_OVERRIDE_CFG_AXIAPR 0x410U
+#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4b8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4a8U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB 0x638U
+#define MC_STREAMID_OVERRIDE_CFG_VIFALW 0x5e8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU6R 0x7f0U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3c0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1 0x760U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1 0x798U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4f0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3d8U
+#define MC_STREAMID_OVERRIDE_CFG_MIU5R 0x7e0U
+#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1 0x750U
+#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA 0x648U
+#define MC_STREAMID_OVERRIDE_CFG_ISPFALR 0x228U
+#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU4R 0x590U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U
+#define MC_STREAMID_OVERRIDE_CFG_VIFALR 0x5e0U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR 0x6e0U
+#define MC_STREAMID_OVERRIDE_CFG_RCEW 0x698U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA1 0x790U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4e0U
+#define MC_STREAMID_OVERRIDE_CFG_MIU3R 0x580U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR 0xf8U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U
+#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB 0x668U
+#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U
+#define MC_STREAMID_OVERRIDE_CFG_PCIE5W 0x718U
+
+/*******************************************************************************
+ * Macro to calculate Security cfg register addr from StreamID Override register
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4)
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8)
+
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12)
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12)
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA 0x1624U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1W 0x16dcU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC 0x1644U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB 0x162cU
+#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB 0x1654U
+#define MC_TXN_OVERRIDE_CONFIG_MIU6R 0x17f4U
+#define MC_TXN_OVERRIDE_CONFIG_MIU5R 0x17e4U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1 0x1784U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R 0x16c4U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1 0x178cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1 0x1774U
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR 0x16bcU
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U
+#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R 0x1714U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_MIU6W 0x17fcU
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1 0x179cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1 0x1764U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_MIU7R 0x1008U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA 0x15f4U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR 0x17dcU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1 0x176cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB 0x166cU
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW 0x16ecU
+#define MC_TXN_OVERRIDE_CONFIG_PCIE1R 0x16d4U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC 0x1674U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA 0x164cU
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_MIU1W 0x1548U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE0W 0x16ccU
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD 0x17ccU
+#define MC_TXN_OVERRIDE_CONFIG_MIU7W 0x1010U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_MIU3R 0x1580U
+#define MC_TXN_OVERRIDE_CONFIG_MIU3W 0x158cU
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U
+#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA 0x1634U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_ISPFALR 0x1228U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1 0x175cU
+#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD 0x16b4U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA 0x1664U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1 0x174cU
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_AXIAPR 0x1410U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR 0x16e4U
+#define MC_TXN_OVERRIDE_CONFIG_ISPFALW 0x1724U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_MIU2W 0x1578U
+#define MC_TXN_OVERRIDE_CONFIG_RCER 0x1694U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4W 0x170cU
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1 0x17d4U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA 0x1614U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB 0x161cU
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_RCEW 0x169cU
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA 0x1604U
+#define MC_TXN_OVERRIDE_CONFIG_VIFALR 0x15e4U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3R 0x16f4U
+#define MC_TXN_OVERRIDE_CONFIG_MIU1R 0x1540U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5W 0x171cU
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_MIU0W 0x1538U
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB 0x160cU
+#define MC_TXN_OVERRIDE_CONFIG_VIFALW 0x15ecU
+#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB 0x15fcU
+#define MC_TXN_OVERRIDE_CONFIG_PCIE3W 0x16fcU
+#define MC_TXN_OVERRIDE_CONFIG_MIU0R 0x1530U
+#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC 0x165cU
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_AXIAPW 0x1418U
+#define MC_TXN_OVERRIDE_CONFIG_MIU4R 0x1594U
+#define MC_TXN_OVERRIDE_CONFIG_MIU4W 0x159cU
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1 0x1754U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB 0x1684U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC 0x168cU
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR 0x16a4U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA1 0x1794U
+#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U
+#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW 0x16acU
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1 0x177cU
+#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB 0x163cU
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA 0x167cU
+#define MC_TXN_OVERRIDE_CONFIG_MIU5W 0x17ecU
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_MIU2R 0x1570U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_PCIE4R 0x1704U
+#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U
+
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12)
+
+/*******************************************************************************
+ * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
+ * MC_TXN_OVERRIDE_CONFIG_{module} registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U
+#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U
+#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U
+#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U
+#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL
+
+/*******************************************************************************
+ * Memory Controller Reset Control registers
+ ******************************************************************************/
+#define MC_CLIENT_HOTRESET_CTRL0 0x200U
+#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9)
+#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11)
+#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15)
+#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17)
+#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS0 0x204U
+#define MC_CLIENT_HOTRESET_CTRL1 0x970U
+#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5)
+#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12)
+#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13)
+#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 17)
+#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 21)
+#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 23)
+#define MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB (1U << 26)
+#define MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB (1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS1 0x974U
+#define MC_CLIENT_HOTRESET_CTRL2 0x97cU
+#define MC_CLIENT_HOTRESET_CTRL2_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB (1U << 2)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB (1U << 4)
+#define MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB (1U << 9)
+#define MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB (1U << 10)
+#define MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB (1U << 11)
+#define MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB (1U << 14)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB (1U << 16)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB (1U << 17)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB (1U << 23)
+#define MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB (1U << 25)
+#define MC_CLIENT_HOTRESET_STATUS2 0x1898U
+
+/*******************************************************************************
+ * Tegra TSA Controller constants
+ ******************************************************************************/
+#define TEGRA_TSA_BASE U(0x02000000)
+
+#define TSA_CONFIG_STATIC0_CSR_RESET_R 0x20000000U
+#define TSA_CONFIG_STATIC0_CSW_RESET_W 0x20001000U
+#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV 0x20001000U
+
+#define TSA_CONFIG_STATIC0_CSW_PCIE1W 0x1004U
+#define TSA_CONFIG_STATIC0_CSW_PCIE2AW 0x1008U
+#define TSA_CONFIG_STATIC0_CSW_PCIE3W 0x100cU
+#define TSA_CONFIG_STATIC0_CSW_PCIE4W 0x1028U
+#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW 0x2004U
+#define TSA_CONFIG_STATIC0_CSR_SATAR 0x2010U
+#define TSA_CONFIG_STATIC0_CSW_SATAW 0x2014U
+#define TSA_CONFIG_STATIC0_CSW_PCIE0W 0x2020U
+#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW 0x202cU
+#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR 0x3004U
+#define TSA_CONFIG_STATIC0_CSW_NVENCSWR 0x3010U
+#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR 0x4004U
+#define TSA_CONFIG_STATIC0_CSR_ISPFALR 0x4010U
+#define TSA_CONFIG_STATIC0_CSW_ISPWA 0x4014U
+#define TSA_CONFIG_STATIC0_CSW_ISPWB 0x4018U
+#define TSA_CONFIG_STATIC0_CSW_ISPFALW 0x401cU
+#define TSA_CONFIG_STATIC0_CSW_NVDECSWR 0x5004U
+#define TSA_CONFIG_STATIC0_CSR_EQOSR 0x5010U
+#define TSA_CONFIG_STATIC0_CSW_EQOSW 0x5014U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB 0x5020U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB 0x5024U
+#define TSA_CONFIG_STATIC0_CSW_UFSHCW 0x6004U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCR 0x6010U
+#define TSA_CONFIG_STATIC0_CSR_SDMMCRA 0x6014U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCW 0x6018U
+#define TSA_CONFIG_STATIC0_CSW_SDMMCWA 0x601cU
+#define TSA_CONFIG_STATIC0_CSR_RCER 0x6030U
+#define TSA_CONFIG_STATIC0_CSR_RCEDMAR 0x6034U
+#define TSA_CONFIG_STATIC0_CSW_RCEW 0x6038U
+#define TSA_CONFIG_STATIC0_CSW_RCEDMAW 0x603cU
+#define TSA_CONFIG_STATIC0_CSR_SCER 0x6050U
+#define TSA_CONFIG_STATIC0_CSR_SCEDMAR 0x6054U
+#define TSA_CONFIG_STATIC0_CSW_SCEW 0x6058U
+#define TSA_CONFIG_STATIC0_CSW_SCEDMAW 0x605cU
+#define TSA_CONFIG_STATIC0_CSR_AXIAPR 0x7004U
+#define TSA_CONFIG_STATIC0_CSR_ETRR 0x7008U
+#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR 0x700cU
+#define TSA_CONFIG_STATIC0_CSW_AXIAPW 0x7010U
+#define TSA_CONFIG_STATIC0_CSW_ETRW 0x7014U
+#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD 0x8004U
+#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR 0x8008U
+#define TSA_CONFIG_STATIC0_CSR_AXISR 0x8014U
+#define TSA_CONFIG_STATIC0_CSW_AXISW 0x8018U
+#define TSA_CONFIG_STATIC0_CSR_BPMPR 0x9004U
+#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR 0x9008U
+#define TSA_CONFIG_STATIC0_CSW_BPMPW 0x900cU
+#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW 0x9010U
+#define TSA_CONFIG_STATIC0_CSR_SESRD 0x9024U
+#define TSA_CONFIG_STATIC0_CSR_TSECSRD 0x9028U
+#define TSA_CONFIG_STATIC0_CSR_TSECSRDB 0x902cU
+#define TSA_CONFIG_STATIC0_CSW_SESWR 0x9030U
+#define TSA_CONFIG_STATIC0_CSW_TSECSWR 0x9034U
+#define TSA_CONFIG_STATIC0_CSW_TSECSWRB 0x9038U
+#define TSA_CONFIG_STATIC0_CSW_PCIE5W 0xb004U
+#define TSA_CONFIG_STATIC0_CSW_VICSWR 0xc004U
+#define TSA_CONFIG_STATIC0_CSR_APER 0xd004U
+#define TSA_CONFIG_STATIC0_CSR_APEDMAR 0xd008U
+#define TSA_CONFIG_STATIC0_CSW_APEW 0xd00cU
+#define TSA_CONFIG_STATIC0_CSW_APEDMAW 0xd010U
+#define TSA_CONFIG_STATIC0_CSR_HDAR 0xf004U
+#define TSA_CONFIG_STATIC0_CSW_HDAW 0xf008U
+#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR 0xf014U
+#define TSA_CONFIG_STATIC0_CSR_VIFALR 0x10004U
+#define TSA_CONFIG_STATIC0_CSW_VIW 0x10008U
+#define TSA_CONFIG_STATIC0_CSW_VIFALW 0x1000cU
+#define TSA_CONFIG_STATIC0_CSR_AONR 0x12004U
+#define TSA_CONFIG_STATIC0_CSR_AONDMAR 0x12008U
+#define TSA_CONFIG_STATIC0_CSW_AONW 0x1200cU
+#define TSA_CONFIG_STATIC0_CSW_AONDMAW 0x12010U
+#define TSA_CONFIG_STATIC0_CSR_PCIE1R 0x14004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE2AR 0x14008U
+#define TSA_CONFIG_STATIC0_CSR_PCIE3R 0x1400cU
+#define TSA_CONFIG_STATIC0_CSR_PCIE4R 0x14028U
+#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR 0x15004U
+#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR 0x15010U
+#define TSA_CONFIG_STATIC0_CSR_UFSHCR 0x16004U
+#define TSA_CONFIG_STATIC0_CSW_DLA1WRA 0x18004U
+#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB 0x18010U
+#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB 0x18014U
+#define TSA_CONFIG_STATIC0_CSW_DLA0WRA 0x19004U
+#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB 0x19010U
+#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB 0x19014U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDC 0x1a004U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRC 0x1a008U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRA 0x1a014U
+#define TSA_CONFIG_STATIC0_CSW_PVA1WRB 0x1a020U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRB 0x1b004U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDC 0x1b010U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRC 0x1b014U
+#define TSA_CONFIG_STATIC0_CSW_PVA0WRA 0x1b020U
+#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD 0x1d004U
+#define TSA_CONFIG_STATIC0_CSR_NVENCSRD 0x1d010U
+#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD 0x1e004U
+#define TSA_CONFIG_STATIC0_CSR_ISPRA 0x1e010U
+#define TSA_CONFIG_STATIC0_CSR_NVDECSRD 0x1f004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE0R 0x21004U
+#define TSA_CONFIG_STATIC0_CSR_PCIE5R 0x23004U
+#define TSA_CONFIG_STATIC0_CSR_VICSRD 0x24004U
+#define TSA_CONFIG_STATIC0_CSR_DLA1RDA 0x26004U
+#define TSA_CONFIG_STATIC0_CSR_DLA0RDA 0x27004U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDA 0x28004U
+#define TSA_CONFIG_STATIC0_CSR_PVA1RDB 0x28010U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDB 0x29004U
+#define TSA_CONFIG_STATIC0_CSR_PVA0RDA 0x29010U
+
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (ULL(0x3) << 11)
+#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (ULL(0) << 11)
+
+#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index cd2f77308c..761acdea5e 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -137,7 +137,6 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
void tegra_delay_timer_init(void);
void tegra_secure_entrypoint(void);
-void tegra186_cpu_reset_handler(void);
/* Declarations for tegra_sip_calls.c */
uintptr_t tegra_sip_handler(uint32_t smc_fid,
diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat
index 2f5fd9ecbb..2d6d2b3d2b 100644
--- a/plat/nvidia/tegra/scat/bl31.scat
+++ b/plat/nvidia/tegra/scat/bl31.scat
@@ -95,7 +95,7 @@ LR_RO_DATA +0
/* cpu_ops must always be defined */
ScatterAssert(ImageLength(__CPU_OPS__) > 0)
-#if ENABLE_SPM
+#if SPM_MM
LR_SPM +0
{
/*
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
index 3994b2d755..226ab5bc51 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __MCE_PRIVATE_H__
-#define __MCE_PRIVATE_H__
+#ifndef MCE_PRIVATE_H
+#define MCE_PRIVATE_H
#include <tegra_def.h>
@@ -66,10 +66,9 @@ uint64_t nvg_get_result(void);
uint64_t nvg_cache_clean(void);
uint64_t nvg_cache_clean_inval(void);
uint64_t nvg_cache_inval_all(void);
-int32_t nvg_roc_clean_cache_trbits(void);
void nvg_enable_strict_checking_mode(void);
/* MCE helper functions */
void mce_enable_strict_checking(void);
-#endif /* __MCE_PRIVATE_H__ */
+#endif /* MCE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
index 6e656f6775..e7cf88d05d 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SE_H__
-#define __SE_H__
+#ifndef SE_H
+#define SE_H
int32_t tegra_se_suspend(void);
void tegra_se_resume(void);
-#endif /* __SE_H__ */
+#endif /* SE_H */
diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
index 1dd1f51b90..536ed57c00 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -165,7 +165,7 @@ int32_t nvg_online_core(uint32_t core)
/* sanity check the core ID value */
if (core > (uint32_t)PLATFORM_CORE_COUNT) {
ERROR("%s: unknown core id (%d)\n", __func__, core);
- ret = EINVAL;
+ ret = -EINVAL;
} else {
/* get a core online */
nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE,
@@ -183,15 +183,15 @@ int32_t nvg_online_core(uint32_t core)
*/
int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx)
{
- int32_t ret;
+ int32_t ret = 0;
/* sanity check GSC ID */
if (gsc_idx > (uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR) {
ERROR("%s: unknown gsc_idx (%u)\n", __func__, gsc_idx);
- ret = EINVAL;
+ ret = -EINVAL;
} else {
nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC,
- (uint64_t)gsc_idx);
+ (uint64_t)gsc_idx);
}
return ret;
@@ -209,11 +209,12 @@ int32_t nvg_roc_clean_cache(void)
ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
if (nvg_cache_clean() == 0U) {
ERROR("%s: failed\n", __func__);
- ret = EINVAL;
+ ret = -ENODEV;
}
} else {
- ret = EINVAL;
+ ret = -ENOTSUP;
}
+
return ret;
}
@@ -229,11 +230,12 @@ int32_t nvg_roc_flush_cache(void)
ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
if (nvg_cache_clean_inval() == 0U) {
ERROR("%s: failed\n", __func__);
- ret = EINVAL;
+ ret = -ENODEV;
}
} else {
- ret = EINVAL;
+ ret = -ENOTSUP;
}
+
return ret;
}
@@ -249,11 +251,12 @@ int32_t nvg_roc_clean_cache_trbits(void)
ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) {
if (nvg_cache_inval_all() == 0U) {
ERROR("%s: failed\n", __func__);
- ret = EINVAL;
+ ret = -ENODEV;
}
} else {
- ret = EINVAL;
+ ret = -ENOTSUP;
}
+
return ret;
}
@@ -271,8 +274,8 @@ int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time)
(state != (uint32_t)TEGRA_NVG_CORE_C6) &&
(state != (uint32_t)TEGRA_NVG_CORE_C7))
{
- ERROR("%s: unknown cstate (%d)\n", __func__, state);
- ret = EINVAL;
+ ERROR("%s: unknown cstate (%u)\n", __func__, state);
+ ret = -EINVAL;
} else {
/* time (TSC ticks) until the core is expected to get a wake event */
nvg_set_wake_time(wake_time);
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
index 3df670c922..a9f461071c 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c
@@ -1,4 +1,5 @@
-/*
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
index 7d531bb9de..a2c5d1c381 100644
--- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h
@@ -1,11 +1,12 @@
-/*
- * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
+/*
+ * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __SE_PRIVATE_H__
-#define __SE_PRIVATE_H__
+#ifndef SE_PRIVATE_H
+#define SE_PRIVATE_H
#include <lib/utils_def.h>
@@ -81,4 +82,4 @@ static inline void tegra_se_write_32(uint32_t offset, uint32_t val)
mmio_write_32(TEGRA_SE0_BASE + offset, val);
}
-#endif /* __SE_PRIVATE_H__ */
+#endif /* SE_PRIVATE_H */
diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
index 948fadec9b..fa5ba6263f 100644
--- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c
@@ -26,7 +26,6 @@
#include <tegra_platform.h>
#include <tegra_private.h>
-extern void tegra194_cpu_reset_handler(void);
extern uint32_t __tegra194_cpu_reset_handler_data,
__tegra194_cpu_reset_handler_end;
@@ -66,10 +65,10 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state,
<< TEGRA194_WAKE_TIME_SHIFT;
/*
- * Clean percpu_data[cpu] to DRAM. This needs to be done to ensure that
- * the correct value is read in tegra_soc_pwr_domain_suspend(), which
- * is called with caches disabled. It is possible to read a stale value
- * from DRAM in that function, because the L2 cache is not flushed
+ * Clean t19x_percpu_data[cpu] to DRAM. This needs to be done to ensure
+ * that the correct value is read in tegra_soc_pwr_domain_suspend(),
+ * which is called with caches disabled. It is possible to read a stale
+ * value from DRAM in that function, because the L2 cache is not flushed
* unless the cluster is entering CC6/CC7.
*/
clean_dcache_range((uint64_t)&t19x_percpu_data[cpu],
@@ -125,7 +124,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
(uint32_t)TEGRA_NVG_CORE_C6 : (uint32_t)TEGRA_NVG_CORE_C7;
ret = mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)val,
- percpu_data[cpu].wake_time, 0);
+ t19x_percpu_data[cpu].wake_time, 0);
assert(ret == 0);
} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c
index 1696d59108..640ef4deb0 100644
--- a/plat/nvidia/tegra/soc/t194/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c
@@ -270,143 +270,8 @@ static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = {
mc_make_sid_override_cfg(MIU2W),
mc_make_sid_override_cfg(MIU3R),
mc_make_sid_override_cfg(MIU3W),
- smmu_make_gnsr0_nsec_cfg(CR0),
- smmu_make_gnsr0_sec_cfg(IDR0),
- smmu_make_gnsr0_sec_cfg(IDR1),
- smmu_make_gnsr0_sec_cfg(IDR2),
- smmu_make_gnsr0_nsec_cfg(GFSR),
- smmu_make_gnsr0_nsec_cfg(GFSYNR0),
- smmu_make_gnsr0_nsec_cfg(GFSYNR1),
- smmu_make_gnsr0_nsec_cfg(TLBGSTATUS),
- smmu_make_gnsr0_nsec_cfg(PIDR2),
- smmu_make_smrg_group(0),
- smmu_make_smrg_group(1),
- smmu_make_smrg_group(2),
- smmu_make_smrg_group(3),
- smmu_make_smrg_group(4),
- smmu_make_smrg_group(5),
- smmu_make_smrg_group(6),
- smmu_make_smrg_group(7),
- smmu_make_smrg_group(8),
- smmu_make_smrg_group(9),
- smmu_make_smrg_group(10),
- smmu_make_smrg_group(11),
- smmu_make_smrg_group(12),
- smmu_make_smrg_group(13),
- smmu_make_smrg_group(14),
- smmu_make_smrg_group(15),
- smmu_make_smrg_group(16),
- smmu_make_smrg_group(17),
- smmu_make_smrg_group(18),
- smmu_make_smrg_group(19),
- smmu_make_smrg_group(20),
- smmu_make_smrg_group(21),
- smmu_make_smrg_group(22),
- smmu_make_smrg_group(23),
- smmu_make_smrg_group(24),
- smmu_make_smrg_group(25),
- smmu_make_smrg_group(26),
- smmu_make_smrg_group(27),
- smmu_make_smrg_group(28),
- smmu_make_smrg_group(29),
- smmu_make_smrg_group(30),
- smmu_make_smrg_group(31),
- smmu_make_smrg_group(32),
- smmu_make_smrg_group(33),
- smmu_make_smrg_group(34),
- smmu_make_smrg_group(35),
- smmu_make_smrg_group(36),
- smmu_make_smrg_group(37),
- smmu_make_smrg_group(38),
- smmu_make_smrg_group(39),
- smmu_make_smrg_group(40),
- smmu_make_smrg_group(41),
- smmu_make_smrg_group(42),
- smmu_make_smrg_group(43),
- smmu_make_smrg_group(44),
- smmu_make_smrg_group(45),
- smmu_make_smrg_group(46),
- smmu_make_smrg_group(47),
- smmu_make_smrg_group(48),
- smmu_make_smrg_group(49),
- smmu_make_smrg_group(50),
- smmu_make_smrg_group(51),
- smmu_make_smrg_group(52),
- smmu_make_smrg_group(53),
- smmu_make_smrg_group(54),
- smmu_make_smrg_group(55),
- smmu_make_smrg_group(56),
- smmu_make_smrg_group(57),
- smmu_make_smrg_group(58),
- smmu_make_smrg_group(59),
- smmu_make_smrg_group(60),
- smmu_make_smrg_group(61),
- smmu_make_smrg_group(62),
- smmu_make_smrg_group(63),
- smmu_make_cb_group(0),
- smmu_make_cb_group(1),
- smmu_make_cb_group(2),
- smmu_make_cb_group(3),
- smmu_make_cb_group(4),
- smmu_make_cb_group(5),
- smmu_make_cb_group(6),
- smmu_make_cb_group(7),
- smmu_make_cb_group(8),
- smmu_make_cb_group(9),
- smmu_make_cb_group(10),
- smmu_make_cb_group(11),
- smmu_make_cb_group(12),
- smmu_make_cb_group(13),
- smmu_make_cb_group(14),
- smmu_make_cb_group(15),
- smmu_make_cb_group(16),
- smmu_make_cb_group(17),
- smmu_make_cb_group(18),
- smmu_make_cb_group(19),
- smmu_make_cb_group(20),
- smmu_make_cb_group(21),
- smmu_make_cb_group(22),
- smmu_make_cb_group(23),
- smmu_make_cb_group(24),
- smmu_make_cb_group(25),
- smmu_make_cb_group(26),
- smmu_make_cb_group(27),
- smmu_make_cb_group(28),
- smmu_make_cb_group(29),
- smmu_make_cb_group(30),
- smmu_make_cb_group(31),
- smmu_make_cb_group(32),
- smmu_make_cb_group(33),
- smmu_make_cb_group(34),
- smmu_make_cb_group(35),
- smmu_make_cb_group(36),
- smmu_make_cb_group(37),
- smmu_make_cb_group(38),
- smmu_make_cb_group(39),
- smmu_make_cb_group(40),
- smmu_make_cb_group(41),
- smmu_make_cb_group(42),
- smmu_make_cb_group(43),
- smmu_make_cb_group(44),
- smmu_make_cb_group(45),
- smmu_make_cb_group(46),
- smmu_make_cb_group(47),
- smmu_make_cb_group(48),
- smmu_make_cb_group(49),
- smmu_make_cb_group(50),
- smmu_make_cb_group(51),
- smmu_make_cb_group(52),
- smmu_make_cb_group(53),
- smmu_make_cb_group(54),
- smmu_make_cb_group(55),
- smmu_make_cb_group(56),
- smmu_make_cb_group(57),
- smmu_make_cb_group(58),
- smmu_make_cb_group(59),
- smmu_make_cb_group(60),
- smmu_make_cb_group(61),
- smmu_make_cb_group(62),
- smmu_make_cb_group(63),
+ smmu_make_cfg(TEGRA_SMMU0_BASE),
+ smmu_make_cfg(TEGRA_SMMU2_BASE),
smmu_bypass_cfg, /* TBU settings */
_END_OF_TABLE_,
};
diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
index 33c7e6f789..696a5774e0 100644
--- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S
@@ -12,7 +12,7 @@
#define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7
#define TEGRA194_STATE_SYSTEM_RESUME 0x600D
-#define TEGRA194_SMMU_CTX_SIZE 0x490
+#define TEGRA194_SMMU_CTX_SIZE 0x80B
.align 4
.globl tegra194_cpu_reset_handler
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
index be1f9cc392..352107d2ce 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
index 8d7dbf9e55..d5e0491268 100644
--- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
+++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+/*
+ * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
index 3b124c7893..bf2706d53f 100644
--- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c
+++ b/plat/renesas/rcar/bl2_plat_mem_params_desc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -53,6 +53,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = {
entry_point_info_t, SECURE | EXECUTABLE),
.ep_info.pc = BL32_BASE,
.ep_info.spsr = 0,
+ .ep_info.args.arg3 = (uintptr_t)fdt_blob,
SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2,
image_info_t, 0),
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index b4762f3309..193d80e708 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -415,6 +415,9 @@ static void bl2_populate_compatible_string(void *dt)
uint32_t reg;
int ret;
+ fdt_setprop_u32(dt, 0, "#address-cells", 2);
+ fdt_setprop_u32(dt, 0, "#size-cells", 2);
+
/* Populate compatible string */
rcar_get_board_type(&board_type, &board_rev);
switch (board_type) {
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index dc58e191d9..4c41dd341c 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -348,12 +348,12 @@ ERRATA_A53_855873 := 1
ERRATA_A57_859972 := 1
ERRATA_A57_813419 := 1
-include drivers/staging/renesas/rcar/ddr/ddr.mk
+include drivers/renesas/rcar/ddr/ddr.mk
include drivers/renesas/rcar/qos/qos.mk
include drivers/renesas/rcar/pfc/pfc.mk
include lib/libfdt/libfdt.mk
-PLAT_INCLUDES := -Idrivers/staging/renesas/rcar/ddr \
+PLAT_INCLUDES := -Idrivers/renesas/rcar/ddr \
-Idrivers/renesas/rcar/qos \
-Idrivers/renesas/rcar/iic_dvfs \
-Idrivers/renesas/rcar/board \
diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c
index 0a2515d128..5f4e64f7b8 100644
--- a/plat/rockchip/px30/drivers/pmu/pmu.c
+++ b/plat/rockchip/px30/drivers/pmu/pmu.c
@@ -22,6 +22,7 @@
#include <plat_private.h>
#include <pmu.h>
#include <px30_def.h>
+#include <secure.h>
#include <soc.h>
DEFINE_BAKERY_LOCK(rockchip_pd_lock);
diff --git a/plat/rockchip/px30/drivers/secure/secure.c b/plat/rockchip/px30/drivers/secure/secure.c
new file mode 100644
index 0000000000..144f94537e
--- /dev/null
+++ b/plat/rockchip/px30/drivers/secure/secure.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <ddr_parameter.h>
+#include <plat_private.h>
+#include <secure.h>
+#include <px30_def.h>
+
+/**
+ * There are 8 regions for DDR security control
+ * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
+ * The internal unit is megabytes, so memory areas need to be aligned
+ * to megabyte borders.
+ */
+static void secure_ddr_region(uint32_t rgn,
+ uintptr_t st, size_t sz)
+{
+ uintptr_t ed = st + sz;
+ uintptr_t st_mb, ed_mb;
+ uint32_t val;
+
+ assert(rgn <= 7);
+ assert(st < ed);
+
+ /* check aligned 1MB */
+ assert(st % SIZE_M(1) == 0);
+ assert(ed % SIZE_M(1) == 0);
+
+ st_mb = st / SIZE_M(1);
+ ed_mb = ed / SIZE_M(1);
+
+ /* map top and base */
+ mmio_write_32(FIREWALL_DDR_BASE +
+ FIREWALL_DDR_FW_DDR_RGN(rgn),
+ RG_MAP_SECURE(ed_mb, st_mb));
+
+ /* enable secure */
+ val = mmio_read_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_CON_REG);
+ val |= BIT(rgn);
+ mmio_write_32(FIREWALL_DDR_BASE +
+ FIREWALL_DDR_FW_DDR_CON_REG, val);
+}
+
+void secure_timer_init(void)
+{
+ mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
+ TIMER_DIS);
+
+ mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
+ mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
+
+ /* auto reload & enable the timer */
+ mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
+ TIMER_EN | TIMER_FMODE);
+}
+
+void sgrf_init(void)
+{
+#ifdef PLAT_RK_SECURE_DDR_MINILOADER
+ uint32_t i;
+ struct param_ddr_usage usg;
+
+ /* general secure regions */
+ usg = ddr_region_usage_parse(DDR_PARAM_BASE,
+ PLAT_MAX_DDR_CAPACITY_MB);
+
+ /* region-0 for TF-A, region-1 for optional OP-TEE */
+ assert(usg.s_nr < 7);
+
+ for (i = 0; i < usg.s_nr; i++)
+ secure_ddr_region(7 - i, usg.s_top[i], usg.s_base[i]);
+#endif
+
+ /* secure the trustzone ram */
+ secure_ddr_region(0, TZRAM_BASE, TZRAM_SIZE);
+
+ /* set all slave ip into no-secure, except stimer */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000);
+
+ /* set master crypto to no-secure, dcf to secure */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003);
+
+ /* set DMAC into no-secure */
+ mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS);
+ mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0);
+ mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16);
+ mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS);
+
+ /* soft reset dma before use */
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ);
+ udelay(5);
+ mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS);
+}
diff --git a/plat/rockchip/px30/drivers/secure/secure.h b/plat/rockchip/px30/drivers/secure/secure.h
new file mode 100644
index 0000000000..498027db2a
--- /dev/null
+++ b/plat/rockchip/px30/drivers/secure/secure.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECURE_H
+#define SECURE_H
+
+/***************************************************************************
+ * SGRF
+ ***************************************************************************/
+#define SGRF_SOC_CON(i) ((i) * 0x4)
+#define SGRF_DMAC_CON(i) (0x30 + (i) * 0x4)
+
+#define SGRF_MST_S_ALL_NS 0xffffffff
+#define SGRF_SLV_S_ALL_NS 0xffff0000
+#define DMA_IRQ_BOOT_NS 0xffffffff
+#define DMA_PERI_CH_NS_15_0 0xffffffff
+#define DMA_PERI_CH_NS_19_16 0x000f000f
+#define DMA_MANAGER_BOOT_NS 0x00010001
+#define DMA_SOFTRST_REQ BITS_WITH_WMASK(1, 0x1, 12)
+#define DMA_SOFTRST_RLS BITS_WITH_WMASK(0, 0x1, 12)
+
+/***************************************************************************
+ * DDR FIREWALL
+ ***************************************************************************/
+#define FIREWALL_DDR_FW_DDR_RGN(i) ((i) * 0x4)
+#define FIREWALL_DDR_FW_DDR_MST(i) (0x20 + (i) * 0x4)
+#define FIREWALL_DDR_FW_DDR_CON_REG 0x40
+#define FIREWALL_DDR_FW_DDR_RGN_NUM 8
+#define FIREWALL_DDR_FW_DDR_MST_NUM 6
+
+#define PLAT_MAX_DDR_CAPACITY_MB 4096
+#define RG_MAP_SECURE(top, base) ((((top) - 1) << 16) | (base))
+
+/**************************************************
+ * secure timer
+ **************************************************/
+
+/* chanal0~5 */
+#define STIMER_CHN_BASE(n) (STIME_BASE + 0x20 * (n))
+
+#define TIMER_LOAD_COUNT0 0x0
+#define TIMER_LOAD_COUNT1 0x4
+
+#define TIMER_CUR_VALUE0 0x8
+#define TIMER_CUR_VALUE1 0xc
+
+#define TIMER_CONTROL_REG 0x10
+#define TIMER_INTSTATUS 0x18
+
+#define TIMER_DIS 0x0
+#define TIMER_EN 0x1
+
+#define TIMER_FMODE (0x0 << 1)
+#define TIMER_RMODE (0x1 << 1)
+
+#define TIMER_LOAD_COUNT0_MSK (0xffffffff)
+#define TIMER_LOAD_COUNT1_MSK (0xffffffff00000000)
+
+void secure_timer_init(void);
+void sgrf_init(void);
+
+#endif /* SECURE_H */
diff --git a/plat/rockchip/px30/drivers/soc/soc.c b/plat/rockchip/px30/drivers/soc/soc.c
index e00561d80a..200563deec 100644
--- a/plat/rockchip/px30/drivers/soc/soc.c
+++ b/plat/rockchip/px30/drivers/soc/soc.c
@@ -12,10 +12,10 @@
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
-#include <ddr_parameter.h>
#include <platform_def.h>
#include <pmu.h>
#include <px30_def.h>
+#include <secure.h>
#include <soc.h>
#include <rockchip_sip_svc.h>
@@ -83,65 +83,6 @@ void clk_gate_con_disable(void)
0xffff0000);
}
-void secure_timer_init(void)
-{
- mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
- TIMER_DIS);
-
- mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff);
- mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff);
-
- /* auto reload & enable the timer */
- mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG,
- TIMER_EN | TIMER_FMODE);
-}
-
-static void sgrf_init(void)
-{
- uint32_t i, val;
- struct param_ddr_usage usg;
-
- /* general secure regions */
- usg = ddr_region_usage_parse(DDR_PARAM_BASE,
- PLAT_MAX_DDR_CAPACITY_MB);
- for (i = 0; i < usg.s_nr; i++) {
- /* enable secure */
- val = mmio_read_32(FIREWALL_DDR_BASE +
- FIREWALL_DDR_FW_DDR_CON_REG);
- val |= BIT(7 - i);
- mmio_write_32(FIREWALL_DDR_BASE +
- FIREWALL_DDR_FW_DDR_CON_REG, val);
- /* map top and base */
- mmio_write_32(FIREWALL_DDR_BASE +
- FIREWALL_DDR_FW_DDR_RGN(7 - i),
- RG_MAP_SECURE(usg.s_top[i], usg.s_base[i]));
- }
-
- /* set ddr rgn0_top and rga0_top as 0 */
- mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0);
-
- /* set all slave ip into no-secure, except stimer */
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS);
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS);
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS);
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS);
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000);
-
- /* set master crypto to no-secure, dcf to secure */
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003);
-
- /* set DMAC into no-secure */
- mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS);
- mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0);
- mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16);
- mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS);
-
- /* soft reset dma before use */
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ);
- udelay(5);
- mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS);
-}
-
static void soc_reset_config_all(void)
{
uint32_t tmp;
diff --git a/plat/rockchip/px30/drivers/soc/soc.h b/plat/rockchip/px30/drivers/soc/soc.h
index 69f2de44ad..648d18b625 100644
--- a/plat/rockchip/px30/drivers/soc/soc.h
+++ b/plat/rockchip/px30/drivers/soc/soc.h
@@ -29,21 +29,6 @@ enum pll_mode {
};
/***************************************************************************
- * SGRF
- ***************************************************************************/
-#define SGRF_SOC_CON(i) ((i) * 0x4)
-#define SGRF_DMAC_CON(i) (0x30 + (i) * 0x4)
-
-#define SGRF_MST_S_ALL_NS 0xffffffff
-#define SGRF_SLV_S_ALL_NS 0xffff0000
-#define DMA_IRQ_BOOT_NS 0xffffffff
-#define DMA_PERI_CH_NS_15_0 0xffffffff
-#define DMA_PERI_CH_NS_19_16 0x000f000f
-#define DMA_MANAGER_BOOT_NS 0x00010001
-#define DMA_SOFTRST_REQ BITS_WITH_WMASK(1, 0x1, 12)
-#define DMA_SOFTRST_RLS BITS_WITH_WMASK(0, 0x1, 12)
-
-/***************************************************************************
* GRF
***************************************************************************/
#define GRF_SOC_CON(i) (0x0400 + (i) * 4)
@@ -61,18 +46,6 @@ enum pll_mode {
#define GRF_SOC_CON2_NSWDT_RST_EN 12
/***************************************************************************
- * DDR FIREWALL
- ***************************************************************************/
-#define FIREWALL_DDR_FW_DDR_RGN(i) ((i) * 0x4)
-#define FIREWALL_DDR_FW_DDR_MST(i) (0x20 + (i) * 0x4)
-#define FIREWALL_DDR_FW_DDR_CON_REG 0x40
-#define FIREWALL_DDR_FW_DDR_RGN_NUM 8
-#define FIREWALL_DDR_FW_DDR_MST_NUM 6
-
-#define PLAT_MAX_DDR_CAPACITY_MB 4096
-#define RG_MAP_SECURE(top, base) ((((top) - 1) << 16) | (base))
-
-/***************************************************************************
* cru
***************************************************************************/
#define CRU_MODE 0xa0
@@ -136,37 +109,10 @@ enum pll_mode {
#define GPIO_INT_STATUS 0x40
#define GPIO_NUMS 4
-/**************************************************
- * secure timer
- **************************************************/
-
-/* chanal0~5 */
-#define STIMER_CHN_BASE(n) (STIME_BASE + 0x20 * (n))
-
-#define TIMER_LOAD_COUNT0 0x0
-#define TIMER_LOAD_COUNT1 0x4
-
-#define TIMER_CUR_VALUE0 0x8
-#define TIMER_CUR_VALUE1 0xc
-
-#define TIMER_CONTROL_REG 0x10
-#define TIMER_INTSTATUS 0x18
-
-#define TIMER_DIS 0x0
-#define TIMER_EN 0x1
-
-#define TIMER_FMODE (0x0 << 1)
-#define TIMER_RMODE (0x1 << 1)
-
-#define TIMER_LOAD_COUNT0_MSK (0xffffffff)
-#define TIMER_LOAD_COUNT1_MSK (0xffffffff00000000)
-
void clk_gate_con_save(uint32_t *clkgt_save);
void clk_gate_con_restore(uint32_t *clkgt_save);
void clk_gate_con_disable(void);
-void secure_timer_init(void);
-void secure_timer_disable(void);
void px30_soc_reset_config(void);
#endif /* __SOC_H__ */
diff --git a/plat/rockchip/px30/include/platform_def.h b/plat/rockchip/px30/include/platform_def.h
index 9dccab82be..2f4f672a03 100644
--- a/plat/rockchip/px30/include/platform_def.h
+++ b/plat/rockchip/px30/include/platform_def.h
@@ -69,9 +69,9 @@
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
#define TZRAM_BASE (0x0)
-#define TZRAM_SIZE (0x80000)
+#define TZRAM_SIZE (0x100000)
/*******************************************************************************
* BL31 specific defines.
diff --git a/plat/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk
index ee85cd3116..87cf18704a 100644
--- a/plat/rockchip/px30/platform.mk
+++ b/plat/rockchip/px30/platform.mk
@@ -20,6 +20,7 @@ PLAT_INCLUDES := -Idrivers/arm/gic/common/ \
-I${RK_PLAT_COMMON}/pmusram \
-I${RK_PLAT_SOC}/ \
-I${RK_PLAT_SOC}/drivers/pmu/ \
+ -I${RK_PLAT_SOC}/drivers/secure/ \
-I${RK_PLAT_SOC}/drivers/soc/ \
-I${RK_PLAT_SOC}/include/
@@ -45,16 +46,20 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
- ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S \
${RK_PLAT_COMMON}/plat_pm.c \
${RK_PLAT_COMMON}/plat_topology.c \
${RK_PLAT_COMMON}/rockchip_sip_svc.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
+ ${RK_PLAT_SOC}/drivers/secure/secure.c \
${RK_PLAT_SOC}/drivers/soc/soc.c \
${RK_PLAT_SOC}/plat_sip_calls.c
+ifdef PLAT_RK_SECURE_DDR_MINILOADER
+BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c
+endif
+
ENABLE_PLAT_COMPAT := 0
MULTI_CONSOLE_API := 1
diff --git a/plat/rockchip/px30/px30_def.h b/plat/rockchip/px30/px30_def.h
index 9b8ccfca63..efe789e1ec 100644
--- a/plat/rockchip/px30/px30_def.h
+++ b/plat/rockchip/px30/px30_def.h
@@ -11,6 +11,7 @@
#define MINOR_VERSION (0)
#define SIZE_K(n) ((n) * 1024)
+#define SIZE_M(n) ((n) * 1024 * 1024)
#define WITH_16BITS_WMSK(bits) (0xffff0000 | (bits))
@@ -54,6 +55,9 @@
#define UART2_BASE 0xff160000
#define UART2_SIZE SIZE_K(64)
+#define UART3_BASE 0xff168000
+#define UART3_SIZE SIZE_K(64)
+
#define UART5_BASE 0xff178000
#define UART5_SIZE SIZE_K(64)
diff --git a/plat/rockchip/rk3288/drivers/secure/secure.c b/plat/rockchip/rk3288/drivers/secure/secure.c
index 68994e4586..25e1cca48d 100644
--- a/plat/rockchip/rk3288/drivers/secure/secure.c
+++ b/plat/rockchip/rk3288/drivers/secure/secure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -38,15 +38,18 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
* SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control
*
* @rgn - the DDR regions 0 ~ 7 which are can be configured.
- * The @st and @ed indicate the start and end addresses for which to set
- * the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
+ * The @st_mb and @ed_mb indicate the start and end addresses for which to set
+ * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the
* address range 0x0 ~ 0xfffff is secure.
*
* For example, if we would like to set the range [0, 32MB) is security via
* DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
*/
-static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed)
+static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, size_t sz)
{
+ uintptr_t ed = st + sz;
uintptr_t st_mb, ed_mb;
assert(rgn <= 7);
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c
index 59d857244a..306308f3f1 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.c
+++ b/plat/rockchip/rk3328/drivers/soc/soc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -97,6 +97,7 @@ void secure_timer_init(void)
void sgrf_init(void)
{
+#ifdef PLAT_RK_SECURE_DDR_MINILOADER
uint32_t i, val;
struct param_ddr_usage usg;
@@ -115,6 +116,7 @@ void sgrf_init(void)
FIREWALL_DDR_FW_DDR_RGN(7 - i),
RG_MAP_SECURE(usg.s_top[i], usg.s_base[i]));
}
+#endif
/* set ddr rgn0_top and rga0_top as 0 */
mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0);
diff --git a/plat/rockchip/rk3328/drivers/soc/soc.h b/plat/rockchip/rk3328/drivers/soc/soc.h
index a1f35b2826..e8cbc09f62 100644
--- a/plat/rockchip/rk3328/drivers/soc/soc.h
+++ b/plat/rockchip/rk3328/drivers/soc/soc.h
@@ -16,8 +16,6 @@
#define TIMER_INTSTATUS 0x18
#define TIMER_EN 0x1
-extern const unsigned char rockchip_power_domain_tree_desc[];
-
/**************************** read/write **************************************/
#ifndef BITS_WMSK
#define BITS_WMSK(msk, shift) ((msk) << (shift + REG_MSK_SHIFT))
diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h
index baac12d3ba..e9eb3fafb9 100644
--- a/plat/rockchip/rk3328/include/platform_def.h
+++ b/plat/rockchip/rk3328/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -66,9 +66,9 @@
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
#define TZRAM_BASE (0x0)
-#define TZRAM_SIZE (0x80000)
+#define TZRAM_SIZE (0x100000)
/*******************************************************************************
* BL31 specific defines.
diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk
index 0da4f2dc46..0219422f93 100644
--- a/plat/rockchip/rk3328/platform.mk
+++ b/plat/rockchip/rk3328/platform.mk
@@ -42,7 +42,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
drivers/delay_timer/generic_delay_timer.c \
lib/cpus/aarch64/aem_generic.S \
lib/cpus/aarch64/cortex_a53.S \
- ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \
${RK_PLAT_COMMON}/aarch64/plat_helpers.S \
${RK_PLAT_COMMON}/params_setup.c \
${RK_PLAT_COMMON}/bl31_plat_setup.c \
@@ -53,9 +52,16 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
${RK_PLAT_SOC}/drivers/soc/soc.c
+ifdef PLAT_RK_SECURE_DDR_MINILOADER
+BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c
+endif
+
include lib/coreboot/coreboot.mk
include lib/libfdt/libfdt.mk
+# Enable workarounds for selected Cortex-A53 errata
+ERRATA_A53_855873 := 1
+
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
$(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER))
diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h
index 9334a83ae6..2abd56b0bd 100644
--- a/plat/rockchip/rk3368/include/platform_def.h
+++ b/plat/rockchip/rk3368/include/platform_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -67,9 +67,9 @@
/*******************************************************************************
* Platform memory map related constants
******************************************************************************/
-/* TF text, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
#define TZRAM_BASE (0x0)
-#define TZRAM_SIZE (0x80000)
+#define TZRAM_SIZE (0x100000)
/*******************************************************************************
* BL31 specific defines.
diff --git a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
index aa71fdea6f..a8773f4f6f 100644
--- a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
+++ b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c
@@ -18,7 +18,7 @@ __asm__(
".global hdcp_handler\n"
".balign 4\n"
"hdcp_handler:\n"
- ".incbin \"" __XSTRING(HDCPFW) "\"\n"
+ ".incbin \"" HDCPFW "\"\n"
".type hdcp_handler, %function\n"
".size hdcp_handler, .- hdcp_handler\n"
".popsection\n"
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c
index 30941fd077..faee6787dd 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c
@@ -400,6 +400,25 @@ static void pmu_power_domains_resume(void)
clk_gate_con_restore();
}
+void pmu_power_domains_on(void)
+{
+ clk_gate_con_disable();
+ pmu_set_power_domain(PD_VDU, pmu_pd_on);
+ pmu_set_power_domain(PD_VCODEC, pmu_pd_on);
+ pmu_set_power_domain(PD_RGA, pmu_pd_on);
+ pmu_set_power_domain(PD_IEP, pmu_pd_on);
+ pmu_set_power_domain(PD_EDP, pmu_pd_on);
+ pmu_set_power_domain(PD_GMAC, pmu_pd_on);
+ pmu_set_power_domain(PD_SDIOAUDIO, pmu_pd_on);
+ pmu_set_power_domain(PD_HDCP, pmu_pd_on);
+ pmu_set_power_domain(PD_ISP1, pmu_pd_on);
+ pmu_set_power_domain(PD_ISP0, pmu_pd_on);
+ pmu_set_power_domain(PD_VO, pmu_pd_on);
+ pmu_set_power_domain(PD_TCPD1, pmu_pd_on);
+ pmu_set_power_domain(PD_TCPD0, pmu_pd_on);
+ pmu_set_power_domain(PD_GPU, pmu_pd_on);
+}
+
void rk3399_flush_l2_b(void)
{
uint32_t wait_cnt = 0;
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.h b/plat/rockchip/rk3399/drivers/pmu/pmu.h
index 74db82ff20..bb7de5091a 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu.h
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h
@@ -136,5 +136,6 @@ struct pmu_slpdata_s {
extern uint32_t clst_warmboot_data[PLATFORM_CLUSTER_COUNT];
extern void sram_func_set_ddrctl_pll(uint32_t pll_src);
+void pmu_power_domains_on(void);
#endif /* PMU_H */
diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
index a09ad21e87..25596b1880 100644
--- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
+++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c
@@ -5,20 +5,18 @@
*/
/* convoluted way to make sure that the define is pasted just the right way */
-#define _INCBIN(file, sym, sec) \
+#define INCBIN(file, sym, sec) \
__asm__( \
- ".section " #sec "\n" \
- ".global " #sym "\n" \
- ".type " #sym ", %object\n" \
+ ".section " sec "\n" \
+ ".global " sym "\n" \
+ ".type " sym ", %object\n" \
".align 4\n" \
- #sym ":\n" \
- ".incbin \"" #file "\"\n" \
- ".size " #sym ", .-" #sym "\n" \
- ".global " #sym "_end\n" \
- #sym "_end:\n" \
+ sym ":\n" \
+ ".incbin \"" file "\"\n" \
+ ".size " sym ", .-" sym "\n" \
+ ".global " sym "_end\n" \
+ sym "_end:\n" \
)
-#define INCBIN(file, sym, sec) _INCBIN(file, sym, sec)
-
-INCBIN(RK3399M0FW, rk3399m0_bin, ".sram.incbin");
-INCBIN(RK3399M0PMUFW, rk3399m0pmu_bin, ".pmusram.incbin");
+INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin");
+INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin");
diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c
index 8286f17c64..13c83ca1fb 100644
--- a/plat/rockchip/rk3399/drivers/secure/secure.c
+++ b/plat/rockchip/rk3399/drivers/secure/secure.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -45,6 +45,8 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
* bypass, 1: enable bypass
*
* @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * @st - start address to set as secure
+ * @sz - length of area to set as secure
* The @st_mb and @ed_mb indicate the start and end addresses for which to set
* the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the
* address range 0x0 ~ 0xfffff is secure.
@@ -53,8 +55,9 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
* DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
*/
static void sgrf_ddr_rgn_config(uint32_t rgn,
- uintptr_t st, uintptr_t ed)
+ uintptr_t st, size_t sz)
{
+ uintptr_t ed = st + sz;
uintptr_t st_mb, ed_mb;
assert(rgn <= 7);
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index c877dbde84..98b5ad6469 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -17,6 +17,7 @@
#include <dram.h>
#include <m0_ctl.h>
#include <plat_private.h>
+#include <pmu.h>
#include <rk3399_def.h>
#include <secure.h>
#include <soc.h>
@@ -327,6 +328,7 @@ void soc_global_soft_reset_init(void)
void __dead2 soc_global_soft_reset(void)
{
+ pmu_power_domains_on();
set_pll_slow_mode(VPLL_ID);
set_pll_slow_mode(NPLL_ID);
set_pll_slow_mode(GPLL_ID);
diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c
index c2cc5b11c3..ce8476c9a6 100644
--- a/plat/rockchip/rk3399/plat_sip_calls.c
+++ b/plat/rockchip/rk3399/plat_sip_calls.c
@@ -56,17 +56,21 @@ uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid,
void *handle,
u_register_t flags)
{
+#ifdef PLAT_RK_DP_HDCP
uint64_t x5, x6;
+#endif
switch (smc_fid) {
case RK_SIP_DDR_CFG:
SMC_RET1(handle, ddr_smc_handler(x1, x2, x3, x4));
+#ifdef PLAT_RK_DP_HDCP
case RK_SIP_HDCP_CONTROL:
SMC_RET1(handle, dp_hdcp_ctrl(x1));
case RK_SIP_HDCP_KEY_DATA64:
x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5);
x6 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X6);
SMC_RET1(handle, dp_hdcp_store_key(x1, x2, x3, x4, x5, x6));
+#endif
default:
ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk
index cfc48e8f96..5a23d3c71f 100644
--- a/plat/rockchip/rk3399/platform.mk
+++ b/plat/rockchip/rk3399/platform.mk
@@ -56,7 +56,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \
${RK_PLAT_COMMON}/aarch64/platform_common.c \
${RK_PLAT_COMMON}/rockchip_sip_svc.c \
${RK_PLAT_SOC}/plat_sip_calls.c \
- ${RK_PLAT_SOC}/drivers/dp/cdn_dp.c \
${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \
${RK_PLAT_SOC}/drivers/pmu/pmu.c \
${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \
@@ -82,22 +81,26 @@ PLAT_M0 := ${PLAT}m0
BUILD_M0 := ${BUILD_PLAT}/m0
RK3399M0FW=${BUILD_M0}/${PLAT_M0}.bin
-$(eval $(call add_define,RK3399M0FW))
+$(eval $(call add_define_val,RK3399M0FW,\"$(RK3399M0FW)\"))
RK3399M0PMUFW=${BUILD_M0}/${PLAT_M0}pmu.bin
-$(eval $(call add_define,RK3399M0PMUFW))
+$(eval $(call add_define_val,RK3399M0PMUFW,\"$(RK3399M0PMUFW)\"))
+
+ifdef PLAT_RK_DP_HDCP
+BL31_SOURCES += ${RK_PLAT_SOC}/drivers/dp/cdn_dp.c
HDCPFW=${RK_PLAT_SOC}/drivers/dp/hdcp.bin
-$(eval $(call add_define,HDCPFW))
+$(eval $(call add_define_val,HDCPFW,\"$(HDCPFW)\"))
+
+${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)
+${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW)
+endif
# CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin
export CCACHE_EXTRAFILES
${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW)
${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW)
-${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW)
-${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW)
-
$(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT}))
.PHONY: $(RK3399M0FW)
$(RK3399M0FW): | ${BUILD_M0}
diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S
index 46073b7917..083c30e715 100644
--- a/plat/rpi/rpi4/aarch64/plat_helpers.S
+++ b/plat/rpi/rpi4/aarch64/plat_helpers.S
@@ -136,8 +136,8 @@ endfunc platform_mem_init
*/
func plat_crash_console_init
mov_imm x0, PLAT_RPI3_UART_BASE
- mov_imm x1, PLAT_RPI4_VPU_CLK_RATE
- mov_imm x2, PLAT_RPI3_UART_BAUDRATE
+ mov x1, xzr
+ mov x2, xzr
b console_16550_core_init
endfunc plat_crash_console_init
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index ed367ee201..b1dd4e92e4 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/plat/rpi/rpi4/include/rpi_hw.h
@@ -59,13 +59,6 @@
#define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555)
/*
- * Clock controller
- */
-#define RPI4_IO_CLOCK_OFFSET ULL(0x00101000)
-#define RPI4_CLOCK_BASE (RPI_IO_BASE + RPI4_IO_CLOCK_OFFSET)
-#define RPI4_VPU_CLOCK_DIVIDER ULL(0x0000000c)
-
-/*
* Hardware random number generator.
*/
#define RPI3_IO_RNG_OFFSET ULL(0x00104000)
@@ -88,7 +81,6 @@
*/
#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040)
#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET)
-#define PLAT_RPI4_VPU_CLK_RATE ULL(1000000000)
/*
* GPIO controller
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index 53ab0c2e2f..9e3b539797 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -119,8 +119,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
u_register_t arg2, u_register_t arg3)
{
- uint32_t div_reg;
-
/*
* LOCAL_CONTROL:
* Bit 9 clear: Increment by 1 (vs. 2).
@@ -136,16 +134,12 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
/*
* Initialize the console to provide early debug support.
- * Different GPU firmware revisions set up the VPU divider differently,
- * so read the actual divider register to learn the UART base clock
- * rate. The divider is encoded as a 12.12 fixed point number, but we
- * just care about the integer part of it.
+ * We rely on the GPU firmware to have initialised the UART correctly,
+ * as the baud base clock rate differs across GPU firmware revisions.
+ * Providing a base clock of 0 lets the 16550 UART init routine skip
+ * the initial enablement and baud rate setup.
*/
- div_reg = mmio_read_32(RPI4_CLOCK_BASE + RPI4_VPU_CLOCK_DIVIDER);
- div_reg = (div_reg >> 12) & 0xfff;
- if (div_reg == 0)
- div_reg = 1;
- rpi3_console_init(PLAT_RPI4_VPU_CLK_RATE / div_reg);
+ rpi3_console_init(0);
bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry();
diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk
index fe1448ff10..ab1f69e68c 100644
--- a/plat/socionext/synquacer/platform.mk
+++ b/plat/socionext/synquacer/platform.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -57,7 +57,7 @@ BL31_SOURCES += $(PLAT_PATH)/drivers/scp/sq_scmi.c \
drivers/arm/css/mhu/css_mhu_doorbell.c
endif
-ifeq (${ENABLE_SPM},1)
+ifeq (${SPM_MM},1)
$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
BL31_SOURCES += $(PLAT_PATH)/sq_spm.c
diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c
index c78fe91881..b86402179a 100644
--- a/plat/socionext/synquacer/sq_bl31_setup.c
+++ b/plat/socionext/synquacer/sq_bl31_setup.c
@@ -159,7 +159,7 @@ void bl31_plat_runtime_setup(void)
void bl31_plat_arch_setup(void)
{
static const mmap_region_t secure_partition_mmap[] = {
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
MAP_REGION_FLAT(PLAT_SPM_BUF_BASE,
PLAT_SPM_BUF_SIZE,
MT_RW_DATA | MT_SECURE),
@@ -173,7 +173,7 @@ void bl31_plat_arch_setup(void)
sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap);
enable_mmu_el3(XLAT_TABLE_NC);
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
memcpy((void *)SPM_SHIM_EXCEPTIONS_START,
(void *)SPM_SHIM_EXCEPTIONS_LMA,
(uintptr_t)SPM_SHIM_EXCEPTIONS_END -
diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c
index 01cce17399..7bea1114ec 100644
--- a/plat/socionext/synquacer/sq_spm.c
+++ b/plat/socionext/synquacer/sq_spm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,7 +10,7 @@
#include <bl31/ehf.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
static const mmap_region_t plat_arm_secure_partition_mmap[] = {
PLAT_SQ_FLASH_MMAP,
@@ -27,7 +27,7 @@ static const mmap_region_t plat_arm_secure_partition_mmap[] = {
* 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[] = {
+static spm_mm_mp_info_t sp_mp_info[] = {
{0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0},
{0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0},
{0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0},
@@ -36,10 +36,10 @@ static secure_partition_mp_info_t sp_mp_info[] = {
{0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 0},
};
-const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = {
+const spm_mm_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.size = sizeof(spm_mm_boot_info_t),
.h.attr = 0,
.sp_mem_base = BL32_BASE,
.sp_mem_limit = BL32_LIMIT,
@@ -63,7 +63,7 @@ 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(
+const struct spm_mm_boot_info *plat_get_secure_partition_boot_info(
void *cookie)
{
return &plat_arm_secure_partition_boot_info;
diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk
index d974584900..d31fbe88f0 100644
--- a/plat/socionext/uniphier/platform.mk
+++ b/plat/socionext/uniphier/platform.mk
@@ -60,6 +60,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \
plat/common/plat_gicv3.c \
plat/common/plat_psci_common.c \
$(PLAT_PATH)/uniphier_bl31_setup.c \
+ $(PLAT_PATH)/uniphier_boot_device.c \
$(PLAT_PATH)/uniphier_cci.c \
$(PLAT_PATH)/uniphier_gicv3.c \
$(PLAT_PATH)/uniphier_psci.c \
diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c
index 9e171e073c..817029a2c7 100644
--- a/plat/socionext/uniphier/uniphier_image_desc.c
+++ b/plat/socionext/uniphier/uniphier_image_desc.c
@@ -80,7 +80,7 @@ static struct bl_mem_params_node uniphier_image_descs[] = {
VERSION_2, entry_point_info_t,
NON_SECURE | EXECUTABLE),
.ep_info.pc = UNIPHIER_BL33_BASE,
- .ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX,
+ .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX,
DISABLE_ALL_EXCEPTIONS),
.next_handoff_image_id = INVALID_IMAGE_ID,
diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c
index 464252ddd4..2acc874401 100644
--- a/plat/socionext/uniphier/uniphier_psci.c
+++ b/plat/socionext/uniphier/uniphier_psci.c
@@ -6,6 +6,7 @@
#include <arch_helpers.h>
#include <common/debug.h>
+#include <errno.h>
#include <lib/mmio.h>
#include <lib/psci/psci.h>
@@ -113,17 +114,27 @@ static const struct plat_psci_ops uniphier_psci_ops = {
int plat_setup_psci_ops(uintptr_t sec_entrypoint,
const struct plat_psci_ops **psci_ops)
{
+ unsigned int soc;
+
+ soc = uniphier_get_soc_id();
+ if (soc == UNIPHIER_SOC_UNKNOWN) {
+ ERROR("unsupported SoC\n");
+ return -ENOTSUP;
+ }
+
+ if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) {
+ uniphier_psci_scp_mode = uniphier_scp_is_running();
+ flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
+ sizeof(uniphier_psci_scp_mode));
+
+ if (uniphier_psci_scp_mode)
+ uniphier_scp_open_com();
+ }
+
uniphier_sec_entrypoint = sec_entrypoint;
flush_dcache_range((uint64_t)&uniphier_sec_entrypoint,
sizeof(uniphier_sec_entrypoint));
- uniphier_psci_scp_mode = uniphier_scp_is_running();
- flush_dcache_range((uint64_t)&uniphier_psci_scp_mode,
- sizeof(uniphier_psci_scp_mode));
-
- if (uniphier_psci_scp_mode)
- uniphier_scp_open_com();
-
*psci_ops = &uniphier_psci_ops;
return 0;
diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c
index 38b2a0bd79..3ec7d4048a 100644
--- a/plat/st/common/bl2_io_storage.c
+++ b/plat/st/common/bl2_io_storage.c
@@ -14,11 +14,17 @@
#include <drivers/io/io_block.h>
#include <drivers/io/io_driver.h>
#include <drivers/io/io_dummy.h>
+#include <drivers/io/io_mtd.h>
#include <drivers/io/io_storage.h>
#include <drivers/mmc.h>
#include <drivers/partition/partition.h>
+#include <drivers/raw_nand.h>
+#include <drivers/spi_nand.h>
+#include <drivers/spi_nor.h>
#include <drivers/st/io_mmc.h>
#include <drivers/st/io_stm32image.h>
+#include <drivers/st/stm32_fmc2_nand.h>
+#include <drivers/st/stm32_qspi.h>
#include <drivers/st/stm32_sdmmc2.h>
#include <lib/mmio.h>
#include <lib/utils.h>
@@ -30,7 +36,9 @@ static uintptr_t dummy_dev_handle;
static uintptr_t dummy_dev_spec;
static uintptr_t image_dev_handle;
+static uintptr_t storage_dev_handle;
+#if STM32MP_SDMMC || STM32MP_EMMC
static io_block_spec_t gpt_block_spec = {
.offset = 0,
.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
@@ -51,8 +59,41 @@ static const io_block_dev_spec_t mmc_block_dev_spec = {
.block_size = MMC_BLOCK_SIZE,
};
-static uintptr_t storage_dev_handle;
static const io_dev_connector_t *mmc_dev_con;
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static io_mtd_dev_spec_t spi_nor_dev_spec = {
+ .ops = {
+ .init = spi_nor_init,
+ .read = spi_nor_read,
+ },
+};
+#endif
+
+#if STM32MP_RAW_NAND
+static io_mtd_dev_spec_t nand_dev_spec = {
+ .ops = {
+ .init = nand_raw_init,
+ .read = nand_read,
+ },
+};
+
+static const io_dev_connector_t *nand_dev_con;
+#endif
+
+#if STM32MP_SPI_NAND
+static io_mtd_dev_spec_t spi_nand_dev_spec = {
+ .ops = {
+ .init = spi_nand_init,
+ .read = nand_read,
+ },
+};
+#endif
+
+#if STM32MP_SPI_NAND || STM32MP_SPI_NOR
+static const io_dev_connector_t *spi_dev_con;
+#endif
#ifdef AARCH32_SP_OPTEE
static const struct stm32image_part_info optee_header_partition_spec = {
@@ -96,7 +137,7 @@ enum {
IMG_IDX_NUM
};
-static struct stm32image_device_info stm32image_dev_info_spec = {
+static struct stm32image_device_info stm32image_dev_info_spec __unused = {
.lba_size = MMC_BLOCK_SIZE,
.part_info[IMG_IDX_BL33] = {
.name = BL33_IMAGE_NAME,
@@ -123,7 +164,7 @@ static io_block_spec_t stm32image_block_spec = {
.length = 0,
};
-static const io_dev_connector_t *stm32image_dev_con;
+static const io_dev_connector_t *stm32image_dev_con __unused;
static int open_dummy(const uintptr_t spec);
static int open_image(const uintptr_t spec);
@@ -169,11 +210,13 @@ static const struct plat_io_policy policies[] = {
.image_spec = (uintptr_t)&bl33_partition_spec,
.check = open_image
},
+#if STM32MP_SDMMC || STM32MP_EMMC
[GPT_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&gpt_block_spec,
.check = open_storage
},
+#endif
[STM32_IMAGE_ID] = {
.dev_handle = &storage_dev_handle,
.image_spec = (uintptr_t)&stm32image_block_spec,
@@ -205,6 +248,15 @@ static void print_boot_device(boot_api_context_t *boot_context)
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
INFO("Using EMMC\n");
break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+ INFO("Using QSPI NOR\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ INFO("Using FMC NAND\n");
+ break;
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+ INFO("Using SPI NAND\n");
+ break;
default:
ERROR("Boot interface not found\n");
panic();
@@ -216,6 +268,7 @@ static void print_boot_device(boot_api_context_t *boot_context)
}
}
+#if STM32MP_SDMMC || STM32MP_EMMC
static void boot_mmc(enum mmc_device_type mmc_dev_type,
uint16_t boot_interface_instance)
{
@@ -305,6 +358,167 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
&image_dev_handle);
assert(io_result == 0);
}
+#endif /* STM32MP_SDMMC || STM32MP_EMMC */
+
+#if STM32MP_SPI_NOR
+static void boot_spi_nor(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_qspi_init();
+ assert(io_result == 0);
+
+ io_result = register_io_dev_mtd(&spi_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(spi_dev_con,
+ (uintptr_t)&spi_nor_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_BL33_OFFSET;
+ part->bkp_offset = 0U;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEEH_OFFSET;
+ part->bkp_offset = 0U;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEED_OFFSET;
+ part->bkp_offset = 0U;
+
+ idx = IMG_IDX_OPTEE_PAGER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NOR_TEEX_OFFSET;
+ part->bkp_offset = 0U;
+#endif
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+}
+#endif /* STM32MP_SPI_NOR */
+
+#if STM32MP_RAW_NAND
+static void boot_fmc2_nand(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_fmc2_init();
+ assert(io_result == 0);
+
+ /* Register the IO device on this platform */
+ io_result = register_io_dev_mtd(&nand_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_BL33_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEED_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+ part->bkp_offset = nand_dev_spec.erase_size;
+#endif
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+}
+#endif /* STM32MP_RAW_NAND */
+
+#if STM32MP_SPI_NAND
+static void boot_spi_nand(boot_api_context_t *boot_context)
+{
+ int io_result __unused;
+ uint8_t idx;
+ struct stm32image_part_info *part;
+
+ io_result = stm32_qspi_init();
+ assert(io_result == 0);
+
+ io_result = register_io_dev_mtd(&spi_dev_con);
+ assert(io_result == 0);
+
+ /* Open connections to device */
+ io_result = io_dev_open(spi_dev_con,
+ (uintptr_t)&spi_nand_dev_spec,
+ &storage_dev_handle);
+ assert(io_result == 0);
+
+ stm32image_dev_info_spec.device_size =
+ spi_nand_dev_spec.device_size;
+
+ idx = IMG_IDX_BL33;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_BL33_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+#ifdef AARCH32_SP_OPTEE
+ idx = IMG_IDX_OPTEE_HEADER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEH_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGED;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEED_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+
+ idx = IMG_IDX_OPTEE_PAGER;
+ part = &stm32image_dev_info_spec.part_info[idx];
+ part->part_offset = STM32MP_NAND_TEEX_OFFSET;
+ part->bkp_offset = spi_nand_dev_spec.erase_size;
+#endif
+
+ io_result = register_io_dev_stm32image(&stm32image_dev_con);
+ assert(io_result == 0);
+
+ io_result = io_dev_open(stm32image_dev_con,
+ (uintptr_t)&stm32image_dev_info_spec,
+ &image_dev_handle);
+ assert(io_result == 0);
+}
+#endif /* STM32MP_SPI_NAND */
void stm32mp_io_setup(void)
{
@@ -328,14 +542,36 @@ void stm32mp_io_setup(void)
assert(io_result == 0);
switch (boot_context->boot_interface_selected) {
+#if STM32MP_SDMMC
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
dmbsy();
boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
break;
+#endif
+#if STM32MP_EMMC
case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
dmbsy();
boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
break;
+#endif
+#if STM32MP_SPI_NOR
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
+ dmbsy();
+ boot_spi_nor(boot_context);
+ break;
+#endif
+#if STM32MP_RAW_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
+ dmbsy();
+ boot_fmc2_nand(boot_context);
+ break;
+#endif
+#if STM32MP_SPI_NAND
+ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
+ dmbsy();
+ boot_spi_nand(boot_context);
+ break;
+#endif
default:
ERROR("Boot interface %d not supported\n",
diff --git a/plat/st/common/include/stm32mp_dt.h b/plat/st/common/include/stm32mp_dt.h
index 74b01b3aa5..a29d9148d0 100644
--- a/plat/st/common/include/stm32mp_dt.h
+++ b/plat/st/common/include/stm32mp_dt.h
@@ -32,6 +32,8 @@ 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 fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
+ size_t *size);
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);
diff --git a/plat/st/common/stm32mp_dt.c b/plat/st/common/stm32mp_dt.c
index 17da4904ac..4fa796f0c8 100644
--- a/plat/st/common/stm32mp_dt.c
+++ b/plat/st/common/stm32mp_dt.c
@@ -93,6 +93,46 @@ uint8_t fdt_get_status(int node)
}
/*******************************************************************************
+ * This function returns the address cells from the node parent.
+ * Returns:
+ * - #address-cells value if success.
+ * - invalid value if error.
+ * - a default value if undefined #address-cells property as per libfdt
+ * implementation.
+ ******************************************************************************/
+int fdt_get_node_parent_address_cells(int node)
+{
+ int parent;
+
+ parent = fdt_parent_offset(fdt, node);
+ if (parent < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return fdt_address_cells(fdt, parent);
+}
+
+/*******************************************************************************
+ * This function returns the size cells from the node parent.
+ * Returns:
+ * - #size-cells value if success.
+ * - invalid value if error.
+ * - a default value if undefined #size-cells property as per libfdt
+ * implementation.
+ ******************************************************************************/
+int fdt_get_node_parent_size_cells(int node)
+{
+ int parent;
+
+ parent = fdt_parent_offset(fdt, node);
+ if (parent < 0) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ return fdt_size_cells(fdt, parent);
+}
+
+/*******************************************************************************
* 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.
@@ -146,6 +186,46 @@ int fdt_read_uint32_array(int node, const char *prop_name, uint32_t *array,
}
/*******************************************************************************
+ * This function fills reg node info (base & size) with an index found by
+ * checking the reg-names node.
+ * Returns 0 on success and a negative FDT error code on failure.
+ ******************************************************************************/
+int fdt_get_reg_props_by_name(int node, const char *name, uintptr_t *base,
+ size_t *size)
+{
+ const fdt32_t *cuint;
+ int index, len;
+
+ assert((fdt_get_node_parent_address_cells(node) == 1) &&
+ (fdt_get_node_parent_size_cells(node) == 1));
+
+ index = fdt_stringlist_search(fdt, node, "reg-names", name);
+ if (index < 0) {
+ return index;
+ }
+
+ cuint = fdt_getprop(fdt, node, "reg", &len);
+ if (cuint == NULL) {
+ return -FDT_ERR_NOTFOUND;
+ }
+
+ if ((index * (int)sizeof(uint32_t)) > len) {
+ return -FDT_ERR_BADVALUE;
+ }
+
+ cuint += index << 1;
+ if (base != NULL) {
+ *base = fdt32_to_cpu(*cuint);
+ }
+ cuint++;
+ if (size != NULL) {
+ *size = fdt32_to_cpu(*cuint);
+ }
+
+ return 0;
+}
+
+/*******************************************************************************
* This function gets the stdout path node.
* It reads the value indicated inside the device tree.
* Returns node offset on success and a negative FDT error code on failure.
@@ -215,6 +295,8 @@ void dt_fill_device_info(struct dt_node_info *info, int node)
{
const fdt32_t *cuint;
+ assert(fdt_get_node_parent_address_cells(node) == 1);
+
cuint = fdt_getprop(fdt, node, "reg", NULL);
if (cuint != NULL) {
info->base = fdt32_to_cpu(*cuint);
@@ -309,6 +391,9 @@ uintptr_t dt_get_ddrctrl_base(void)
return 0;
}
+ assert((fdt_get_node_parent_address_cells(node) == 1) &&
+ (fdt_get_node_parent_size_cells(node) == 1));
+
if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
return 0;
}
@@ -331,6 +416,9 @@ uintptr_t dt_get_ddrphyc_base(void)
return 0;
}
+ assert((fdt_get_node_parent_address_cells(node) == 1) &&
+ (fdt_get_node_parent_size_cells(node) == 1));
+
if (fdt_read_uint32_array(node, "reg", array, 4) < 0) {
return 0;
}
@@ -353,6 +441,8 @@ uintptr_t dt_get_pwr_base(void)
return 0;
}
+ assert(fdt_get_node_parent_address_cells(node) == 1);
+
cuint = fdt_getprop(fdt, node, "reg", NULL);
if (cuint == NULL) {
return 0;
@@ -415,6 +505,8 @@ uintptr_t dt_get_syscfg_base(void)
return 0;
}
+ assert(fdt_get_node_parent_address_cells(node) == 1);
+
cuint = fdt_getprop(fdt, node, "reg", NULL);
if (cuint == NULL) {
return 0;
diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h
index c80aef6dd7..c16639ac40 100644
--- a/plat/st/stm32mp1/include/boot_api.h
+++ b/plat/st/stm32mp1/include/boot_api.h
@@ -33,6 +33,15 @@
/* Boot occurred on EMMC */
#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC 0x2U
+/* Boot occurred on FMC */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC 0x3U
+
+/* Boot occurred on QSPI NOR */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U
+
+/* Boot occurred on QSPI NAND */
+#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U
+
/**
* @brief Possible value of boot context field 'EmmcXferStatus'
*/
diff --git a/plat/st/stm32mp1/include/platform_def.h b/plat/st/stm32mp1/include/platform_def.h
index 263e6d6e1f..450a9d404c 100644
--- a/plat/st/stm32mp1/include/platform_def.h
+++ b/plat/st/stm32mp1/include/platform_def.h
@@ -51,6 +51,7 @@
#define MAX_IO_DEVICES U(4)
#define MAX_IO_HANDLES U(4)
#define MAX_IO_BLOCK_DEVICES U(1)
+#define MAX_IO_MTD_DEVICES U(1)
/*******************************************************************************
* BL2 specific defines.
diff --git a/plat/st/stm32mp1/include/stm32mp1_boot_device.h b/plat/st/stm32mp1/include/stm32mp1_boot_device.h
new file mode 100644
index 0000000000..a74598395f
--- /dev/null
+++ b/plat/st/stm32mp1/include/stm32mp1_boot_device.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STM32MP1_BOOT_DEVICE_H
+#define STM32MP1_BOOT_DEVICE_H
+
+#include <drivers/raw_nand.h>
+#include <drivers/spi_nand.h>
+#include <drivers/spi_nor.h>
+
+int plat_get_raw_nand_data(struct rawnand_device *device);
+int plat_get_spi_nand_data(struct spinand_device *device);
+int plat_get_nor_data(struct nor_device *device);
+
+#endif /* STM32MP1_BOOT_DEVICE_H */
diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk
index 90b3e3c1e5..b86287b669 100644
--- a/plat/st/stm32mp1/platform.mk
+++ b/plat/st/stm32mp1/platform.mk
@@ -24,6 +24,29 @@ PLAT_PARTITION_MAX_ENTRIES := $(shell echo $$(($(STM32_TF_A_COPIES) + 1)))
endif
$(eval $(call add_define,PLAT_PARTITION_MAX_ENTRIES))
+# Boot devices
+STM32MP_EMMC ?= 0
+STM32MP_SDMMC ?= 0
+STM32MP_RAW_NAND ?= 0
+STM32MP_SPI_NAND ?= 0
+STM32MP_SPI_NOR ?= 0
+
+ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \
+ ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+$(error "No boot device driver is enabled")
+endif
+
+$(eval $(call assert_boolean,STM32MP_EMMC))
+$(eval $(call assert_boolean,STM32MP_SDMMC))
+$(eval $(call assert_boolean,STM32MP_RAW_NAND))
+$(eval $(call assert_boolean,STM32MP_SPI_NAND))
+$(eval $(call assert_boolean,STM32MP_SPI_NOR))
+$(eval $(call add_define,STM32MP_EMMC))
+$(eval $(call add_define,STM32MP_SDMMC))
+$(eval $(call add_define,STM32MP_RAW_NAND))
+$(eval $(call add_define,STM32MP_SPI_NAND))
+$(eval $(call add_define,STM32MP_SPI_NOR))
+
PLAT_INCLUDES := -Iplat/st/common/include/
PLAT_INCLUDES += -Iplat/st/stm32mp1/include/
@@ -70,6 +93,7 @@ PLAT_BL_COMMON_SOURCES += drivers/arm/tzc/tzc400.c \
BL2_SOURCES += drivers/io/io_block.c \
drivers/io/io_dummy.c \
+ drivers/io/io_mtd.c \
drivers/io/io_storage.c \
drivers/st/crypto/stm32_hash.c \
drivers/st/io/io_stm32image.c \
@@ -77,11 +101,40 @@ BL2_SOURCES += drivers/io/io_block.c \
plat/st/common/bl2_io_storage.c \
plat/st/stm32mp1/bl2_plat_setup.c
+ifneq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC}),)
BL2_SOURCES += drivers/mmc/mmc.c \
drivers/partition/gpt.c \
drivers/partition/partition.c \
drivers/st/io/io_mmc.c \
drivers/st/mmc/stm32_sdmmc2.c
+endif
+
+ifeq (${STM32MP_RAW_NAND},1)
+$(eval $(call add_define_val,NAND_ONFI_DETECT,1))
+BL2_SOURCES += drivers/mtd/nand/raw_nand.c \
+ drivers/st/fmc/stm32_fmc2_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NAND},1)
+BL2_SOURCES += drivers/mtd/nand/spi_nand.c
+endif
+
+ifeq (${STM32MP_SPI_NOR},1)
+BL2_SOURCES += drivers/mtd/nor/spi_nor.c
+endif
+
+ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+BL2_SOURCES += drivers/mtd/spi-mem/spi_mem.c \
+ drivers/st/spi/stm32_qspi.c
+endif
+
+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),)
+BL2_SOURCES += drivers/mtd/nand/core.c
+endif
+
+ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),)
+BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c
+endif
BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \
drivers/st/ddr/stm32mp1_ram.c
diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c
new file mode 100644
index 0000000000..2d8eccff7d
--- /dev/null
+++ b/plat/st/stm32mp1/stm32mp1_boot_device.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2019, STMicroelectronics - All Rights Reserved
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <drivers/nand.h>
+#include <lib/utils.h>
+#include <plat/common/platform.h>
+
+#define SZ_512 0x200U
+#define SZ_64M 0x4000000U
+
+#if STM32MP_RAW_NAND || STM32MP_SPI_NAND
+static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc)
+{
+ int result;
+ uint32_t nand_param;
+
+ /* Check if NAND parameters are stored in OTP */
+ result = bsec_shadow_read_otp(&nand_param, NAND_OTP);
+ if (result != BSEC_OK) {
+ ERROR("BSEC: NAND_OTP Error %i\n", result);
+ return -EACCES;
+ }
+
+ if (nand_param == 0U) {
+ return 0;
+ }
+
+ if ((nand_param & NAND_PARAM_STORED_IN_OTP) == 0U) {
+ goto ecc;
+ }
+
+ /* NAND parameter shall be read from OTP */
+ if ((nand_param & NAND_WIDTH_MASK) != 0U) {
+ nand_dev->buswidth = NAND_BUS_WIDTH_16;
+ } else {
+ nand_dev->buswidth = NAND_BUS_WIDTH_8;
+ }
+
+ switch ((nand_param & NAND_PAGE_SIZE_MASK) >> NAND_PAGE_SIZE_SHIFT) {
+ case NAND_PAGE_SIZE_2K:
+ nand_dev->page_size = 0x800U;
+ break;
+
+ case NAND_PAGE_SIZE_4K:
+ nand_dev->page_size = 0x1000U;
+ break;
+
+ case NAND_PAGE_SIZE_8K:
+ nand_dev->page_size = 0x2000U;
+ break;
+
+ default:
+ ERROR("Cannot read NAND page size\n");
+ return -EINVAL;
+ }
+
+ switch ((nand_param & NAND_BLOCK_SIZE_MASK) >> NAND_BLOCK_SIZE_SHIFT) {
+ case NAND_BLOCK_SIZE_64_PAGES:
+ nand_dev->block_size = 64U * nand_dev->page_size;
+ break;
+
+ case NAND_BLOCK_SIZE_128_PAGES:
+ nand_dev->block_size = 128U * nand_dev->page_size;
+ break;
+
+ case NAND_BLOCK_SIZE_256_PAGES:
+ nand_dev->block_size = 256U * nand_dev->page_size;
+ break;
+
+ default:
+ ERROR("Cannot read NAND block size\n");
+ return -EINVAL;
+ }
+
+ nand_dev->size = ((nand_param & NAND_BLOCK_NB_MASK) >>
+ NAND_BLOCK_NB_SHIFT) *
+ NAND_BLOCK_NB_UNIT * nand_dev->block_size;
+
+ecc:
+ if (is_slc) {
+ switch ((nand_param & NAND_ECC_BIT_NB_MASK) >>
+ NAND_ECC_BIT_NB_SHIFT) {
+ case NAND_ECC_BIT_NB_1_BITS:
+ nand_dev->ecc.max_bit_corr = 1U;
+ break;
+
+ case NAND_ECC_BIT_NB_4_BITS:
+ nand_dev->ecc.max_bit_corr = 4U;
+ break;
+
+ case NAND_ECC_BIT_NB_8_BITS:
+ nand_dev->ecc.max_bit_corr = 8U;
+ break;
+
+ case NAND_ECC_ON_DIE:
+ nand_dev->ecc.mode = NAND_ECC_ONDIE;
+ break;
+
+ default:
+ if (nand_dev->ecc.max_bit_corr == 0U) {
+ ERROR("No valid eccbit number\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ /* Selected multiple plane NAND */
+ if ((nand_param & NAND_PLANE_BIT_NB_MASK) != 0U) {
+ nand_dev->nb_planes = 2U;
+ } else {
+ nand_dev->nb_planes = 1U;
+ }
+ }
+
+ VERBOSE("OTP: Block %i Page %i Size %lli\n", nand_dev->block_size,
+ nand_dev->page_size, nand_dev->size);
+
+ return 0;
+}
+#endif /* STM32MP_RAW_NAND || STM32MP_SPI_NAND */
+
+#if STM32MP_RAW_NAND
+int plat_get_raw_nand_data(struct rawnand_device *device)
+{
+ device->nand_dev->ecc.mode = NAND_ECC_HW;
+ device->nand_dev->ecc.size = SZ_512;
+
+ return get_data_from_otp(device->nand_dev, true);
+}
+#endif
+
+#if STM32MP_SPI_NAND
+int plat_get_spi_nand_data(struct spinand_device *device)
+{
+ zeromem(&device->spi_read_cache_op, sizeof(struct spi_mem_op));
+ device->spi_read_cache_op.cmd.opcode = SPI_NAND_OP_READ_FROM_CACHE_4X;
+ device->spi_read_cache_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->spi_read_cache_op.addr.nbytes = 2U;
+ device->spi_read_cache_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->spi_read_cache_op.dummy.nbytes = 1U;
+ device->spi_read_cache_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->spi_read_cache_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
+ device->spi_read_cache_op.data.dir = SPI_MEM_DATA_IN;
+
+ return get_data_from_otp(device->nand_dev, false);
+}
+#endif
+
+#if STM32MP_SPI_NOR
+int plat_get_nor_data(struct nor_device *device)
+{
+ device->size = SZ_64M;
+
+ zeromem(&device->read_op, sizeof(struct spi_mem_op));
+ device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4;
+ device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->read_op.addr.nbytes = 3U;
+ device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->read_op.dummy.nbytes = 1U;
+ device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE;
+ device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE;
+ device->read_op.data.dir = SPI_MEM_DATA_IN;
+
+ return 0;
+}
+#endif
diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h
index a40852bde7..11b01ab882 100644
--- a/plat/st/stm32mp1/stm32mp1_def.h
+++ b/plat/st/stm32mp1/stm32mp1_def.h
@@ -23,6 +23,7 @@
#include <stm32mp_common.h>
#include <stm32mp_dt.h>
#include <stm32mp_shres_helpers.h>
+#include <stm32mp1_boot_device.h>
#include <stm32mp1_dbgmcu.h>
#include <stm32mp1_private.h>
#endif
@@ -74,7 +75,7 @@ enum ddr_type {
#endif
/* Section used inside TF binaries */
-#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 Ko for param */
+#define STM32MP_PARAM_LOAD_SIZE U(0x00002400) /* 9 KB for param */
/* 256 Octets reserved for header */
#define STM32MP_HEADER_SIZE U(0x00000100)
@@ -95,9 +96,9 @@ enum ddr_type {
STM32MP_OPTEE_BASE)
#else
#if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL32_SIZE U(0x00012000) /* 72 Ko for BL32 */
+#define STM32MP_BL32_SIZE U(0x00012000) /* 72 KB for BL32 */
#else
-#define STM32MP_BL32_SIZE U(0x00011000) /* 68 Ko for BL32 */
+#define STM32MP_BL32_SIZE U(0x00011000) /* 68 KB for BL32 */
#endif
#endif
@@ -107,23 +108,23 @@ enum ddr_type {
#ifdef AARCH32_SP_OPTEE
#if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL2_SIZE U(0x00019000) /* 100 Ko for BL2 */
+#define STM32MP_BL2_SIZE U(0x0001A000) /* 100 KB for BL2 */
#else
-#define STM32MP_BL2_SIZE U(0x00017000) /* 92 Ko for BL2 */
+#define STM32MP_BL2_SIZE U(0x00018000) /* 92 KB for BL2 */
#endif
#else
#if STACK_PROTECTOR_ENABLED
-#define STM32MP_BL2_SIZE U(0x00018000) /* 96 Ko for BL2 */
+#define STM32MP_BL2_SIZE U(0x00019000) /* 96 KB for BL2 */
#else
-#define STM32MP_BL2_SIZE U(0x00016000) /* 88 Ko for BL2 */
+#define STM32MP_BL2_SIZE U(0x00017000) /* 88 KB for BL2 */
#endif
#endif
#define STM32MP_BL2_BASE (STM32MP_BL32_BASE - \
STM32MP_BL2_SIZE)
-/* BL2 and BL32/sp_min require 5 tables */
-#define MAX_XLAT_TABLES 5
+/* BL2 and BL32/sp_min require 4 tables */
+#define MAX_XLAT_TABLES U(4) /* 16 KB for mapping */
/*
* MAX_MMAP_REGIONS is usually:
@@ -137,13 +138,33 @@ enum ddr_type {
#endif
/* DTB initialization value */
-#define STM32MP_DTB_SIZE U(0x00005000) /* 20Ko for DTB */
+#define STM32MP_DTB_SIZE U(0x00005000) /* 20 KB for DTB */
#define STM32MP_DTB_BASE (STM32MP_BL2_BASE - \
STM32MP_DTB_SIZE)
#define STM32MP_BL33_BASE (STM32MP_DDR_BASE + U(0x100000))
+/* Define maximum page size for NAND devices */
+#define PLATFORM_MTD_MAX_PAGE_SIZE U(0x1000)
+
+/*******************************************************************************
+ * STM32MP1 RAW partition offset for MTD devices
+ ******************************************************************************/
+#define STM32MP_NOR_BL33_OFFSET U(0x00080000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NOR_TEEH_OFFSET U(0x00280000)
+#define STM32MP_NOR_TEED_OFFSET U(0x002C0000)
+#define STM32MP_NOR_TEEX_OFFSET U(0x00300000)
+#endif
+
+#define STM32MP_NAND_BL33_OFFSET U(0x00200000)
+#ifdef AARCH32_SP_OPTEE
+#define STM32MP_NAND_TEEH_OFFSET U(0x00600000)
+#define STM32MP_NAND_TEED_OFFSET U(0x00680000)
+#define STM32MP_NAND_TEEX_OFFSET U(0x00700000)
+#endif
+
/*******************************************************************************
* STM32MP1 device/io map related constants (used for MMU)
******************************************************************************/
@@ -266,6 +287,7 @@ enum ddr_type {
/* OTP offsets */
#define DATA0_OTP U(0)
#define PART_NUMBER_OTP U(1)
+#define NAND_OTP U(9)
#define PACKAGE_OTP U(16)
#define HW2_OTP U(18)
@@ -289,6 +311,45 @@ enum ddr_type {
/* HW2 OTP */
#define HW2_OTP_PRODUCT_BELOW_2V5 BIT(13)
+/* NAND OTP */
+/* NAND parameter storage flag */
+#define NAND_PARAM_STORED_IN_OTP BIT(31)
+
+/* NAND page size in bytes */
+#define NAND_PAGE_SIZE_MASK GENMASK_32(30, 29)
+#define NAND_PAGE_SIZE_SHIFT 29
+#define NAND_PAGE_SIZE_2K U(0)
+#define NAND_PAGE_SIZE_4K U(1)
+#define NAND_PAGE_SIZE_8K U(2)
+
+/* NAND block size in pages */
+#define NAND_BLOCK_SIZE_MASK GENMASK_32(28, 27)
+#define NAND_BLOCK_SIZE_SHIFT 27
+#define NAND_BLOCK_SIZE_64_PAGES U(0)
+#define NAND_BLOCK_SIZE_128_PAGES U(1)
+#define NAND_BLOCK_SIZE_256_PAGES U(2)
+
+/* NAND number of block (in unit of 256 blocs) */
+#define NAND_BLOCK_NB_MASK GENMASK_32(26, 19)
+#define NAND_BLOCK_NB_SHIFT 19
+#define NAND_BLOCK_NB_UNIT U(256)
+
+/* NAND bus width in bits */
+#define NAND_WIDTH_MASK BIT(18)
+#define NAND_WIDTH_SHIFT 18
+
+/* NAND number of ECC bits per 512 bytes */
+#define NAND_ECC_BIT_NB_MASK GENMASK_32(17, 15)
+#define NAND_ECC_BIT_NB_SHIFT 15
+#define NAND_ECC_BIT_NB_UNSET U(0)
+#define NAND_ECC_BIT_NB_1_BITS U(1)
+#define NAND_ECC_BIT_NB_4_BITS U(2)
+#define NAND_ECC_BIT_NB_8_BITS U(3)
+#define NAND_ECC_ON_DIE U(4)
+
+/* NAND number of planes */
+#define NAND_PLANE_BIT_NB_MASK BIT(14)
+
/*******************************************************************************
* STM32MP1 TAMP
******************************************************************************/
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index ab5d95d1e2..d6313a68f4 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -189,6 +189,18 @@ static const struct {
.id = 0x65,
.name = "25DR",
},
+ {
+ .id = 0x66,
+ .name = "39DR",
+ },
+ {
+ .id = 0x7b,
+ .name = "48DR",
+ },
+ {
+ .id = 0x7e,
+ .name = "49DR",
+ },
};
#define ZYNQMP_PL_STATUS_BIT 9
@@ -338,7 +350,7 @@ unsigned int plat_get_syscnt_freq2(void)
unsigned int ver = zynqmp_get_silicon_ver();
if (ver == ZYNQMP_CSU_VERSION_QEMU)
- return 50000000;
+ return 65000000;
else
return mmio_read_32(IOU_SCNTRS_BASEFREQ);
}
diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h
index 8648b9ab2c..5d335d945b 100644
--- a/plat/xilinx/zynqmp/include/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/include/zynqmp_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -330,6 +330,7 @@
#define IOU_SLCR_GEM_CLK_CTRL (IOU_SLCR_BASEADDR + 0x308)
#define IOU_SLCR_CAN_MIO_CTRL (IOU_SLCR_BASEADDR + 0x304)
#define FPD_SLCR_WDT_CLK_SEL (FPD_SLCR_BASEADDR + 0x100)
+#define IOU_SLCR_WDT_CLK_SEL (IOU_SLCR_BASEADDR + 0x300)
/* Global general storage register base address */
#define GGS_BASEADDR (0xFFD80030U)
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
index 85cffcb13a..6e53bd89de 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,6 +30,10 @@
#define CLK_TYPE_SHIFT U(2)
#define CLK_CLKFLAGS_SHIFT U(8)
#define CLK_TYPEFLAGS_SHIFT U(24)
+#define CLK_TYPEFLAGS2_SHIFT U(4)
+#define CLK_TYPEFLAGS_BITS_MASK U(0xFF)
+#define CLK_TYPEFLAGS2_BITS_MASK U(0x0F00)
+#define CLK_TYPEFLAGS_BITS U(8)
#define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
@@ -364,9 +368,8 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = {
.offset = PERIPH_MUX_SHIFT,
.width = PERIPH_MUX_WIDTH,
.clkflags = CLK_SET_RATE_NO_REPARENT |
- CLK_SET_RATE_PARENT |
- CLK_FRAC | CLK_IS_BASIC,
- .typeflags = NA_TYPE_FLAGS,
+ CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .typeflags = CLK_FRAC,
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -375,8 +378,9 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = {
.offset = PERIPH_DIV1_SHIFT,
.width = PERIPH_DIV1_WIDTH,
.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
- CLK_FRAC | CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+ CLK_FRAC,
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -385,8 +389,9 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = {
.offset = PERIPH_DIV2_SHIFT,
.width = PERIPH_DIV2_WIDTH,
.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
- CLK_FRAC | CLK_IS_BASIC,
- .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
+ CLK_IS_BASIC,
+ .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
+ CLK_FRAC,
.mult = NA_MULT,
.div = NA_DIV,
},
@@ -562,13 +567,13 @@ static struct pm_clock_node gpu_pp1_nodes[] = {
},
};
-static struct pm_clock_node gem_nodes[] = {
+static struct pm_clock_node gem_ref_ungated_nodes[] = {
GENERIC_MUX,
{
.type = TYPE_DIV1,
.offset = 8,
.width = 6,
- .clkflags = CLK_IS_BASIC,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
.mult = NA_MULT,
.div = NA_DIV,
@@ -577,77 +582,74 @@ static struct pm_clock_node gem_nodes[] = {
.type = TYPE_DIV2,
.offset = 16,
.width = 6,
- .clkflags = CLK_IS_BASIC,
+ .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
+ CLK_SET_RATE_PARENT,
.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
.mult = NA_MULT,
.div = NA_DIV,
},
- {
- .type = TYPE_GATE,
- .offset = 25,
- .width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
- .typeflags = NA_TYPE_FLAGS,
- .mult = NA_MULT,
- .div = NA_DIV,
- },
};
-static struct pm_clock_node gem0_tx_nodes[] = {
+static struct pm_clock_node gem0_ref_nodes[] = {
{
.type = TYPE_MUX,
.offset = 1,
.width = 1,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
- .typeflags = NA_TYPE_FLAGS,
- .mult = NA_MULT,
- .div = NA_DIV,
- },
- {
- .type = TYPE_GATE,
- .offset = 26,
- .width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
},
};
-static struct pm_clock_node gem1_tx_nodes[] = {
+static struct pm_clock_node gem1_ref_nodes[] = {
{
.type = TYPE_MUX,
.offset = 6,
.width = 1,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
},
+};
+
+static struct pm_clock_node gem2_ref_nodes[] = {
{
- .type = TYPE_GATE,
- .offset = 26,
- .width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .type = TYPE_MUX,
+ .offset = 11,
+ .width = 1,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
},
};
-static struct pm_clock_node gem2_tx_nodes[] = {
+static struct pm_clock_node gem3_ref_nodes[] = {
{
.type = TYPE_MUX,
- .offset = 11,
+ .offset = 16,
.width = 1,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
+ .clkflags = CLK_SET_RATE_PARENT |
+ CLK_SET_RATE_NO_REPARENT |
+ CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
},
+};
+
+static struct pm_clock_node gem_tx_nodes[] = {
{
.type = TYPE_GATE,
- .offset = 26,
+ .offset = 25,
.width = PERIPH_GATE_WIDTH,
.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
@@ -656,21 +658,12 @@ static struct pm_clock_node gem2_tx_nodes[] = {
},
};
-static struct pm_clock_node gem3_tx_nodes[] = {
- {
- .type = TYPE_MUX,
- .offset = 16,
- .width = 1,
- .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
- .typeflags = NA_TYPE_FLAGS,
- .mult = NA_MULT,
- .div = NA_DIV,
- },
+static struct pm_clock_node gem_rx_nodes[] = {
{
.type = TYPE_GATE,
.offset = 26,
.width = PERIPH_GATE_WIDTH,
- .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
+ .clkflags = CLK_IS_BASIC,
.typeflags = NA_TYPE_FLAGS,
.mult = NA_MULT,
.div = NA_DIV,
@@ -1442,8 +1435,8 @@ static struct pm_clock clocks[] = {
.nodes = &generic_mux_div_unused_gate_nodes,
.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
},
- [CLK_GEM0_REF] = {
- .name = "gem0_ref",
+ [CLK_GEM0_REF_UNGATED] = {
+ .name = "gem0_ref_ung",
.control_reg = CRL_APB_GEM0_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
@@ -1453,11 +1446,11 @@ static struct pm_clock clocks[] = {
CLK_DPLL_TO_LPD,
CLK_NA_PARENT
}),
- .nodes = &gem_nodes,
- .num_nodes = ARRAY_SIZE(gem_nodes),
+ .nodes = &gem_ref_ungated_nodes,
+ .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
},
- [CLK_GEM1_REF] = {
- .name = "gem1_ref",
+ [CLK_GEM1_REF_UNGATED] = {
+ .name = "gem1_ref_ung",
.control_reg = CRL_APB_GEM1_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
@@ -1467,11 +1460,11 @@ static struct pm_clock clocks[] = {
CLK_DPLL_TO_LPD,
CLK_NA_PARENT
}),
- .nodes = &gem_nodes,
- .num_nodes = ARRAY_SIZE(gem_nodes),
+ .nodes = &gem_ref_ungated_nodes,
+ .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
},
- [CLK_GEM2_REF] = {
- .name = "gem2_ref",
+ [CLK_GEM2_REF_UNGATED] = {
+ .name = "gem2_ref_ung",
.control_reg = CRL_APB_GEM2_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
@@ -1481,11 +1474,11 @@ static struct pm_clock clocks[] = {
CLK_DPLL_TO_LPD,
CLK_NA_PARENT
}),
- .nodes = &gem_nodes,
- .num_nodes = ARRAY_SIZE(gem_nodes),
+ .nodes = &gem_ref_ungated_nodes,
+ .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
},
- [CLK_GEM3_REF] = {
- .name = "gem3_ref",
+ [CLK_GEM3_REF_UNGATED] = {
+ .name = "gem3_ref_ung",
.control_reg = CRL_APB_GEM3_REF_CTRL,
.status_reg = 0,
.parents = &((int32_t []) {
@@ -1495,8 +1488,60 @@ static struct pm_clock clocks[] = {
CLK_DPLL_TO_LPD,
CLK_NA_PARENT
}),
- .nodes = &gem_nodes,
- .num_nodes = ARRAY_SIZE(gem_nodes),
+ .nodes = &gem_ref_ungated_nodes,
+ .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
+ },
+ [CLK_GEM0_REF] = {
+ .name = "gem0_ref",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM0_REF_UNGATED |
+ (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem0_ref_nodes,
+ .num_nodes = ARRAY_SIZE(gem0_ref_nodes),
+ },
+ [CLK_GEM1_REF] = {
+ .name = "gem1_ref",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM1_REF_UNGATED |
+ (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem1_ref_nodes,
+ .num_nodes = ARRAY_SIZE(gem1_ref_nodes),
+ },
+ [CLK_GEM2_REF] = {
+ .name = "gem2_ref",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM2_REF_UNGATED |
+ (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem2_ref_nodes,
+ .num_nodes = ARRAY_SIZE(gem2_ref_nodes),
+ },
+ [CLK_GEM3_REF] = {
+ .name = "gem3_ref",
+ .control_reg = IOU_SLCR_GEM_CLK_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM3_REF_UNGATED |
+ (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
+ EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem3_ref_nodes,
+ .num_nodes = ARRAY_SIZE(gem3_ref_nodes),
},
[CLK_USB0_BUS_REF] = {
.name = "usb0_bus_ref",
@@ -1960,69 +2005,93 @@ static struct pm_clock clocks[] = {
.nodes = &generic_domain_crossing_nodes,
.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
},
- /*
- * This clock control requires different registers for mux and gate.
- * Use control and status registers for the same.
- */
[CLK_GEM0_TX] = {
.name = "gem0_tx",
- .control_reg = IOU_SLCR_GEM_CLK_CTRL,
- .status_reg = CRL_APB_GEM0_REF_CTRL,
+ .control_reg = CRL_APB_GEM0_REF_CTRL,
+ .status_reg = 0,
.parents = &((int32_t []) {
- CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
- EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_GEM0_REF,
CLK_NA_PARENT
}),
- .nodes = &gem0_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem0_tx_nodes),
+ .nodes = &gem_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_tx_nodes),
},
- /*
- * This clock control requires different registers for mux and gate.
- * Use control and status registers for the same.
- */
[CLK_GEM1_TX] = {
.name = "gem1_tx",
- .control_reg = IOU_SLCR_GEM_CLK_CTRL,
- .status_reg = CRL_APB_GEM1_REF_CTRL,
+ .control_reg = CRL_APB_GEM1_REF_CTRL,
+ .status_reg = 0,
.parents = &((int32_t []) {
- CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
- EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_GEM1_REF,
CLK_NA_PARENT
}),
- .nodes = &gem1_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem1_tx_nodes),
+ .nodes = &gem_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_tx_nodes),
},
- /*
- * This clock control requires different registers for mux and gate.
- * Use control and status registers for the same.
- */
[CLK_GEM2_TX] = {
.name = "gem2_tx",
- .control_reg = IOU_SLCR_GEM_CLK_CTRL,
- .status_reg = CRL_APB_GEM2_REF_CTRL,
+ .control_reg = CRL_APB_GEM2_REF_CTRL,
+ .status_reg = 0,
.parents = &((int32_t []) {
- CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
- EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_GEM2_REF,
CLK_NA_PARENT
}),
- .nodes = &gem2_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem2_tx_nodes),
+ .nodes = &gem_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_tx_nodes),
},
- /*
- * This clock control requires different registers for mux and gate.
- * Use control and status registers for the same.
- */
[CLK_GEM3_TX] = {
.name = "gem3_tx",
- .control_reg = IOU_SLCR_GEM_CLK_CTRL,
- .status_reg = CRL_APB_GEM3_REF_CTRL,
+ .control_reg = CRL_APB_GEM3_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_GEM3_REF,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_tx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_tx_nodes),
+ },
+ [CLK_GEM0_RX] = {
+ .name = "gem0_rx",
+ .control_reg = CRL_APB_GEM0_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_rx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ },
+ [CLK_GEM1_RX] = {
+ .name = "gem1_rx",
+ .control_reg = CRL_APB_GEM1_REF_CTRL,
+ .status_reg = 0,
.parents = &((int32_t []) {
- CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
- EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
+ EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT,
CLK_NA_PARENT
}),
- .nodes = &gem3_tx_nodes,
- .num_nodes = ARRAY_SIZE(gem3_tx_nodes),
+ .nodes = &gem_rx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ },
+ [CLK_GEM2_RX] = {
+ .name = "gem2_rx",
+ .control_reg = CRL_APB_GEM2_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_rx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_rx_nodes),
+ },
+ [CLK_GEM3_RX] = {
+ .name = "gem3_rx",
+ .control_reg = CRL_APB_GEM3_REF_CTRL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &gem_rx_nodes,
+ .num_nodes = ARRAY_SIZE(gem_rx_nodes),
},
[CLK_ACPU_HALF] = {
.name = "acpu_half",
@@ -2035,8 +2104,8 @@ static struct pm_clock clocks[] = {
.nodes = &acpu_half_nodes,
.num_nodes = ARRAY_SIZE(acpu_half_nodes),
},
- [CLK_WDT] = {
- .name = "wdt",
+ [CLK_FPD_WDT] = {
+ .name = "fpd_wdt",
.control_reg = FPD_SLCR_WDT_CLK_SEL,
.status_reg = 0,
.parents = &((int32_t []) {
@@ -2135,6 +2204,18 @@ static struct pm_clock clocks[] = {
.nodes = &can1_nodes,
.num_nodes = ARRAY_SIZE(can1_nodes),
},
+ [CLK_LPD_WDT] = {
+ .name = "lpd_wdt",
+ .control_reg = IOU_SLCR_WDT_CLK_SEL,
+ .status_reg = 0,
+ .parents = &((int32_t []) {
+ CLK_LPD_LSBUS,
+ EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
+ CLK_NA_PARENT
+ }),
+ .nodes = &wdt_nodes,
+ .num_nodes = ARRAY_SIZE(wdt_nodes),
+ },
};
static struct pm_ext_clock ext_clocks[] = {
@@ -2159,17 +2240,29 @@ static struct pm_ext_clock ext_clocks[] = {
[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
.name = "swdt1_ext_clk",
},
- [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
- .name = "gem0_emio_clk",
+ [EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = {
+ .name = "gem0_tx_ext",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = {
+ .name = "gem1_tx_ext",
},
- [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
- .name = "gem1_emio_clk",
+ [EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = {
+ .name = "gem2_tx_ext",
},
- [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
- .name = "gem2_emio_clk",
+ [EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = {
+ .name = "gem3_tx_ext",
},
- [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
- .name = "gem3_emio_clk",
+ [EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = {
+ .name = "gem0_rx_ext",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = {
+ .name = "gem1_rx_ext",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = {
+ .name = "gem2_rx_ext",
+ },
+ [EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = {
+ .name = "gem3_rx_ext",
},
[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
.name = "mio_clk_50_51",
@@ -2265,10 +2358,8 @@ static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB,
CLK_DBG_TSTMP,
CLK_DDR_REF,
CLK_TOPSW_MAIN,
- CLK_TOPSW_LSBUS,
CLK_GTGREF0_REF,
CLK_LPD_SWITCH,
- CLK_LPD_LSBUS,
CLK_CPU_R5,
CLK_CPU_R5_CORE,
CLK_CSU_SPB,
@@ -2376,6 +2467,7 @@ enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
struct pm_clock_node *clock_nodes;
uint8_t num_nodes;
unsigned int i;
+ uint16_t typeflags;
if (!pm_clock_valid(clock_id))
return PM_RET_ERROR_ARGS;
@@ -2395,11 +2487,14 @@ enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
for (i = 0; i < 3U; i++) {
if ((index + i) == num_nodes)
break;
- topology[i] = clock_nodes[index + i].type;
+ topology[i] = clock_nodes[index + i].type;
topology[i] |= clock_nodes[index + i].clkflags <<
CLK_CLKFLAGS_SHIFT;
- topology[i] |= clock_nodes[index + i].typeflags <<
+ typeflags = clock_nodes[index + i].typeflags;
+ topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
CLK_TYPEFLAGS_SHIFT;
+ topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
+ (CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT);
}
return PM_RET_SUCCESS;
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
index 9717ca86af..48f5a5ec4f 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -43,7 +43,6 @@
#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */
/* parents need enable during gate/ungate, set rate and re-parent */
#define CLK_OPS_PARENT_ENABLE BIT(12)
-#define CLK_FRAC BIT(13)
#define CLK_DIVIDER_ONE_BASED BIT(0)
#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
@@ -52,6 +51,7 @@
#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
#define CLK_DIVIDER_READ_ONLY BIT(5)
#define CLK_DIVIDER_MAX_AT_ZERO BIT(6)
+#define CLK_FRAC BIT(8)
#define END_OF_CLK "END_OF_CLK"
@@ -102,14 +102,14 @@ enum clock_id {
CLK_IOU_SWITCH,
CLK_GEM_TSU_REF,
CLK_GEM_TSU,
- CLK_GEM0_REF,
- CLK_GEM1_REF,
- CLK_GEM2_REF,
- CLK_GEM3_REF,
CLK_GEM0_TX,
CLK_GEM1_TX,
CLK_GEM2_TX,
CLK_GEM3_TX,
+ CLK_GEM0_RX,
+ CLK_GEM1_RX,
+ CLK_GEM2_RX,
+ CLK_GEM3_RX,
CLK_QSPI_REF,
CLK_SDIO0_REF,
CLK_SDIO1_REF,
@@ -132,7 +132,7 @@ enum clock_id {
CLK_PL1_REF,
CLK_PL2_REF,
CLK_PL3_REF,
- CLK_WDT,
+ CLK_FPD_WDT,
CLK_IOPLL_INT,
CLK_IOPLL_PRE_SRC,
CLK_IOPLL_HALF,
@@ -161,6 +161,15 @@ enum clock_id {
CLK_CAN0_MIO,
CLK_CAN1_MIO,
CLK_ACPU_FULL,
+ CLK_GEM0_REF,
+ CLK_GEM1_REF,
+ CLK_GEM2_REF,
+ CLK_GEM3_REF,
+ CLK_GEM0_REF_UNGATED,
+ CLK_GEM1_REF_UNGATED,
+ CLK_GEM2_REF_UNGATED,
+ CLK_GEM3_REF_UNGATED,
+ CLK_LPD_WDT,
END_OF_OUTPUT_CLKS,
};
@@ -175,10 +184,14 @@ enum {
EXT_CLK_GT_CRX_REF,
EXT_CLK_SWDT0,
EXT_CLK_SWDT1,
- EXT_CLK_GEM0_EMIO,
- EXT_CLK_GEM1_EMIO,
- EXT_CLK_GEM2_EMIO,
- EXT_CLK_GEM3_EMIO,
+ EXT_CLK_GEM0_TX_EMIO,
+ EXT_CLK_GEM1_TX_EMIO,
+ EXT_CLK_GEM2_TX_EMIO,
+ EXT_CLK_GEM3_TX_EMIO,
+ EXT_CLK_GEM0_RX_EMIO,
+ EXT_CLK_GEM1_RX_EMIO,
+ EXT_CLK_GEM2_RX_EMIO,
+ EXT_CLK_GEM3_RX_EMIO,
EXT_CLK_MIO50_OR_MIO51,
EXT_CLK_MIO0,
EXT_CLK_MIO1,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
index e0b9816e4f..cd6f44f832 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -630,6 +630,22 @@ enum pm_ret_status pm_aes_engine(uint32_t address_high,
}
/**
+ * pm_get_callbackdata() - Read from IPI response buffer
+ * @data - array of PAYLOAD_ARG_CNT elements
+ *
+ * Read value from ipi buffer response buffer.
+ */
+void pm_get_callbackdata(uint32_t *data, size_t count)
+{
+ /* Return if interrupt is not from PMU */
+ if (!pm_ipi_irq_status(primary_proc))
+ return;
+
+ pm_ipi_buff_read_callb(data, count);
+ pm_ipi_irq_clear(primary_proc);
+}
+
+/**
* pm_pinctrl_request() - Request Pin from firmware
* @pin Pin number to request
*
diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
index 282ca3dc65..56c004339b 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
+++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -116,6 +116,7 @@ enum pm_ret_status pm_secure_rsaaes(uint32_t address_high,
uint32_t size,
uint32_t flags);
unsigned int pm_get_shutdown_scope(void);
+void pm_get_callbackdata(uint32_t *data, size_t count);
enum pm_ret_status pm_pinctrl_request(unsigned int pin);
enum pm_ret_status pm_pinctrl_release(unsigned int pin);
enum pm_ret_status pm_pinctrl_get_function(unsigned int pin,
diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
index faa2827450..5a320f1bae 100644
--- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
+++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -25,6 +25,7 @@
#include "pm_client.h"
#include "pm_ipi.h"
+#define PM_GET_CALLBACK_DATA 0xa01
#define PM_SET_SUSPEND_MODE 0xa02
#define PM_GET_TRUSTZONE_VERSION 0xa03
@@ -412,6 +413,16 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
pm_arg[3]);
SMC_RET1(handle, (uint64_t)ret);
+ case PM_GET_CALLBACK_DATA:
+ {
+ uint32_t result[4] = {0};
+
+ pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t)));
+ SMC_RET2(handle,
+ (uint64_t)result[0] | ((uint64_t)result[1] << 32),
+ (uint64_t)result[2] | ((uint64_t)result[3] << 32));
+ }
+
case PM_PINCTRL_REQUEST:
ret = pm_pinctrl_request(pm_arg[0]);
SMC_RET1(handle, (uint64_t)ret);
diff --git a/services/std_svc/spm/README.rst b/services/std_svc/spm/README.rst
deleted file mode 100644
index 63406a3bb9..0000000000
--- a/services/std_svc/spm/README.rst
+++ /dev/null
@@ -1,3 +0,0 @@
-This is a prototype loosely based on the SPCI Alpha and SPRT pre-alpha
-specifications. Any interface / platform API introduced for this is subject to
-change as it evolves.
diff --git a/services/std_svc/spm/aarch64/spm_helpers.S b/services/std_svc/spm/aarch64/spm_helpers.S
deleted file mode 100644
index aa35811f14..0000000000
--- a/services/std_svc/spm/aarch64/spm_helpers.S
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <asm_macros.S>
-#include "../spm_private.h"
-
- .global spm_secure_partition_enter
- .global spm_secure_partition_exit
-
- /* ---------------------------------------------------------------------
- * This function is called with SP_EL0 as stack. Here we stash our EL3
- * callee-saved registers on to the stack as a part of saving the C
- * runtime and enter the secure payload.
- * 'x0' contains a pointer to the memory where the address of the C
- * runtime context is to be saved.
- * ---------------------------------------------------------------------
- */
-func spm_secure_partition_enter
- /* Make space for the registers that we're going to save */
- mov x3, sp
- str x3, [x0, #0]
- sub sp, sp, #SP_C_RT_CTX_SIZE
-
- /* Save callee-saved registers on to the stack */
- stp x19, x20, [sp, #SP_C_RT_CTX_X19]
- stp x21, x22, [sp, #SP_C_RT_CTX_X21]
- stp x23, x24, [sp, #SP_C_RT_CTX_X23]
- stp x25, x26, [sp, #SP_C_RT_CTX_X25]
- stp x27, x28, [sp, #SP_C_RT_CTX_X27]
- stp x29, x30, [sp, #SP_C_RT_CTX_X29]
-
- /* ---------------------------------------------------------------------
- * Everything is setup now. el3_exit() will use the secure context to
- * restore to the general purpose and EL3 system registers to ERET
- * into the secure payload.
- * ---------------------------------------------------------------------
- */
- b el3_exit
-endfunc spm_secure_partition_enter
-
- /* ---------------------------------------------------------------------
- * This function is called with 'x0' pointing to a C runtime context
- * saved in spm_secure_partition_enter().
- * It restores the saved registers and jumps to that runtime with 'x0'
- * as the new SP register. This destroys the C runtime context that had
- * been built on the stack below the saved context by the caller. Later
- * the second parameter 'x1' is passed as a return value to the caller.
- * ---------------------------------------------------------------------
- */
-func spm_secure_partition_exit
- /* Restore the previous stack */
- mov sp, x0
-
- /* Restore callee-saved registers on to the stack */
- ldp x19, x20, [x0, #(SP_C_RT_CTX_X19 - SP_C_RT_CTX_SIZE)]
- ldp x21, x22, [x0, #(SP_C_RT_CTX_X21 - SP_C_RT_CTX_SIZE)]
- ldp x23, x24, [x0, #(SP_C_RT_CTX_X23 - SP_C_RT_CTX_SIZE)]
- ldp x25, x26, [x0, #(SP_C_RT_CTX_X25 - SP_C_RT_CTX_SIZE)]
- ldp x27, x28, [x0, #(SP_C_RT_CTX_X27 - SP_C_RT_CTX_SIZE)]
- ldp x29, x30, [x0, #(SP_C_RT_CTX_X29 - SP_C_RT_CTX_SIZE)]
-
- /* ---------------------------------------------------------------------
- * This should take us back to the instruction after the call to the
- * last spm_secure_partition_enter().* Place the second parameter to x0
- * so that the caller will see it as a return value from the original
- * entry call.
- * ---------------------------------------------------------------------
- */
- mov x0, x1
- ret
-endfunc spm_secure_partition_exit
diff --git a/services/std_svc/spm/spci.c b/services/std_svc/spm/spci.c
deleted file mode 100644
index 2e12a6c6b2..0000000000
--- a/services/std_svc/spm/spci.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/spinlock.h>
-#include <lib/utils.h>
-#include <services/spci_svc.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-#include <sprt_host.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Macros to print UUIDs.
- ******************************************************************************/
-#define PRINT_UUID_FORMAT "%08x-%08x-%08x-%08x"
-#define PRINT_UUID_ARGS(x) x[0], x[1], x[2], x[3]
-
-/*******************************************************************************
- * Array of structs that contains information about all handles of Secure
- * Services that are currently open.
- ******************************************************************************/
-typedef enum spci_handle_status {
- HANDLE_STATUS_CLOSED = 0,
- HANDLE_STATUS_OPEN,
-} spci_handle_status_t;
-
-typedef struct spci_handle {
- /* 16-bit value used as reference in all SPCI calls */
- uint16_t handle;
-
- /* Client ID of the client that requested the handle */
- uint16_t client_id;
-
- /* Current status of the handle */
- spci_handle_status_t status;
-
- /*
- * Context of the Secure Partition that provides the Secure Service
- * referenced by this handle.
- */
- sp_context_t *sp_ctx;
-
- /*
- * The same handle might be used for multiple requests, keep a reference
- * counter of them.
- */
- unsigned int num_active_requests;
-} spci_handle_t;
-
-static spci_handle_t spci_handles[PLAT_SPCI_HANDLES_MAX_NUM];
-static spinlock_t spci_handles_lock;
-
-/*
- * Given a handle and a client ID, return the element of the spci_handles
- * array that contains the information of the handle. It can only return open
- * handles. It returns NULL if it couldn't find the element in the array.
- */
-static spci_handle_t *spci_handle_info_get(uint16_t handle, uint16_t client_id)
-{
- size_t i;
-
- for (i = 0; i < ARRAY_SIZE(spci_handles); i++) {
- spci_handle_t *h = &(spci_handles[i]);
-
- /* Only check for open handles */
- if (h->status == HANDLE_STATUS_CLOSED) {
- continue;
- }
-
- /* Check if either the handle or the client ID are different */
- if ((h->handle != handle) || (h->client_id != client_id)) {
- continue;
- }
-
- return h;
- }
-
- return NULL;
-}
-
-/*
- * Returns a unique value for a handle. This function must be called while
- * spci_handles_lock is locked. It returns 0 on success, -1 on error.
- */
-static int spci_create_handle_value(uint16_t *handle)
-{
- /*
- * Trivial implementation that relies on the fact that any handle will
- * be closed before 2^16 more handles have been opened.
- */
- static uint16_t handle_count;
-
- *handle = handle_count;
-
- handle_count++;
-
- return 0;
-}
-
-/*******************************************************************************
- * Returns a unique token for a Secure Service request.
- ******************************************************************************/
-static uint32_t spci_create_token_value(void)
-{
- /*
- * Trivial implementation that relies on the fact that any response will
- * be read before 2^32 more service requests have been done.
- */
- static uint32_t token_count;
-
- return token_count++;
-}
-
-/*******************************************************************************
- * This function looks for a Secure Partition that has a Secure Service
- * identified by the given UUID. It returns a handle that the client can use to
- * access the service, and an SPCI_*** error code.
- ******************************************************************************/
-static uint64_t spci_service_handle_open_poll(void *handle, u_register_t x1,
- u_register_t x2, u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6, u_register_t x7)
-{
- unsigned int i;
- sp_context_t *sp_ptr;
- uint16_t service_handle;
-
- /* Bits 31:16 of w7 are reserved (MBZ). */
- assert((x7 & 0xFFFF0000U) == 0);
-
- uint16_t client_id = x7 & 0x0000FFFFU;
- uint32_t uuid[4] = { x1, x2, x3, x4 };
-
- /* Get pointer to the Secure Partition that handles this service */
- sp_ptr = spm_sp_get_by_uuid(&uuid);
- if (sp_ptr == NULL) {
- WARN("SPCI: Service requested by client 0x%04x not found\n",
- client_id);
- WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n",
- PRINT_UUID_ARGS(uuid));
-
- SMC_RET2(handle, SPCI_NOT_PRESENT, 0);
- }
-
- /* Get lock of the array of handles */
- spin_lock(&spci_handles_lock);
-
- /*
- * We need to record the client ID and Secure Partition that correspond
- * to this handle. Look for the first free entry in the array.
- */
- for (i = 0; i < PLAT_SPCI_HANDLES_MAX_NUM; i++) {
- if (spci_handles[i].status == HANDLE_STATUS_CLOSED) {
- break;
- }
- }
-
- if (i == PLAT_SPCI_HANDLES_MAX_NUM) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI: Can't open more handles. Client 0x%04x\n",
- client_id);
- WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n",
- PRINT_UUID_ARGS(uuid));
-
- SMC_RET2(handle, SPCI_NO_MEMORY, 0);
- }
-
- /* Create new handle value */
- if (spci_create_handle_value(&service_handle) != 0) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI: Can't create a new handle value. Client 0x%04x\n",
- client_id);
- WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n",
- PRINT_UUID_ARGS(uuid));
-
- SMC_RET2(handle, SPCI_NO_MEMORY, 0);
- }
-
- /* Save all information about this handle */
- spci_handles[i].status = HANDLE_STATUS_OPEN;
- spci_handles[i].client_id = client_id;
- spci_handles[i].handle = service_handle;
- spci_handles[i].num_active_requests = 0U;
- spci_handles[i].sp_ctx = sp_ptr;
-
- /* Release lock of the array of handles */
- spin_unlock(&spci_handles_lock);
-
- VERBOSE("SPCI: Service handle request by client 0x%04x: 0x%04x\n",
- client_id, service_handle);
- VERBOSE("SPCI: UUID: " PRINT_UUID_FORMAT "\n", PRINT_UUID_ARGS(uuid));
-
- /* The handle is returned in the top 16 bits of x1 */
- SMC_RET2(handle, SPCI_SUCCESS, ((uint32_t)service_handle) << 16);
-}
-
-/*******************************************************************************
- * This function closes a handle that a specific client uses to access a Secure
- * Service. It returns a SPCI_*** error code.
- ******************************************************************************/
-static uint64_t spci_service_handle_close(void *handle, u_register_t x1)
-{
- spci_handle_t *handle_info;
- uint16_t client_id = x1 & 0x0000FFFFU;
- uint16_t service_handle = (x1 >> 16) & 0x0000FFFFU;
-
- spin_lock(&spci_handles_lock);
-
- handle_info = spci_handle_info_get(service_handle, client_id);
-
- if (handle_info == NULL) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI: Tried to close invalid handle 0x%04x by client 0x%04x\n",
- service_handle, client_id);
-
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- if (handle_info->status != HANDLE_STATUS_OPEN) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x in status %d\n",
- service_handle, client_id, handle_info->status);
-
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- if (handle_info->num_active_requests != 0U) {
- spin_unlock(&spci_handles_lock);
-
- /* A handle can't be closed if there are requests left */
- WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x with %d requests left\n",
- service_handle, client_id,
- handle_info->num_active_requests);
-
- SMC_RET1(handle, SPCI_BUSY);
- }
-
- memset(handle_info, 0, sizeof(spci_handle_t));
-
- handle_info->status = HANDLE_STATUS_CLOSED;
-
- spin_unlock(&spci_handles_lock);
-
- VERBOSE("SPCI: Closed handle 0x%04x by client 0x%04x.\n",
- service_handle, client_id);
-
- SMC_RET1(handle, SPCI_SUCCESS);
-}
-
-/*******************************************************************************
- * This function requests a Secure Service from a given handle and client ID.
- ******************************************************************************/
-static uint64_t spci_service_request_blocking(void *handle,
- uint32_t smc_fid, u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4, u_register_t x5,
- u_register_t x6, u_register_t x7)
-{
- spci_handle_t *handle_info;
- sp_context_t *sp_ctx;
- cpu_context_t *cpu_ctx;
- uint32_t rx0;
- u_register_t rx1, rx2, rx3;
- uint16_t request_handle, client_id;
-
- /* Get handle array lock */
- spin_lock(&spci_handles_lock);
-
- /* Get pointer to struct of this open handle and client ID. */
- request_handle = (x7 >> 16U) & 0x0000FFFFU;
- client_id = x7 & 0x0000FFFFU;
-
- handle_info = spci_handle_info_get(request_handle, client_id);
- if (handle_info == NULL) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Not found.\n");
- WARN(" Handle 0x%04x. Client ID 0x%04x\n", request_handle,
- client_id);
-
- SMC_RET1(handle, SPCI_BUSY);
- }
-
- /* Get pointer to the Secure Partition that handles the service */
- sp_ctx = handle_info->sp_ctx;
- assert(sp_ctx != NULL);
- cpu_ctx = &(sp_ctx->cpu_ctx);
-
- /* Blocking requests are only allowed if the queue is empty */
- if (handle_info->num_active_requests > 0) {
- spin_unlock(&spci_handles_lock);
-
- SMC_RET1(handle, SPCI_BUSY);
- }
-
- if (spm_sp_request_increase_if_zero(sp_ctx) == -1) {
- spin_unlock(&spci_handles_lock);
-
- SMC_RET1(handle, SPCI_BUSY);
- }
-
- /* Prevent this handle from being closed */
- handle_info->num_active_requests += 1;
-
- /* Release handle lock */
- spin_unlock(&spci_handles_lock);
-
- /* Save the Normal world context */
- cm_el1_sysregs_context_save(NON_SECURE);
-
- /* Wait until the Secure Partition is idle and set it to busy. */
- sp_state_wait_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY);
-
- /* Pass arguments to the Secure Partition */
- struct sprt_queue_entry_message message = {
- .type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST,
- .client_id = client_id,
- .service_handle = request_handle,
- .session_id = x6,
- .token = 0, /* No token needed for blocking requests */
- .args = {smc_fid, x1, x2, x3, x4, x5}
- };
-
- spin_lock(&(sp_ctx->spm_sp_buffer_lock));
- int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message,
- SPRT_QUEUE_NUM_BLOCKING);
- spin_unlock(&(sp_ctx->spm_sp_buffer_lock));
- if (rc != 0) {
- /*
- * This shouldn't happen, blocking requests can only be made if
- * the request queue is empty.
- */
- assert(rc == -ENOMEM);
- ERROR("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Queue is full.\n");
- panic();
- }
-
- /* Jump to the Secure Partition. */
- rx0 = spm_sp_synchronous_entry(sp_ctx, 0);
-
- /* Verify returned value */
- if (rx0 != SPRT_PUT_RESPONSE_AARCH64) {
- ERROR("SPM: %s: Unexpected x0 value 0x%x\n", __func__, rx0);
- panic();
- }
-
- rx1 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3);
- rx2 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4);
- rx3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5);
-
- /* Flag Secure Partition as idle. */
- assert(sp_ctx->state == SP_STATE_BUSY);
- sp_state_set(sp_ctx, SP_STATE_IDLE);
-
- /* Decrease count of requests. */
- spin_lock(&spci_handles_lock);
- handle_info->num_active_requests -= 1;
- spin_unlock(&spci_handles_lock);
- spm_sp_request_decrease(sp_ctx);
-
- /* Restore non-secure state */
- cm_el1_sysregs_context_restore(NON_SECURE);
- cm_set_next_eret_context(NON_SECURE);
-
- SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function handles the returned values from the Secure Partition.
- ******************************************************************************/
-static void spci_handle_returned_values(const cpu_context_t *cpu_ctx,
- uint64_t ret)
-{
- if (ret == SPRT_PUT_RESPONSE_AARCH64) {
- uint32_t token;
- uint64_t x3, x4, x5, x6;
-
- token = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1);
- x3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3);
- x4 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4);
- x5 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5);
- x6 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X6);
-
- uint16_t client_id = x6 & 0xFFFFU;
- uint16_t service_handle = x6 >> 16;
-
- int rc = spm_response_add(client_id, service_handle, token,
- x3, x4, x5);
- if (rc != 0) {
- /*
- * This is error fatal because we can't return to the SP
- * from this SMC. The SP has crashed.
- */
- panic();
- }
- } else if ((ret != SPRT_YIELD_AARCH64) &&
- (ret != SPM_SECURE_PARTITION_PREEMPTED)) {
- ERROR("SPM: %s: Unexpected x0 value 0x%llx\n", __func__, ret);
- panic();
- }
-}
-
-/*******************************************************************************
- * This function requests a Secure Service from a given handle and client ID.
- ******************************************************************************/
-static uint64_t spci_service_request_start(void *handle,
- uint32_t smc_fid, u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4, u_register_t x5,
- u_register_t x6, u_register_t x7)
-{
- spci_handle_t *handle_info;
- sp_context_t *sp_ctx;
- cpu_context_t *cpu_ctx;
- uint16_t request_handle, client_id;
- uint32_t token;
-
- /* Get handle array lock */
- spin_lock(&spci_handles_lock);
-
- /* Get pointer to struct of this open handle and client ID. */
- request_handle = (x7 >> 16U) & 0x0000FFFFU;
- client_id = x7 & 0x0000FFFFU;
-
- handle_info = spci_handle_info_get(request_handle, client_id);
- if (handle_info == NULL) {
- spin_unlock(&spci_handles_lock);
-
- WARN("SPCI_SERVICE_TUN_REQUEST_START: Not found.\n"
- " Handle 0x%04x. Client ID 0x%04x\n", request_handle,
- client_id);
-
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- /* Get pointer to the Secure Partition that handles the service */
- sp_ctx = handle_info->sp_ctx;
- assert(sp_ctx != NULL);
- cpu_ctx = &(sp_ctx->cpu_ctx);
-
- /* Prevent this handle from being closed */
- handle_info->num_active_requests += 1;
-
- spm_sp_request_increase(sp_ctx);
-
- /* Create new token for this request */
- token = spci_create_token_value();
-
- /* Release handle lock */
- spin_unlock(&spci_handles_lock);
-
- /* Pass arguments to the Secure Partition */
- struct sprt_queue_entry_message message = {
- .type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST,
- .client_id = client_id,
- .service_handle = request_handle,
- .session_id = x6,
- .token = token,
- .args = {smc_fid, x1, x2, x3, x4, x5}
- };
-
- spin_lock(&(sp_ctx->spm_sp_buffer_lock));
- int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message,
- SPRT_QUEUE_NUM_NON_BLOCKING);
- spin_unlock(&(sp_ctx->spm_sp_buffer_lock));
- if (rc != 0) {
- WARN("SPCI_SERVICE_TUN_REQUEST_START: SPRT queue full.\n"
- " Handle 0x%04x. Client ID 0x%04x\n", request_handle,
- client_id);
- SMC_RET1(handle, SPCI_NO_MEMORY);
- }
-
- /* Try to enter the partition. If it's not possible, simply return. */
- if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) {
- SMC_RET2(handle, SPCI_SUCCESS, token);
- }
-
- /* Save the Normal world context */
- cm_el1_sysregs_context_save(NON_SECURE);
-
- /*
- * This request is non-blocking and needs to be interruptible by
- * non-secure interrupts. Enable their routing to EL3 during the
- * processing of the Secure Partition's service on this core.
- */
-
- /* Jump to the Secure Partition. */
- uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1);
-
- /* Handle returned values */
- spci_handle_returned_values(cpu_ctx, ret);
-
- /* Flag Secure Partition as idle. */
- assert(sp_ctx->state == SP_STATE_BUSY);
- sp_state_set(sp_ctx, SP_STATE_IDLE);
-
- /* Restore non-secure state */
- cm_el1_sysregs_context_restore(NON_SECURE);
- cm_set_next_eret_context(NON_SECURE);
-
- SMC_RET2(handle, SPCI_SUCCESS, token);
-}
-
-/*******************************************************************************
- * This function returns the response of a Secure Service given a handle, a
- * client ID and a token. If not available, it will schedule a Secure Partition
- * and give it CPU time.
- ******************************************************************************/
-static uint64_t spci_service_request_resume(void *handle, u_register_t x1,
- u_register_t x7)
-{
- int rc;
- u_register_t rx1 = 0, rx2 = 0, rx3 = 0;
- spci_handle_t *handle_info;
- sp_context_t *sp_ctx;
- cpu_context_t *cpu_ctx;
- uint32_t token = (uint32_t) x1;
- uint16_t client_id = x7 & 0x0000FFFF;
- uint16_t service_handle = (x7 >> 16) & 0x0000FFFF;
-
- /* Get pointer to struct of this open handle and client ID. */
- spin_lock(&spci_handles_lock);
-
- handle_info = spci_handle_info_get(service_handle, client_id);
- if (handle_info == NULL) {
- spin_unlock(&spci_handles_lock);
- WARN("SPCI_SERVICE_REQUEST_RESUME: Not found.\n"
- "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n",
- client_id, service_handle, token);
-
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- /* Get pointer to the Secure Partition that handles the service */
- sp_ctx = handle_info->sp_ctx;
- assert(sp_ctx != NULL);
- cpu_ctx = &(sp_ctx->cpu_ctx);
-
- spin_unlock(&spci_handles_lock);
-
- /* Look for a valid response in the global queue */
- rc = spm_response_get(client_id, service_handle, token,
- &rx1, &rx2, &rx3);
- if (rc == 0) {
- /* Decrease request count */
- spin_lock(&spci_handles_lock);
- handle_info->num_active_requests -= 1;
- spin_unlock(&spci_handles_lock);
- spm_sp_request_decrease(sp_ctx);
-
- SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
- }
-
- /* Try to enter the partition. If it's not possible, simply return. */
- if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) {
- SMC_RET1(handle, SPCI_QUEUED);
- }
-
- /* Save the Normal world context */
- cm_el1_sysregs_context_save(NON_SECURE);
-
- /*
- * This request is non-blocking and needs to be interruptible by
- * non-secure interrupts. Enable their routing to EL3 during the
- * processing of the Secure Partition's service on this core.
- */
-
- /* Jump to the Secure Partition. */
- uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1);
-
- /* Handle returned values */
- spci_handle_returned_values(cpu_ctx, ret);
-
- /* Flag Secure Partition as idle. */
- assert(sp_ctx->state == SP_STATE_BUSY);
- sp_state_set(sp_ctx, SP_STATE_IDLE);
-
- /* Restore non-secure state */
- cm_el1_sysregs_context_restore(NON_SECURE);
- cm_set_next_eret_context(NON_SECURE);
-
- /* Look for a valid response in the global queue */
- rc = spm_response_get(client_id, service_handle, token,
- &rx1, &rx2, &rx3);
- if (rc != 0) {
- SMC_RET1(handle, SPCI_QUEUED);
- }
-
- /* Decrease request count */
- spin_lock(&spci_handles_lock);
- handle_info->num_active_requests -= 1;
- spin_unlock(&spci_handles_lock);
- spm_sp_request_decrease(sp_ctx);
-
- /* Return response */
- SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function returns the response of a Secure Service given a handle, a
- * client ID and a token.
- ******************************************************************************/
-static uint64_t spci_service_get_response(void *handle, u_register_t x1,
- u_register_t x7)
-
-{
- int rc;
- u_register_t rx1 = 0, rx2 = 0, rx3 = 0;
- spci_handle_t *handle_info;
- uint32_t token = (uint32_t) x1;
- uint16_t client_id = x7 & 0x0000FFFF;
- uint16_t service_handle = (x7 >> 16) & 0x0000FFFF;
-
- /* Get pointer to struct of this open handle and client ID. */
-
- spin_lock(&spci_handles_lock);
-
- handle_info = spci_handle_info_get(service_handle, client_id);
- if (handle_info == NULL) {
- spin_unlock(&spci_handles_lock);
- WARN("SPCI_SERVICE_GET_RESPONSE: Not found.\n"
- "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n",
- client_id, service_handle, token);
-
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- spin_unlock(&spci_handles_lock);
-
- /* Look for a valid response in the global queue */
- rc = spm_response_get(client_id, service_handle, token,
- &rx1, &rx2, &rx3);
-
- if (rc != 0) {
- SMC_RET1(handle, SPCI_QUEUED);
- }
-
- /* Decrease request count */
- spin_lock(&spci_handles_lock);
- handle_info->num_active_requests -= 1;
- sp_context_t *sp_ctx;
- sp_ctx = handle_info->sp_ctx;
- spin_unlock(&spci_handles_lock);
- spm_sp_request_decrease(sp_ctx);
-
- /* Return response */
- SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3);
-}
-
-/*******************************************************************************
- * This function handles all SMCs in the range reserved for SPCI.
- ******************************************************************************/
-static uintptr_t spci_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)
-{
- uint32_t spci_fid;
-
- /* SPCI only supported from the Non-secure world for now */
- if (is_caller_non_secure(flags) == SMC_FROM_SECURE) {
- SMC_RET1(handle, SMC_UNK);
- }
-
- if ((smc_fid & SPCI_FID_TUN_FLAG) == 0) {
-
- /* Miscellaneous calls */
-
- spci_fid = (smc_fid >> SPCI_FID_MISC_SHIFT) & SPCI_FID_MISC_MASK;
-
- switch (spci_fid) {
-
- case SPCI_FID_VERSION:
- SMC_RET1(handle, SPCI_VERSION_COMPILED);
-
- case SPCI_FID_SERVICE_HANDLE_OPEN:
- {
- if ((smc_fid & SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT) != 0) {
- /* Not supported for now */
- WARN("SPCI_SERVICE_HANDLE_OPEN_NOTIFY not supported.\n");
- SMC_RET1(handle, SPCI_INVALID_PARAMETER);
- }
-
- uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
- uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
- uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
- return spci_service_handle_open_poll(handle, x1, x2, x3,
- x4, x5, x6, x7);
- }
- case SPCI_FID_SERVICE_HANDLE_CLOSE:
- return spci_service_handle_close(handle, x1);
-
- case SPCI_FID_SERVICE_REQUEST_BLOCKING:
- {
- uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
- uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
- uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
- return spci_service_request_blocking(handle,
- smc_fid, x1, x2, x3, x4, x5, x6, x7);
- }
-
- case SPCI_FID_SERVICE_REQUEST_START:
- {
- uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
- uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
- uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
- return spci_service_request_start(handle,
- smc_fid, x1, x2, x3, x4, x5, x6, x7);
- }
-
- case SPCI_FID_SERVICE_GET_RESPONSE:
- {
- uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
- return spci_service_get_response(handle, x1, x7);
- }
-
- default:
- break;
- }
-
- } else {
-
- /* Tunneled calls */
-
- spci_fid = (smc_fid >> SPCI_FID_TUN_SHIFT) & SPCI_FID_TUN_MASK;
-
- switch (spci_fid) {
-
- case SPCI_FID_SERVICE_REQUEST_RESUME:
- {
- uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
-
- return spci_service_request_resume(handle, x1, x7);
- }
-
- default:
- break;
- }
- }
-
- WARN("SPCI: Unsupported call 0x%08x\n", smc_fid);
- SMC_RET1(handle, SPCI_NOT_SUPPORTED);
-}
-
-DECLARE_RT_SVC(
- spci_handler,
- OEN_SPCI_START,
- OEN_SPCI_END,
- SMC_TYPE_FAST,
- NULL,
- spci_smc_handler
-);
diff --git a/services/std_svc/spm/spm.mk b/services/std_svc/spm/spm.mk
deleted file mode 100644
index 448aba4099..0000000000
--- a/services/std_svc/spm/spm.mk
+++ /dev/null
@@ -1,30 +0,0 @@
-#
-# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-
-ifneq (${SPD},none)
- $(error "Error: SPD and SPM are incompatible build options.")
-endif
-ifneq (${ARCH},aarch64)
- $(error "Error: SPM is only supported on aarch64.")
-endif
-
-include lib/sprt/sprt_host.mk
-
-SPM_SOURCES := $(addprefix services/std_svc/spm/, \
- ${ARCH}/spm_helpers.S \
- ${ARCH}/spm_shim_exceptions.S \
- spci.c \
- spm_buffers.c \
- spm_main.c \
- spm_setup.c \
- spm_xlat.c \
- sprt.c) \
- ${SPRT_LIB_SOURCES}
-
-INCLUDES += ${SPRT_LIB_INCLUDES}
-
-# Let the top-level Makefile know that we intend to include a BL32 image
-NEED_BL32 := yes
diff --git a/services/std_svc/spm/spm_buffers.c b/services/std_svc/spm/spm_buffers.c
deleted file mode 100644
index 79398ba151..0000000000
--- a/services/std_svc/spm/spm_buffers.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch_helpers.h>
-#include <lib/spinlock.h>
-#include <lib/utils_def.h>
-#include <platform_def.h>
-
-#include "./spm_private.h"
-
-/*******************************************************************************
- * Secure Service response global array. All the responses to the requests done
- * to the Secure Partition are stored here. They are removed from the array as
- * soon as their value is read.
- ******************************************************************************/
-struct sprt_response {
- int is_valid;
- uint32_t token;
- uint16_t client_id, handle;
- u_register_t x1, x2, x3;
-};
-
-static struct sprt_response responses[PLAT_SPM_RESPONSES_MAX];
-
-static spinlock_t responses_lock;
-
-/* Add response to the global response buffer. Returns 0 on success else -1. */
-int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token,
- u_register_t x1, u_register_t x2, u_register_t x3)
-{
- spin_lock(&responses_lock);
-
- /* Make sure that there isn't any other response with the same token. */
- for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
- struct sprt_response *resp = &(responses[i]);
-
- if ((resp->is_valid == 1) && (resp->token == token)) {
- spin_unlock(&responses_lock);
-
- return -1;
- }
- }
-
- for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
- struct sprt_response *resp = &(responses[i]);
-
- if (resp->is_valid == 0) {
- resp->token = token;
- resp->client_id = client_id;
- resp->handle = handle;
- resp->x1 = x1;
- resp->x2 = x2;
- resp->x3 = x3;
-
- dmbish();
-
- resp->is_valid = 1;
-
- spin_unlock(&responses_lock);
-
- return 0;
- }
- }
-
- spin_unlock(&responses_lock);
-
- return -1;
-}
-
-/*
- * Returns a response from the requests array and removes it from it. Returns 0
- * on success, -1 if it wasn't found.
- */
-int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token,
- u_register_t *x1, u_register_t *x2, u_register_t *x3)
-{
- spin_lock(&responses_lock);
-
- for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) {
- struct sprt_response *resp = &(responses[i]);
-
- /* Ignore invalid entries */
- if (resp->is_valid == 0) {
- continue;
- }
-
- /* Make sure that all the information matches the stored one */
- if ((resp->token != token) || (resp->client_id != client_id) ||
- (resp->handle != handle)) {
- continue;
- }
-
- *x1 = resp->x1;
- *x2 = resp->x2;
- *x3 = resp->x3;
-
- dmbish();
-
- resp->is_valid = 0;
-
- spin_unlock(&responses_lock);
-
- return 0;
- }
-
- spin_unlock(&responses_lock);
-
- return -1;
-}
diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c
deleted file mode 100644
index 3a63f1c69f..0000000000
--- a/services/std_svc/spm/spm_main.c
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <arch_helpers.h>
-#include <bl31/bl31.h>
-#include <bl31/ehf.h>
-#include <bl31/interrupt_mgmt.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/spinlock.h>
-#include <lib/utils.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-#include <services/spm_svc.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Secure Partition context information.
- ******************************************************************************/
-sp_context_t sp_ctx_array[PLAT_SPM_MAX_PARTITIONS];
-
-/* Last Secure Partition last used by the CPU */
-sp_context_t *cpu_sp_ctx[PLATFORM_CORE_COUNT];
-
-void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx)
-{
- assert(linear_id < PLATFORM_CORE_COUNT);
-
- cpu_sp_ctx[linear_id] = sp_ctx;
-}
-
-sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id)
-{
- assert(linear_id < PLATFORM_CORE_COUNT);
-
- return cpu_sp_ctx[linear_id];
-}
-
-/*******************************************************************************
- * Functions to keep track of how many requests a Secure Partition has received
- * and hasn't finished.
- ******************************************************************************/
-void spm_sp_request_increase(sp_context_t *sp_ctx)
-{
- spin_lock(&(sp_ctx->request_count_lock));
- sp_ctx->request_count++;
- spin_unlock(&(sp_ctx->request_count_lock));
-}
-
-void spm_sp_request_decrease(sp_context_t *sp_ctx)
-{
- spin_lock(&(sp_ctx->request_count_lock));
- sp_ctx->request_count--;
- spin_unlock(&(sp_ctx->request_count_lock));
-}
-
-/* Returns 0 if it was originally 0, -1 otherwise. */
-int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx)
-{
- int ret = -1;
-
- spin_lock(&(sp_ctx->request_count_lock));
- if (sp_ctx->request_count == 0U) {
- sp_ctx->request_count++;
- ret = 0U;
- }
- spin_unlock(&(sp_ctx->request_count_lock));
-
- return ret;
-}
-
-/*******************************************************************************
- * This function returns a pointer to the context of the Secure Partition that
- * handles the service specified by an UUID. It returns NULL if the UUID wasn't
- * found.
- ******************************************************************************/
-sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4])
-{
- unsigned int i;
-
- for (i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) {
-
- sp_context_t *sp_ctx = &sp_ctx_array[i];
-
- if (sp_ctx->is_present == 0) {
- continue;
- }
-
- struct sp_rd_sect_service *rdsvc;
-
- for (rdsvc = sp_ctx->rd.service; rdsvc != NULL;
- rdsvc = rdsvc->next) {
- uint32_t *rd_uuid = (uint32_t *)(rdsvc->uuid);
-
- if (memcmp(rd_uuid, svc_uuid, sizeof(*svc_uuid)) == 0) {
- return sp_ctx;
- }
- }
- }
-
- return NULL;
-}
-
-/*******************************************************************************
- * Set state of a Secure Partition context.
- ******************************************************************************/
-void sp_state_set(sp_context_t *sp_ptr, sp_state_t state)
-{
- spin_lock(&(sp_ptr->state_lock));
- sp_ptr->state = state;
- spin_unlock(&(sp_ptr->state_lock));
-}
-
-/*******************************************************************************
- * Wait until the state of a Secure Partition is the specified one and change it
- * to the desired state.
- ******************************************************************************/
-void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
- int success = 0;
-
- while (success == 0) {
- spin_lock(&(sp_ptr->state_lock));
-
- if (sp_ptr->state == from) {
- sp_ptr->state = to;
-
- success = 1;
- }
-
- spin_unlock(&(sp_ptr->state_lock));
- }
-}
-
-/*******************************************************************************
- * Check if the state of a Secure Partition is the specified one and, if so,
- * change it to the desired state. Returns 0 on success, -1 on error.
- ******************************************************************************/
-int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to)
-{
- int ret = -1;
-
- spin_lock(&(sp_ptr->state_lock));
-
- if (sp_ptr->state == from) {
- sp_ptr->state = to;
-
- ret = 0;
- }
-
- spin_unlock(&(sp_ptr->state_lock));
-
- return ret;
-}
-
-/*******************************************************************************
- * This function takes an SP context pointer and performs a synchronous entry
- * into it.
- ******************************************************************************/
-uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt)
-{
- uint64_t rc;
- unsigned int linear_id = plat_my_core_pos();
-
- assert(sp_ctx != NULL);
-
- /* Assign the context of the SP to this CPU */
- spm_cpu_set_sp_ctx(linear_id, sp_ctx);
- cm_set_context(&(sp_ctx->cpu_ctx), SECURE);
-
- /* Restore the context assigned above */
- cm_el1_sysregs_context_restore(SECURE);
- cm_set_next_eret_context(SECURE);
-
- /* Invalidate TLBs at EL1. */
- tlbivmalle1();
- dsbish();
-
- if (can_preempt == 1) {
- enable_intr_rm_local(INTR_TYPE_NS, SECURE);
- } else {
- disable_intr_rm_local(INTR_TYPE_NS, SECURE);
- }
-
- /* Enter Secure Partition */
- rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx);
-
- /* Save secure state */
- cm_el1_sysregs_context_save(SECURE);
-
- return rc;
-}
-
-/*******************************************************************************
- * This function returns to the place where spm_sp_synchronous_entry() was
- * called originally.
- ******************************************************************************/
-__dead2 void spm_sp_synchronous_exit(uint64_t rc)
-{
- /* Get context of the SP in use by this CPU. */
- unsigned int linear_id = plat_my_core_pos();
- sp_context_t *ctx = spm_cpu_get_sp_ctx(linear_id);
-
- /*
- * The SPM must have initiated the original request through a
- * synchronous entry into the secure partition. Jump back to the
- * original C runtime context with the value of rc in x0;
- */
- spm_secure_partition_exit(ctx->c_rt_ctx, rc);
-
- panic();
-}
-
-/*******************************************************************************
- * This function is the handler registered for Non secure interrupts by the SPM.
- * It validates the interrupt and upon success arranges entry into the normal
- * world for handling the interrupt.
- ******************************************************************************/
-static uint64_t spm_ns_interrupt_handler(uint32_t id, uint32_t flags,
- void *handle, void *cookie)
-{
- /* Check the security state when the exception was generated */
- assert(get_interrupt_src_ss(flags) == SECURE);
-
- spm_sp_synchronous_exit(SPM_SECURE_PARTITION_PREEMPTED);
-}
-
-/*******************************************************************************
- * Jump to each Secure Partition for the first time.
- ******************************************************************************/
-static int32_t spm_init(void)
-{
- uint64_t rc = 0;
- sp_context_t *ctx;
-
- for (unsigned int i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) {
-
- ctx = &sp_ctx_array[i];
-
- if (ctx->is_present == 0) {
- continue;
- }
-
- INFO("Secure Partition %u init...\n", i);
-
- ctx->state = SP_STATE_RESET;
-
- rc = spm_sp_synchronous_entry(ctx, 0);
- if (rc != SPRT_YIELD_AARCH64) {
- ERROR("Unexpected return value 0x%llx\n", rc);
- panic();
- }
-
- ctx->state = SP_STATE_IDLE;
-
- INFO("Secure Partition %u initialized.\n", i);
- }
-
- return rc;
-}
-
-/*******************************************************************************
- * Initialize contexts of all Secure Partitions.
- ******************************************************************************/
-int32_t spm_setup(void)
-{
- int rc;
- sp_context_t *ctx;
- void *sp_base, *rd_base;
- size_t sp_size, rd_size;
- uint64_t flags = 0U;
-
- /* Disable MMU at EL1 (initialized by BL2) */
- disable_mmu_icache_el1();
-
- /*
- * Non-blocking services can be interrupted by Non-secure interrupts.
- * Register an interrupt handler for NS interrupts when generated while
- * the CPU is in secure state. They are routed to EL3.
- */
- set_interrupt_rm_flag(flags, SECURE);
-
- uint64_t rc_int = register_interrupt_type_handler(INTR_TYPE_NS,
- spm_ns_interrupt_handler, flags);
- if (rc_int) {
- ERROR("SPM: Failed to register NS interrupt handler with rc = %llx\n",
- rc_int);
- panic();
- }
-
- /* Setup shim layer */
- spm_exceptions_xlat_init_context();
-
- /*
- * Setup all Secure Partitions.
- */
- unsigned int i = 0U;
-
- while (1) {
- rc = plat_spm_sp_get_next_address(&sp_base, &sp_size,
- &rd_base, &rd_size);
- if (rc < 0) {
- /* Reached the end of the package. */
- break;
- }
-
- if (i >= PLAT_SPM_MAX_PARTITIONS) {
- ERROR("Too many partitions in the package.\n");
- panic();
- }
-
- ctx = &sp_ctx_array[i];
-
- assert(ctx->is_present == 0);
-
- /* Initialize context of the SP */
- INFO("Secure Partition %u context setup start...\n", i);
-
- /* Save location of the image in physical memory */
- ctx->image_base = (uintptr_t)sp_base;
- ctx->image_size = sp_size;
-
- rc = plat_spm_sp_rd_load(&ctx->rd, rd_base, rd_size);
- if (rc < 0) {
- ERROR("Error while loading RD blob.\n");
- panic();
- }
-
- spm_sp_setup(ctx);
-
- ctx->is_present = 1;
-
- INFO("Secure Partition %u setup done.\n", i);
-
- i++;
- }
-
- if (i == 0U) {
- ERROR("No present partitions in the package.\n");
- panic();
- }
-
- /* Register init function for deferred init. */
- bl31_register_bl32_init(&spm_init);
-
- return 0;
-}
diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h
deleted file mode 100644
index efc91cb41d..0000000000
--- a/services/std_svc/spm/spm_private.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_PRIVATE_H
-#define SPM_PRIVATE_H
-
-#include <context.h>
-
-/*******************************************************************************
- * Constants that allow assembler code to preserve callee-saved registers of the
- * C runtime context while performing a security state switch.
- ******************************************************************************/
-#define SP_C_RT_CTX_X19 0x0
-#define SP_C_RT_CTX_X20 0x8
-#define SP_C_RT_CTX_X21 0x10
-#define SP_C_RT_CTX_X22 0x18
-#define SP_C_RT_CTX_X23 0x20
-#define SP_C_RT_CTX_X24 0x28
-#define SP_C_RT_CTX_X25 0x30
-#define SP_C_RT_CTX_X26 0x38
-#define SP_C_RT_CTX_X27 0x40
-#define SP_C_RT_CTX_X28 0x48
-#define SP_C_RT_CTX_X29 0x50
-#define SP_C_RT_CTX_X30 0x58
-
-#define SP_C_RT_CTX_SIZE 0x60
-#define SP_C_RT_CTX_ENTRIES (SP_C_RT_CTX_SIZE >> DWORD_SHIFT)
-
-/* Value returned by spm_sp_synchronous_entry() when a partition is preempted */
-#define SPM_SECURE_PARTITION_PREEMPTED U(0x1234)
-
-#ifndef __ASSEMBLER__
-
-#include <stdint.h>
-
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <lib/spinlock.h>
-#include <services/sp_res_desc.h>
-
-typedef enum sp_state {
- SP_STATE_RESET = 0,
- SP_STATE_IDLE,
- SP_STATE_BUSY
-} sp_state_t;
-
-typedef struct sp_context {
- /* 1 if the partition is present, 0 otherwise */
- int is_present;
-
- /* Location of the image in physical memory */
- unsigned long long image_base;
- size_t image_size;
-
- uint64_t c_rt_ctx;
- cpu_context_t cpu_ctx;
- struct sp_res_desc rd;
-
- /* Translation tables context */
- xlat_ctx_t *xlat_ctx_handle;
- spinlock_t xlat_ctx_lock;
-
- sp_state_t state;
- spinlock_t state_lock;
-
- unsigned int request_count;
- spinlock_t request_count_lock;
-
- /* Base and size of the shared SPM<->SP buffer */
- uintptr_t spm_sp_buffer_base;
- size_t spm_sp_buffer_size;
- spinlock_t spm_sp_buffer_lock;
-} sp_context_t;
-
-/* Functions used to enter/exit a Secure Partition synchronously */
-uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt);
-__dead2 void spm_sp_synchronous_exit(uint64_t rc);
-
-/* Assembly helpers */
-uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx);
-void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret);
-
-/* Secure Partition setup */
-void spm_sp_setup(sp_context_t *sp_ctx);
-
-/* Secure Partition state management helpers */
-void sp_state_set(sp_context_t *sp_ptr, sp_state_t state);
-void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
-int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to);
-
-/* Functions to keep track of the number of active requests per SP */
-void spm_sp_request_increase(sp_context_t *sp_ctx);
-void spm_sp_request_decrease(sp_context_t *sp_ctx);
-int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx);
-
-/* Functions related to the shim layer translation tables */
-void spm_exceptions_xlat_init_context(void);
-uint64_t *spm_exceptions_xlat_get_base_table(void);
-
-/* Functions related to the translation tables management */
-void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx);
-void sp_map_memory_regions(sp_context_t *sp_ctx);
-
-/* Functions to handle Secure Partition contexts */
-void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx);
-sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id);
-sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4]);
-
-/* Functions to manipulate response and requests buffers */
-int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token,
- u_register_t x1, u_register_t x2, u_register_t x3);
-int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token,
- u_register_t *x1, u_register_t *x2, u_register_t *x3);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* SPM_PRIVATE_H */
diff --git a/services/std_svc/spm/spm_setup.c b/services/std_svc/spm/spm_setup.c
deleted file mode 100644
index 2ed44d134b..0000000000
--- a/services/std_svc/spm/spm_setup.c
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <arch.h>
-#include <arch_helpers.h>
-#include <context.h>
-#include <common/debug.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/common_def.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-#include <sprt_host.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/* Setup context of the Secure Partition */
-void spm_sp_setup(sp_context_t *sp_ctx)
-{
- cpu_context_t *ctx = &(sp_ctx->cpu_ctx);
-
- /*
- * Initialize CPU context
- * ----------------------
- */
-
- entry_point_info_t ep_info = {0};
-
- SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
-
- /* Setup entrypoint and SPSR */
- ep_info.pc = sp_ctx->rd.attribute.entrypoint;
- ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS);
-
- /*
- * X0: Unused (MBZ).
- * X1: Unused (MBZ).
- * X2: cookie value (Implementation Defined)
- * X3: cookie value (Implementation Defined)
- * X4 to X7 = 0
- */
- ep_info.args.arg0 = 0;
- ep_info.args.arg1 = 0;
- ep_info.args.arg2 = PLAT_SPM_COOKIE_0;
- ep_info.args.arg3 = PLAT_SPM_COOKIE_1;
-
- cm_setup_context(ctx, &ep_info);
-
- /*
- * Setup translation tables
- * ------------------------
- */
-
- /* Assign translation tables context. */
- spm_sp_xlat_context_alloc(sp_ctx);
-
- sp_map_memory_regions(sp_ctx);
-
- /*
- * MMU-related registers
- * ---------------------
- */
- xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle;
-
- uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
-
- 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]);
-
- /* Enable translations using TTBR1_EL1 */
- int t1sz = 64 - __builtin_ctzll(SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE);
- mmu_cfg_params[MMU_CFG_TCR] &= ~TCR_EPD1_BIT;
- mmu_cfg_params[MMU_CFG_TCR] |=
- ((uint64_t)t1sz << TCR_T1SZ_SHIFT) |
- TCR_SH1_INNER_SHAREABLE |
- TCR_RGN1_OUTER_WBA | TCR_RGN1_INNER_WBA |
- TCR_TG1_4K;
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1,
- mmu_cfg_params[MMU_CFG_TCR]);
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1,
- mmu_cfg_params[MMU_CFG_TTBR0]);
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR1_EL1,
- (uint64_t)spm_exceptions_xlat_get_base_table());
-
- /* Setup SCTLR_EL1 */
- u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1);
-
- sctlr_el1 |=
- /*SCTLR_EL1_RES1 |*/
- /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */
- SCTLR_UCI_BIT |
- /* RW regions at xlat regime EL1&0 are forced to be XN. */
- SCTLR_WXN_BIT |
- /* Don't trap to EL1 execution of WFI or WFE at EL0. */
- SCTLR_NTWI_BIT | SCTLR_NTWE_BIT |
- /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */
- SCTLR_UCT_BIT |
- /* Don't trap to EL1 execution of DZ ZVA at EL0. */
- SCTLR_DZE_BIT |
- /* Enable SP Alignment check for EL0 */
- SCTLR_SA0_BIT |
- /* Allow cacheable data and instr. accesses to normal memory. */
- SCTLR_C_BIT | SCTLR_I_BIT |
- /* Alignment fault checking enabled when at EL1 and EL0. */
- SCTLR_A_BIT |
- /* Enable MMU. */
- SCTLR_M_BIT
- ;
-
- sctlr_el1 &= ~(
- /* Explicit data accesses at EL0 are little-endian. */
- SCTLR_E0E_BIT |
- /* Accesses to DAIF from EL0 are trapped to EL1. */
- SCTLR_UMA_BIT
- );
-
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1);
-
- /*
- * Setup other system registers
- * ----------------------------
- */
-
- /*
- * Shim exception vector base address. It is mapped at the start of the
- * address space accessed by TTBR1_EL1, which means that the base
- * address of the exception vectors depends on the size of the address
- * space specified in TCR_EL1.T1SZ.
- */
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1,
- UINT64_MAX - (SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE - 1ULL));
-
- /*
- * FPEN: Allow the Secure Partition to access FP/SIMD registers.
- * Note that SPM will not do any saving/restoring of these registers on
- * behalf of the SP. This falls under the SP's responsibility.
- * TTA: Enable access to trace registers.
- * ZEN (v8.2): Trap SVE instructions and access to SVE registers.
- */
- write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1,
- CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE));
-
- /*
- * Prepare shared buffers
- * ----------------------
- */
-
- /* Initialize SPRT queues */
- sprt_initialize_queues((void *)sp_ctx->spm_sp_buffer_base,
- sp_ctx->spm_sp_buffer_size);
-}
diff --git a/services/std_svc/spm/spm_shim_private.h b/services/std_svc/spm/spm_shim_private.h
deleted file mode 100644
index fc510b1110..0000000000
--- a/services/std_svc/spm/spm_shim_private.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SPM_SHIM_PRIVATE_H
-#define SPM_SHIM_PRIVATE_H
-
-#include <stdint.h>
-
-#include <lib/utils_def.h>
-
-/* Assembly source */
-IMPORT_SYM(uintptr_t, spm_shim_exceptions_ptr, SPM_SHIM_EXCEPTIONS_PTR);
-
-/* Linker symbols */
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START);
-IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__, SPM_SHIM_EXCEPTIONS_END);
-
-/* Definitions */
-
-#define SPM_SHIM_EXCEPTIONS_SIZE \
- (SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
-
-/*
- * Use the smallest virtual address space size allowed in ARMv8.0 for
- * compatibility.
- */
-#define SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 25)
-#define SPM_SHIM_MMAP_REGIONS 1
-#define SPM_SHIM_XLAT_TABLES 1
-
-#endif /* SPM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm/spm_xlat.c b/services/std_svc/spm/spm_xlat.c
deleted file mode 100644
index 5d5bc519f3..0000000000
--- a/services/std_svc/spm/spm_xlat.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <arch_features.h>
-#include <arch_helpers.h>
-#include <assert.h>
-#include <errno.h>
-#include <string.h>
-
-#include <platform_def.h>
-
-#include <lib/object_pool.h>
-#include <lib/utils.h>
-#include <lib/utils_def.h>
-#include <lib/xlat_tables/xlat_tables_v2.h>
-#include <plat/common/platform.h>
-#include <services/sp_res_desc.h>
-
-#include "spm_private.h"
-#include "spm_shim_private.h"
-
-/*******************************************************************************
- * Instantiation of translation table context
- ******************************************************************************/
-
-/* Place translation tables by default along with the ones used by BL31. */
-#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
-#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "xlat_table"
-#endif
-
-/*
- * Allocate elements of the translation contexts for the Secure Partitions.
- */
-
-/* Allocate an array of mmap_region per partition. */
-static struct mmap_region sp_mmap_regions[PLAT_SP_IMAGE_MMAP_REGIONS + 1]
- [PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_mmap_regions_pool, sp_mmap_regions,
- sizeof(mmap_region_t) * (PLAT_SP_IMAGE_MMAP_REGIONS + 1),
- PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate individual translation tables. */
-static uint64_t sp_xlat_tables[XLAT_TABLE_ENTRIES]
- [(PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS]
- __aligned(XLAT_TABLE_SIZE) __section(PLAT_SP_IMAGE_XLAT_SECTION_NAME);
-static OBJECT_POOL(sp_xlat_tables_pool, sp_xlat_tables,
- XLAT_TABLE_ENTRIES * sizeof(uint64_t),
- (PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate arrays. */
-static int sp_xlat_mapped_regions[PLAT_SP_IMAGE_MAX_XLAT_TABLES]
- [PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_xlat_mapped_regions_pool, sp_xlat_mapped_regions,
- sizeof(int) * PLAT_SP_IMAGE_MAX_XLAT_TABLES, PLAT_SPM_MAX_PARTITIONS);
-
-/* Allocate individual contexts. */
-static xlat_ctx_t sp_xlat_ctx[PLAT_SPM_MAX_PARTITIONS];
-static OBJECT_POOL(sp_xlat_ctx_pool, sp_xlat_ctx, sizeof(xlat_ctx_t),
- PLAT_SPM_MAX_PARTITIONS);
-
-/* Get handle of Secure Partition translation context */
-void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx)
-{
- /* Allocate xlat context elements */
-
- xlat_ctx_t *ctx = pool_alloc(&sp_xlat_ctx_pool);
-
- struct mmap_region *mmap = pool_alloc(&sp_mmap_regions_pool);
-
- uint64_t *base_table = pool_alloc(&sp_xlat_tables_pool);
- uint64_t **tables = pool_alloc_n(&sp_xlat_tables_pool,
- PLAT_SP_IMAGE_MAX_XLAT_TABLES);
-
- int *mapped_regions = pool_alloc(&sp_xlat_mapped_regions_pool);
-
- /* Calculate the size of the virtual address space needed */
-
- uintptr_t va_size = 0U;
- struct sp_rd_sect_mem_region *rdmem;
-
- for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) {
- uintptr_t end_va = (uintptr_t)rdmem->base +
- (uintptr_t)rdmem->size;
-
- if (end_va > va_size)
- va_size = end_va;
- }
-
- if (va_size == 0U) {
- ERROR("No regions in resource description.\n");
- panic();
- }
-
- /*
- * Get the power of two that is greater or equal to the top VA. The
- * values of base and size in the resource description are 32-bit wide
- * so the values will never overflow when using a uintptr_t.
- */
- if (!IS_POWER_OF_TWO(va_size)) {
- va_size = 1ULL <<
- ((sizeof(va_size) * 8) - __builtin_clzll(va_size));
- }
-
- if (va_size > PLAT_VIRT_ADDR_SPACE_SIZE) {
- ERROR("Resource description requested too much virtual memory.\n");
- panic();
- }
-
- uintptr_t min_va_size;
-
- /* The following sizes are only valid for 4KB pages */
- assert(PAGE_SIZE == (4U * 1024U));
-
- if (is_armv8_4_ttst_present()) {
- VERBOSE("Using ARMv8.4-TTST\n");
- min_va_size = 1ULL << (64 - TCR_TxSZ_MAX_TTST);
- } else {
- min_va_size = 1ULL << (64 - TCR_TxSZ_MAX);
- }
-
- if (va_size < min_va_size) {
- va_size = min_va_size;
- }
-
- /* Initialize xlat context */
-
- xlat_setup_dynamic_ctx(ctx, PLAT_PHY_ADDR_SPACE_SIZE - 1ULL,
- va_size - 1ULL, mmap,
- PLAT_SP_IMAGE_MMAP_REGIONS, tables,
- PLAT_SP_IMAGE_MAX_XLAT_TABLES, base_table,
- EL1_EL0_REGIME, mapped_regions);
-
- sp_ctx->xlat_ctx_handle = ctx;
-};
-
-/*******************************************************************************
- * Translation table context used for S-EL1 exception vectors
- ******************************************************************************/
-
-REGISTER_XLAT_CONTEXT2(spm_sel1, SPM_SHIM_MMAP_REGIONS, SPM_SHIM_XLAT_TABLES,
- SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE,
- EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME);
-
-void spm_exceptions_xlat_init_context(void)
-{
- /* This region contains the exception vectors used at S-EL1. */
- mmap_region_t sel1_exception_vectors =
- MAP_REGION(SPM_SHIM_EXCEPTIONS_PTR,
- 0x0UL,
- SPM_SHIM_EXCEPTIONS_SIZE,
- MT_CODE | MT_SECURE | MT_PRIVILEGED);
-
- mmap_add_region_ctx(&spm_sel1_xlat_ctx,
- &sel1_exception_vectors);
-
- init_xlat_tables_ctx(&spm_sel1_xlat_ctx);
-}
-
-uint64_t *spm_exceptions_xlat_get_base_table(void)
-{
- return spm_sel1_xlat_ctx.base_table;
-}
-
-/*******************************************************************************
- * Functions to allocate memory for regions.
- ******************************************************************************/
-
-/*
- * The region with base PLAT_SPM_HEAP_BASE and size PLAT_SPM_HEAP_SIZE is
- * reserved for SPM to use as heap to allocate memory regions of Secure
- * Partitions. This is only done at boot.
- */
-static OBJECT_POOL(spm_heap_mem, (void *)PLAT_SPM_HEAP_BASE, 1U,
- PLAT_SPM_HEAP_SIZE);
-
-static uintptr_t spm_alloc_heap(size_t size)
-{
- return (uintptr_t)pool_alloc_n(&spm_heap_mem, size);
-}
-
-/*******************************************************************************
- * Functions to map memory regions described in the resource description.
- ******************************************************************************/
-static unsigned int rdmem_attr_to_mmap_attr(uint32_t attr)
-{
- unsigned int index = attr & RD_MEM_MASK;
-
- const unsigned int mmap_attr_arr[8] = {
- MT_DEVICE | MT_RW | MT_SECURE, /* RD_MEM_DEVICE */
- MT_CODE | MT_SECURE, /* RD_MEM_NORMAL_CODE */
- MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_DATA */
- MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_BSS */
- MT_RO_DATA | MT_SECURE, /* RD_MEM_NORMAL_RODATA */
- MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_SPM_SP_SHARED_MEM */
- MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_CLIENT_SHARED_MEM */
- MT_MEMORY | MT_RW | MT_SECURE /* RD_MEM_NORMAL_MISCELLANEOUS */
- };
-
- if (index >= ARRAY_SIZE(mmap_attr_arr)) {
- ERROR("Unsupported RD memory attributes 0x%x\n", attr);
- panic();
- }
-
- return mmap_attr_arr[index];
-}
-
-/*
- * The data provided in the resource description structure is not directly
- * compatible with a mmap_region structure. This function handles the conversion
- * and maps it.
- */
-static void map_rdmem(sp_context_t *sp_ctx, struct sp_rd_sect_mem_region *rdmem)
-{
- int rc;
- mmap_region_t mmap;
-
- /* Location of the SP image */
- uintptr_t sp_size = sp_ctx->image_size;
- uintptr_t sp_base_va = sp_ctx->rd.attribute.load_address;
- unsigned long long sp_base_pa = sp_ctx->image_base;
-
- /* Location of the memory region to map */
- size_t rd_size = rdmem->size;
- uintptr_t rd_base_va = rdmem->base;
- unsigned long long rd_base_pa;
-
- unsigned int memtype = rdmem->attr & RD_MEM_MASK;
-
- if (rd_size == 0U) {
- VERBOSE("Memory region '%s' is empty. Ignored.\n", rdmem->name);
- return;
- }
-
- VERBOSE("Adding memory region '%s'\n", rdmem->name);
-
- mmap.granularity = REGION_DEFAULT_GRANULARITY;
-
- /* Check if the RD region is inside of the SP image or not */
- int is_outside = (rd_base_va + rd_size <= sp_base_va) ||
- (sp_base_va + sp_size <= rd_base_va);
-
- /* Set to 1 if it is needed to zero this region */
- int zero_region = 0;
-
- switch (memtype) {
- case RD_MEM_DEVICE:
- /* Device regions are mapped 1:1 */
- rd_base_pa = rd_base_va;
- break;
-
- case RD_MEM_NORMAL_CODE:
- case RD_MEM_NORMAL_RODATA:
- {
- if (is_outside == 1) {
- ERROR("Code and rodata sections must be fully contained in the image.");
- panic();
- }
-
- /* Get offset into the image */
- rd_base_pa = sp_base_pa + rd_base_va - sp_base_va;
- break;
- }
- case RD_MEM_NORMAL_DATA:
- {
- if (is_outside == 1) {
- ERROR("Data sections must be fully contained in the image.");
- panic();
- }
-
- rd_base_pa = spm_alloc_heap(rd_size);
-
- /* Get offset into the image */
- void *img_pa = (void *)(sp_base_pa + rd_base_va - sp_base_va);
-
- VERBOSE(" Copying data from %p to 0x%llx\n", img_pa, rd_base_pa);
-
- /* Map destination */
- rc = mmap_add_dynamic_region(rd_base_pa, rd_base_pa,
- rd_size, MT_MEMORY | MT_RW | MT_SECURE);
- if (rc != 0) {
- ERROR("Unable to map data region at EL3: %d\n", rc);
- panic();
- }
-
- /* Copy original data to destination */
- memcpy((void *)rd_base_pa, img_pa, rd_size);
-
- /* Unmap destination region */
- rc = mmap_remove_dynamic_region(rd_base_pa, rd_size);
- if (rc != 0) {
- ERROR("Unable to remove data region at EL3: %d\n", rc);
- panic();
- }
-
- break;
- }
- case RD_MEM_NORMAL_MISCELLANEOUS:
- /* Allow SPM to change the attributes of the region. */
- mmap.granularity = PAGE_SIZE;
- rd_base_pa = spm_alloc_heap(rd_size);
- zero_region = 1;
- break;
-
- case RD_MEM_NORMAL_SPM_SP_SHARED_MEM:
- if ((sp_ctx->spm_sp_buffer_base != 0) ||
- (sp_ctx->spm_sp_buffer_size != 0)) {
- ERROR("A partition must have only one SPM<->SP buffer.\n");
- panic();
- }
- rd_base_pa = spm_alloc_heap(rd_size);
- zero_region = 1;
- /* Save location of this buffer, it is needed by SPM */
- sp_ctx->spm_sp_buffer_base = rd_base_pa;
- sp_ctx->spm_sp_buffer_size = rd_size;
- break;
-
- case RD_MEM_NORMAL_CLIENT_SHARED_MEM:
- /* Fallthrough */
- case RD_MEM_NORMAL_BSS:
- rd_base_pa = spm_alloc_heap(rd_size);
- zero_region = 1;
- break;
-
- default:
- panic();
- }
-
- mmap.base_pa = rd_base_pa;
- mmap.base_va = rd_base_va;
- mmap.size = rd_size;
-
- /* Only S-EL0 mappings supported for now */
- mmap.attr = rdmem_attr_to_mmap_attr(rdmem->attr) | MT_USER;
-
- VERBOSE(" VA: 0x%lx PA: 0x%llx (0x%lx, attr: 0x%x)\n",
- mmap.base_va, mmap.base_pa, mmap.size, mmap.attr);
-
- /* Map region in the context of the Secure Partition */
- mmap_add_region_ctx(sp_ctx->xlat_ctx_handle, &mmap);
-
- if (zero_region == 1) {
- VERBOSE(" Zeroing region...\n");
-
- rc = mmap_add_dynamic_region(mmap.base_pa, mmap.base_pa,
- mmap.size, MT_MEMORY | MT_RW | MT_SECURE);
- if (rc != 0) {
- ERROR("Unable to map memory at EL3 to zero: %d\n",
- rc);
- panic();
- }
-
- zeromem((void *)mmap.base_pa, mmap.size);
-
- /*
- * Unmap destination region unless it is the SPM<->SP buffer,
- * which must be used by SPM.
- */
- if (memtype != RD_MEM_NORMAL_SPM_SP_SHARED_MEM) {
- rc = mmap_remove_dynamic_region(rd_base_pa, rd_size);
- if (rc != 0) {
- ERROR("Unable to remove region at EL3: %d\n", rc);
- panic();
- }
- }
- }
-}
-
-void sp_map_memory_regions(sp_context_t *sp_ctx)
-{
- struct sp_rd_sect_mem_region *rdmem;
-
- for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) {
- map_rdmem(sp_ctx, rdmem);
- }
-
- init_xlat_tables_ctx(sp_ctx->xlat_ctx_handle);
-}
diff --git a/services/std_svc/spm/sprt.c b/services/std_svc/spm/sprt.c
deleted file mode 100644
index 20ad2afb2c..0000000000
--- a/services/std_svc/spm/sprt.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-
-#include <arch_helpers.h>
-#include <common/debug.h>
-#include <common/runtime_svc.h>
-#include <lib/el3_runtime/context_mgmt.h>
-#include <lib/smccc.h>
-#include <lib/utils.h>
-#include <plat/common/platform.h>
-#include <services/sprt_svc.h>
-#include <smccc_helpers.h>
-
-#include "spm_private.h"
-
-/*******************************************************************************
- * Functions to manipulate memory regions
- ******************************************************************************/
-
-/*
- * Attributes are encoded using a different format in the SMC interface than in
- * the Trusted Firmware, where the mmap_attr_t enum type is used. This function
- * 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
- * xlat_change_mem_attributes_ctx().
- */
-static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
-{
- unsigned int perm = attributes & SPRT_MEMORY_PERM_ATTR_MASK;
-
- if (perm == SPRT_MEMORY_PERM_ATTR_RW) {
- return MT_RW | MT_EXECUTE_NEVER | MT_USER;
- } else if (perm == SPRT_MEMORY_PERM_ATTR_RO) {
- return MT_RO | MT_EXECUTE_NEVER | MT_USER;
- } else if (perm == SPRT_MEMORY_PERM_ATTR_RO_EXEC) {
- return MT_RO | MT_USER;
- } else {
- return UINT_MAX;
- }
-}
-
-/*
- * This function converts attributes from the Trusted Firmware format into the
- * SMC interface format.
- */
-static unsigned int mmap_attr_to_smc_attr(unsigned int attr)
-{
- unsigned int perm;
-
- /* No access from EL0. */
- if ((attr & MT_USER) == 0U)
- return UINT_MAX;
-
- if ((attr & MT_RW) != 0) {
- assert(MT_TYPE(attr) != MT_DEVICE);
- perm = SPRT_MEMORY_PERM_ATTR_RW;
- } else {
- if ((attr & MT_EXECUTE_NEVER) != 0U) {
- perm = SPRT_MEMORY_PERM_ATTR_RO;
- } else {
- perm = SPRT_MEMORY_PERM_ATTR_RO_EXEC;
- }
- }
-
- return perm << SPRT_MEMORY_PERM_ATTR_SHIFT;
-}
-
-static int32_t sprt_memory_perm_attr_get(sp_context_t *sp_ctx, uintptr_t base_va)
-{
- uint32_t attributes;
-
- spin_lock(&(sp_ctx->xlat_ctx_lock));
-
- int ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
- base_va, &attributes);
-
- spin_unlock(&(sp_ctx->xlat_ctx_lock));
-
- /* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */
- assert((ret == 0) || (ret == -EINVAL));
-
- if (ret != 0)
- return SPRT_INVALID_PARAMETER;
-
- unsigned int perm = mmap_attr_to_smc_attr(attributes);
-
- if (perm == UINT_MAX)
- return SPRT_INVALID_PARAMETER;
-
- return SPRT_SUCCESS | perm;
-}
-
-static int32_t sprt_memory_perm_attr_set(sp_context_t *sp_ctx,
- u_register_t page_address, u_register_t pages_count,
- u_register_t smc_attributes)
-{
- int ret;
- uintptr_t base_va = (uintptr_t) page_address;
- size_t size = pages_count * PAGE_SIZE;
-
- VERBOSE(" Start address : 0x%lx\n", base_va);
- VERBOSE(" Number of pages: %i (%zi bytes)\n", (int) pages_count, size);
- VERBOSE(" Attributes : 0x%lx\n", smc_attributes);
-
- uint32_t mmap_attr = smc_attr_to_mmap_attr(smc_attributes);
-
- if (mmap_attr == UINT_MAX) {
- WARN("%s: Invalid memory attributes: 0x%lx\n", __func__,
- smc_attributes);
- return SPRT_INVALID_PARAMETER;
- }
-
- /*
- * Perform some checks before actually trying to change the memory
- * attributes.
- */
-
- spin_lock(&(sp_ctx->xlat_ctx_lock));
-
- uint32_t attributes;
-
- ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
- base_va, &attributes);
-
- if (ret != 0) {
- spin_unlock(&(sp_ctx->xlat_ctx_lock));
- return SPRT_INVALID_PARAMETER;
- }
-
- if ((attributes & MT_USER) == 0U) {
- /* Prohibit changing attributes of S-EL1 regions */
- spin_unlock(&(sp_ctx->xlat_ctx_lock));
- return SPRT_INVALID_PARAMETER;
- }
-
- ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle,
- base_va, size, mmap_attr);
-
- spin_unlock(&(sp_ctx->xlat_ctx_lock));
-
- /* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
- assert((ret == 0) || (ret == -EINVAL));
-
- return (ret == 0) ? SPRT_SUCCESS : SPRT_INVALID_PARAMETER;
-}
-
-/*******************************************************************************
- * This function handles all SMCs in the range reserved for SPRT.
- ******************************************************************************/
-static uintptr_t sprt_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)
-{
- /* SPRT only supported from the Secure world */
- if (is_caller_non_secure(flags) == SMC_FROM_NON_SECURE) {
- SMC_RET1(handle, SMC_UNK);
- }
-
- assert(handle == cm_get_context(SECURE));
-
- /*
- * Only S-EL0 partitions are supported for now. Make the next ERET into
- * the partition jump directly to S-EL0 instead of S-EL1.
- */
- cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1());
-
- switch (smc_fid) {
- case SPRT_VERSION:
- SMC_RET1(handle, SPRT_VERSION_COMPILED);
-
- case SPRT_PUT_RESPONSE_AARCH64:
- spm_sp_synchronous_exit(SPRT_PUT_RESPONSE_AARCH64);
-
- case SPRT_YIELD_AARCH64:
- spm_sp_synchronous_exit(SPRT_YIELD_AARCH64);
-
- case SPRT_MEMORY_PERM_ATTR_GET_AARCH64:
- {
- /* Get context of the SP in use by this CPU. */
- unsigned int linear_id = plat_my_core_pos();
- sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id);
-
- SMC_RET1(handle, sprt_memory_perm_attr_get(sp_ctx, x1));
- }
-
- case SPRT_MEMORY_PERM_ATTR_SET_AARCH64:
- {
- /* Get context of the SP in use by this CPU. */
- unsigned int linear_id = plat_my_core_pos();
- sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id);
-
- SMC_RET1(handle, sprt_memory_perm_attr_set(sp_ctx, x1, x2, x3));
- }
-
- default:
- break;
- }
-
- WARN("SPRT: Unsupported call 0x%08x\n", smc_fid);
- SMC_RET1(handle, SPRT_NOT_SUPPORTED);
-}
-
-DECLARE_RT_SVC(
- sprt_handler,
- OEN_SPRT_START,
- OEN_SPRT_END,
- SMC_TYPE_FAST,
- NULL,
- sprt_smc_handler
-);
diff --git a/services/std_svc/spm_mm/aarch64/spm_helpers.S b/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
index aa35811f14..2c3aaf7aed 100644
--- a/services/std_svc/spm_mm/aarch64/spm_helpers.S
+++ b/services/std_svc/spm_mm/aarch64/spm_mm_helpers.S
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
-#include "../spm_private.h"
+#include "../spm_mm_private.h"
.global spm_secure_partition_enter
.global spm_secure_partition_exit
diff --git a/services/std_svc/spm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
index dab6150129..dab6150129 100644
--- a/services/std_svc/spm/aarch64/spm_shim_exceptions.S
+++ b/services/std_svc/spm_mm/aarch64/spm_mm_shim_exceptions.S
diff --git a/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
deleted file mode 100644
index dab6150129..0000000000
--- a/services/std_svc/spm_mm/aarch64/spm_shim_exceptions.S
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <arch.h>
-#include <asm_macros.S>
-#include <common/bl_common.h>
-#include <context.h>
-
-/* -----------------------------------------------------------------------------
- * Very simple stackless exception handlers used by the spm shim layer.
- * -----------------------------------------------------------------------------
- */
- .globl spm_shim_exceptions_ptr
-
-vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions
-
- /* -----------------------------------------------------
- * Current EL with SP0 : 0x0 - 0x200
- * -----------------------------------------------------
- */
-vector_entry SynchronousExceptionSP0, .spm_shim_exceptions
- b .
-end_vector_entry SynchronousExceptionSP0
-
-vector_entry IrqSP0, .spm_shim_exceptions
- b .
-end_vector_entry IrqSP0
-
-vector_entry FiqSP0, .spm_shim_exceptions
- b .
-end_vector_entry FiqSP0
-
-vector_entry SErrorSP0, .spm_shim_exceptions
- b .
-end_vector_entry SErrorSP0
-
- /* -----------------------------------------------------
- * Current EL with SPx: 0x200 - 0x400
- * -----------------------------------------------------
- */
-vector_entry SynchronousExceptionSPx, .spm_shim_exceptions
- b .
-end_vector_entry SynchronousExceptionSPx
-
-vector_entry IrqSPx, .spm_shim_exceptions
- b .
-end_vector_entry IrqSPx
-
-vector_entry FiqSPx, .spm_shim_exceptions
- b .
-end_vector_entry FiqSPx
-
-vector_entry SErrorSPx, .spm_shim_exceptions
- b .
-end_vector_entry SErrorSPx
-
- /* -----------------------------------------------------
- * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
- * are handled since secure_partition does not implement
- * a lower EL
- * -----------------------------------------------------
- */
-vector_entry SynchronousExceptionA64, .spm_shim_exceptions
- msr tpidr_el1, x30
- mrs x30, esr_el1
- ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
-
- cmp x30, #EC_AARCH64_SVC
- b.eq do_smc
-
- cmp x30, #EC_AARCH32_SVC
- b.eq do_smc
-
- cmp x30, #EC_AARCH64_SYS
- b.eq handle_sys_trap
-
- /* Fail in all the other cases */
- b panic
-
- /* ---------------------------------------------
- * Tell SPM that we are done initialising
- * ---------------------------------------------
- */
-do_smc:
- mrs x30, tpidr_el1
- smc #0
- eret
-
- /* AArch64 system instructions trap are handled as a panic for now */
-handle_sys_trap:
-panic:
- b panic
-end_vector_entry SynchronousExceptionA64
-
-vector_entry IrqA64, .spm_shim_exceptions
- b .
-end_vector_entry IrqA64
-
-vector_entry FiqA64, .spm_shim_exceptions
- b .
-end_vector_entry FiqA64
-
-vector_entry SErrorA64, .spm_shim_exceptions
- b .
-end_vector_entry SErrorA64
-
- /* -----------------------------------------------------
- * Lower EL using AArch32 : 0x600 - 0x800
- * -----------------------------------------------------
- */
-vector_entry SynchronousExceptionA32, .spm_shim_exceptions
- b .
-end_vector_entry SynchronousExceptionA32
-
-vector_entry IrqA32, .spm_shim_exceptions
- b .
-end_vector_entry IrqA32
-
-vector_entry FiqA32, .spm_shim_exceptions
- b .
-end_vector_entry FiqA32
-
-vector_entry SErrorA32, .spm_shim_exceptions
- b .
-end_vector_entry SErrorA32
diff --git a/services/std_svc/spm_mm/spm.mk b/services/std_svc/spm_mm/spm_mm.mk
index 3aa10ee556..656488b8e1 100644
--- a/services/std_svc/spm_mm/spm.mk
+++ b/services/std_svc/spm_mm/spm_mm.mk
@@ -1,22 +1,22 @@
#
-# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifneq (${SPD},none)
- $(error "Error: SPD and SPM are incompatible build options.")
+ $(error "Error: SPD and SPM_MM are incompatible build options.")
endif
ifneq (${ARCH},aarch64)
- $(error "Error: SPM is only supported on aarch64.")
+ $(error "Error: SPM_MM is only supported on aarch64.")
endif
SPM_SOURCES := $(addprefix services/std_svc/spm_mm/, \
- ${ARCH}/spm_helpers.S \
- ${ARCH}/spm_shim_exceptions.S \
- spm_main.c \
- spm_setup.c \
- spm_xlat.c)
+ ${ARCH}/spm_mm_helpers.S \
+ ${ARCH}/spm_mm_shim_exceptions.S \
+ spm_mm_main.c \
+ spm_mm_setup.c \
+ spm_mm_xlat.c)
# Let the top-level Makefile know that we intend to include a BL32 image
diff --git a/services/std_svc/spm_mm/spm_main.c b/services/std_svc/spm_mm/spm_mm_main.c
index 706b69d9f8..14c0038ba8 100644
--- a/services/std_svc/spm_mm/spm_main.c
+++ b/services/std_svc/spm_mm/spm_mm_main.c
@@ -18,12 +18,11 @@
#include <lib/utils.h>
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <plat/common/platform.h>
-#include <services/mm_svc.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_partition.h>
+#include <services/spm_mm_svc.h>
#include <smccc_helpers.h>
-#include "spm_private.h"
+#include "spm_mm_private.h"
/*******************************************************************************
* Secure Partition context information.
@@ -157,7 +156,7 @@ static int32_t spm_init(void)
/*******************************************************************************
* Initialize contexts of all Secure Partitions.
******************************************************************************/
-int32_t spm_setup(void)
+int32_t spm_mm_setup(void)
{
sp_context_t *ctx;
@@ -185,7 +184,7 @@ int32_t spm_setup(void)
/*******************************************************************************
* Function to perform a call to a Secure Partition.
******************************************************************************/
-uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
+uint64_t spm_mm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3)
{
uint64_t rc;
sp_context_t *sp_ptr = &sp_ctx;
@@ -223,12 +222,12 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
/* Cookie. Reserved for future use. It must be zero. */
if (mm_cookie != 0U) {
ERROR("MM_COMMUNICATE: cookie is not zero\n");
- SMC_RET1(handle, SPM_INVALID_PARAMETER);
+ SMC_RET1(handle, SPM_MM_INVALID_PARAMETER);
}
if (comm_buffer_address == 0U) {
ERROR("MM_COMMUNICATE: comm_buffer_address is zero\n");
- SMC_RET1(handle, SPM_INVALID_PARAMETER);
+ SMC_RET1(handle, SPM_MM_INVALID_PARAMETER);
}
if (comm_size_address != 0U) {
@@ -251,8 +250,8 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
/* Save the Normal world context */
cm_el1_sysregs_context_save(NON_SECURE);
- rc = spm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
- plat_my_core_pos());
+ rc = spm_mm_sp_call(smc_fid, comm_buffer_address, comm_size_address,
+ plat_my_core_pos());
/* Restore non-secure state */
cm_el1_sysregs_context_restore(NON_SECURE);
@@ -270,7 +269,7 @@ static uint64_t mm_communicate(uint32_t smc_fid, uint64_t mm_cookie,
/*******************************************************************************
* Secure Partition Manager SMC handler.
******************************************************************************/
-uint64_t spm_smc_handler(uint32_t smc_fid,
+uint64_t spm_mm_smc_handler(uint32_t smc_fid,
uint64_t x1,
uint64_t x2,
uint64_t x3,
@@ -295,29 +294,29 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
switch (smc_fid) {
- case SPM_VERSION_AARCH32:
- SMC_RET1(handle, SPM_VERSION_COMPILED);
+ case SPM_MM_VERSION_AARCH32:
+ SMC_RET1(handle, SPM_MM_VERSION_COMPILED);
- case SP_EVENT_COMPLETE_AARCH64:
+ case MM_SP_EVENT_COMPLETE_AARCH64:
spm_sp_synchronous_exit(x1);
- case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
- INFO("Received SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
+ case MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+ INFO("Received MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 SMC\n");
if (sp_ctx.state != SP_STATE_RESET) {
- WARN("SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
- SMC_RET1(handle, SPM_NOT_SUPPORTED);
+ WARN("MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 is available at boot time only\n");
+ SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
}
SMC_RET1(handle,
spm_memory_attributes_get_smc_handler(
&sp_ctx, x1));
- case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
- INFO("Received SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
+ case MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+ INFO("Received MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 SMC\n");
if (sp_ctx.state != SP_STATE_RESET) {
- WARN("SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
- SMC_RET1(handle, SPM_NOT_SUPPORTED);
+ WARN("MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 is available at boot time only\n");
+ SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
}
SMC_RET1(handle,
spm_memory_attributes_set_smc_handler(
@@ -340,10 +339,10 @@ uint64_t spm_smc_handler(uint32_t smc_fid,
case MM_COMMUNICATE_AARCH64:
return mm_communicate(smc_fid, x1, x2, x3, handle);
- case SP_MEMORY_ATTRIBUTES_GET_AARCH64:
- case SP_MEMORY_ATTRIBUTES_SET_AARCH64:
+ case MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64:
+ case MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64:
/* SMC interfaces reserved for secure callers. */
- SMC_RET1(handle, SPM_NOT_SUPPORTED);
+ SMC_RET1(handle, SPM_MM_NOT_SUPPORTED);
default:
break;
diff --git a/services/std_svc/spm_mm/spm_private.h b/services/std_svc/spm_mm/spm_mm_private.h
index ba94a4d088..45b4789ad1 100644
--- a/services/std_svc/spm_mm/spm_private.h
+++ b/services/std_svc/spm_mm/spm_mm_private.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef SPM_PRIVATE_H
-#define SPM_PRIVATE_H
+#ifndef SPM_MM_PRIVATE_H
+#define SPM_MM_PRIVATE_H
#include <context.h>
@@ -68,4 +68,4 @@ int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
#endif /* __ASSEMBLER__ */
-#endif /* SPM_PRIVATE_H */
+#endif /* SPM_MM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_setup.c b/services/std_svc/spm_mm/spm_mm_setup.c
index aae6cd5e2b..ccb2f90582 100644
--- a/services/std_svc/spm_mm/spm_setup.c
+++ b/services/std_svc/spm_mm/spm_mm_setup.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,10 +16,10 @@
#include <platform_def.h>
#include <plat/common/common_def.h>
#include <plat/common/platform.h>
-#include <services/secure_partition.h>
+#include <services/spm_mm_partition.h>
-#include "spm_private.h"
-#include "spm_shim_private.h"
+#include "spm_mm_private.h"
+#include "spm_mm_shim_private.h"
/* Setup context of the Secure Partition */
void spm_sp_setup(sp_context_t *sp_ctx)
@@ -192,22 +192,22 @@ void spm_sp_setup(sp_context_t *sp_ctx)
void *shared_buf_ptr = (void *) PLAT_SPM_BUF_BASE;
/* Copy the boot information into the shared buffer with the SP. */
- assert((uintptr_t)shared_buf_ptr + sizeof(secure_partition_boot_info_t)
+ assert((uintptr_t)shared_buf_ptr + sizeof(spm_mm_boot_info_t)
<= (PLAT_SPM_BUF_BASE + PLAT_SPM_BUF_SIZE));
assert(PLAT_SPM_BUF_BASE <= (UINTPTR_MAX - PLAT_SPM_BUF_SIZE + 1));
- const secure_partition_boot_info_t *sp_boot_info =
+ const spm_mm_boot_info_t *sp_boot_info =
plat_get_secure_partition_boot_info(NULL);
assert(sp_boot_info != NULL);
memcpy((void *) shared_buf_ptr, (const void *) sp_boot_info,
- sizeof(secure_partition_boot_info_t));
+ sizeof(spm_mm_boot_info_t));
/* Pointer to the MP information from the platform port. */
- secure_partition_mp_info_t *sp_mp_info =
- ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+ spm_mm_mp_info_t *sp_mp_info =
+ ((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info;
assert(sp_mp_info != NULL);
@@ -215,15 +215,15 @@ void spm_sp_setup(sp_context_t *sp_ctx)
* Point the shared buffer MP information pointer to where the info will
* be populated, just after the boot info.
*/
- ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info =
- (secure_partition_mp_info_t *) ((uintptr_t)shared_buf_ptr
- + sizeof(secure_partition_boot_info_t));
+ ((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info =
+ (spm_mm_mp_info_t *) ((uintptr_t)shared_buf_ptr
+ + sizeof(spm_mm_boot_info_t));
/*
* Update the shared buffer pointer to where the MP information for the
* payload will be populated
*/
- shared_buf_ptr = ((secure_partition_boot_info_t *) shared_buf_ptr)->mp_info;
+ shared_buf_ptr = ((spm_mm_boot_info_t *) shared_buf_ptr)->mp_info;
/*
* Copy the cpu information into the shared buffer area after the boot
@@ -242,7 +242,7 @@ void spm_sp_setup(sp_context_t *sp_ctx)
* Calculate the linear indices of cores in boot information for the
* secure partition and flag the primary CPU
*/
- sp_mp_info = (secure_partition_mp_info_t *) shared_buf_ptr;
+ sp_mp_info = (spm_mm_mp_info_t *) shared_buf_ptr;
for (unsigned int index = 0; index < sp_boot_info->num_cpus; index++) {
u_register_t mpidr = sp_mp_info[index].mpidr;
diff --git a/services/std_svc/spm_mm/spm_shim_private.h b/services/std_svc/spm_mm/spm_mm_shim_private.h
index 7fe9692b45..0c8d894f19 100644
--- a/services/std_svc/spm_mm/spm_shim_private.h
+++ b/services/std_svc/spm_mm/spm_mm_shim_private.h
@@ -1,11 +1,11 @@
/*
- * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef SPM_SHIM_PRIVATE_H
-#define SPM_SHIM_PRIVATE_H
+#ifndef SPM_MM_SHIM_PRIVATE_H
+#define SPM_MM_SHIM_PRIVATE_H
#include <stdint.h>
@@ -23,4 +23,4 @@ IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__, SPM_SHIM_EXCEPTIONS_END);
#define SPM_SHIM_EXCEPTIONS_SIZE \
(SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START)
-#endif /* SPM_SHIM_PRIVATE_H */
+#endif /* SPM_MM_SHIM_PRIVATE_H */
diff --git a/services/std_svc/spm_mm/spm_xlat.c b/services/std_svc/spm_mm/spm_mm_xlat.c
index f54168e334..6c02f0743a 100644
--- a/services/std_svc/spm_mm/spm_xlat.c
+++ b/services/std_svc/spm_mm/spm_mm_xlat.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -11,11 +11,11 @@
#include <lib/xlat_tables/xlat_tables_v2.h>
#include <platform_def.h>
#include <plat/common/platform.h>
-#include <services/secure_partition.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_partition.h>
+#include <services/spm_mm_svc.h>
-#include "spm_private.h"
-#include "spm_shim_private.h"
+#include "spm_mm_private.h"
+#include "spm_mm_shim_private.h"
/* Place translation tables by default along with the ones used by BL31. */
#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME
@@ -50,21 +50,21 @@ static unsigned int smc_attr_to_mmap_attr(unsigned int attributes)
{
unsigned int tf_attr = 0U;
- unsigned int access = (attributes & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
- >> SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+ unsigned int access = (attributes & MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+ >> MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
- if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
+ if (access == MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW) {
tf_attr |= MT_RW | MT_USER;
- } else if (access == SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
+ } else if (access == MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO) {
tf_attr |= MT_RO | MT_USER;
} else {
/* Other values are reserved. */
- assert(access == SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
+ assert(access == MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS);
/* The only requirement is that there's no access from EL0 */
tf_attr |= MT_RO | MT_PRIVILEGED;
}
- if ((attributes & SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
+ if ((attributes & MM_SP_MEMORY_ATTRIBUTES_NON_EXEC) == 0) {
tf_attr |= MT_EXECUTE;
} else {
tf_attr |= MT_EXECUTE_NEVER;
@@ -85,21 +85,21 @@ static unsigned int smc_mmap_to_smc_attr(unsigned int attr)
if ((attr & MT_USER) == 0) {
/* No access from EL0. */
- data_access = SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
+ data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS;
} else {
if ((attr & MT_RW) != 0) {
assert(MT_TYPE(attr) != MT_DEVICE);
- data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RW;
+ data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_RW;
} else {
- data_access = SP_MEMORY_ATTRIBUTES_ACCESS_RO;
+ data_access = MM_SP_MEMORY_ATTRIBUTES_ACCESS_RO;
}
}
- smc_attr |= (data_access & SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
- << SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
+ smc_attr |= (data_access & MM_SP_MEMORY_ATTRIBUTES_ACCESS_MASK)
+ << MM_SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT;
if ((attr & MT_EXECUTE_NEVER) != 0U) {
- smc_attr |= SP_MEMORY_ATTRIBUTES_NON_EXEC;
+ smc_attr |= MM_SP_MEMORY_ATTRIBUTES_NON_EXEC;
}
return smc_attr;
@@ -123,7 +123,7 @@ int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx,
if (rc == 0) {
return (int32_t) smc_mmap_to_smc_attr(attributes);
} else {
- return SPM_INVALID_PARAMETER;
+ return SPM_MM_INVALID_PARAMETER;
}
}
@@ -151,5 +151,5 @@ int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx,
/* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */
assert((ret == 0) || (ret == -EINVAL));
- return (ret == 0) ? SPM_SUCCESS : SPM_INVALID_PARAMETER;
+ return (ret == 0) ? SPM_MM_SUCCESS : SPM_MM_INVALID_PARAMETER;
}
diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c
index 1d80fa3433..7787a2fa23 100644
--- a/services/std_svc/std_svc_setup.c
+++ b/services/std_svc/std_svc_setup.c
@@ -14,7 +14,7 @@
#include <lib/psci/psci.h>
#include <lib/runtime_instr.h>
#include <services/sdei.h>
-#include <services/spm_svc.h>
+#include <services/spm_mm_svc.h>
#include <services/std_svc.h>
#include <smccc_helpers.h>
#include <tools_share/uuid.h>
@@ -45,8 +45,8 @@ static int32_t std_svc_setup(void)
ret = 1;
}
-#if ENABLE_SPM
- if (spm_setup() != 0) {
+#if SPM_MM
+ if (spm_mm_setup() != 0) {
ret = 1;
}
#endif
@@ -103,14 +103,14 @@ static uintptr_t std_svc_smc_handler(uint32_t smc_fid,
SMC_RET1(handle, ret);
}
-#if ENABLE_SPM && SPM_MM
+#if SPM_MM
/*
* Dispatch SPM calls to SPM SMC handler and return its return
* value
*/
- if (is_spm_fid(smc_fid)) {
- return spm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
- handle, flags);
+ if (is_spm_mm_fid(smc_fid)) {
+ return spm_mm_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
}
#endif
diff --git a/tools/memory/print_memory_map.py b/tools/memory/print_memory_map.py
new file mode 100755
index 0000000000..35cccd38c3
--- /dev/null
+++ b/tools/memory/print_memory_map.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import re
+import os
+import sys
+import operator
+
+# List of folder/map to parse
+bl_images = ['bl1', 'bl2', 'bl31']
+
+# List of symbols to search for
+blx_symbols = ['__BL1_RAM_START__', '__BL1_RAM_END__',
+ '__BL2_END__',
+ '__BL31_END__',
+ '__TEXT_START__', '__TEXT_END__',
+ '__RODATA_START__', '__RODATA_END__',
+ '__DATA_START__', '__DATA_END__',
+ '__STACKS_START__', '__STACKS_END__',
+ '__BSS_END',
+ ]
+
+# Regex to extract address from map file
+address_pattern = re.compile(r"\b0x\w*")
+
+# List of found element: [address, symbol, file]
+address_list = []
+
+# Get the directory from command line or use a default one
+if len(sys.argv) >= 2:
+ build_dir = sys.argv[1]
+else:
+ build_dir = 'build/fvp/debug'
+
+# Extract all the required symbols from the map files
+for image in bl_images:
+ file_path = os.path.join(build_dir, image, '{}.map'.format(image))
+ if os.path.isfile(file_path):
+ with open (file_path, 'rt') as mapfile:
+ for line in mapfile:
+ for symbol in blx_symbols:
+ if line.find(symbol) > 0 and line.find("ASSERT") < 0:
+ # Extract address from line
+ match = address_pattern.search(line)
+ if match:
+ address_list.append([match.group(0), symbol, image])
+
+# Sort by address
+address_list.sort(key=operator.itemgetter(0))
+
+# Generate memory view
+print('{:-^87}'.format('Memory Map from: ' + build_dir))
+for address in reversed(address_list):
+ if "bl1" in address[2]:
+ print(address[0], '+{:-^20}+ |{:^20}| |{:^20}|'.format(address[1], '', ''))
+ elif "bl2" in address[2]:
+ print(address[0], '|{:^20}| +{:-^20}+ |{:^20}|'.format('', address[1], ''))
+ elif "bl31" in address[2]:
+ print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+ else:
+ print(address[0], '|{:^20}| |{:^20}| +{:-^20}+'.format('', '', address[1]))
+
+print('{:^20}{:_^20} {:_^20} {:_^20}'.format('', '', '', ''))
+print('{:^20}{:^20} {:^20} {:^20}'.format('address', 'bl1', 'bl2', 'bl31'))