arm-trusted-firmware/plat/imx/imx8m/imx8mq/include/platform_def.h
Igor Opaniuk 9ce232fe98 feat(plat/imx8m): add SiP call for secondary boot
In iMX8MM it is possible to have two copies of bootloader in
SD/eMMC and switch between them. The switch is triggered either
by the BootROM in case the bootloader image is faulty OR can be
enforced by the user. To trigger that switch the
PERSIST_SECONDARY_BOOT bit should be set in GPR10 SRC register.
As the bit is retained after WARM reset, that permits to control
BootROM behavior regarding what boot image it will boot after
reset: primary or secondary.

This is useful for reliable bootloader A/B updates, as it permits
switching between two copies of bootloader at different offsets of
the same storage.

If the PERSIST_SECONDARY_BOOT is 0, the boot ROM uses address
0x8400 for the primary image. If the PERSIST_SECONDARY_BOOT is 1,
the boot ROM reads that secondary image table from address 0x8200
on the boot media and uses the address specified in the table for
the secondary image.

Secondary Image Table contains the sector of secondary bootloader
image, exluding the offset to that image (explained below in the
note). To generate the Secondary Image Table, use e.g.:
$ printf '\x0\x0\x0\x0\x0\x0\x0\x0\x33\x22\x11'
         '\x00\x00\x10\x0\x0\x00\x0\x0\x0'
  > /tmp/sit.bin
$ hexdump  -vC /tmp/sit.bin
  00000000  00 00 00 00
  00000004  00 00 00 00
  00000008  33 22 11 00 <--- This is the "tag"
  0000000c  00 10 00 00 <--- This is the "firstSectorNumber"
  00000010  00 00 00 00

You can also use NXP script from [1][2] imx-mkimage tool for
SIT generation. Note that the firstSectorNumber is NOT the offset
of the IVT, but an offset of the IVT decremented by Image Vector
Table offset (Table 6-25. Image Vector Table Offset and Initial
Load Region Size for iMX8MM/MQ), so for secondary SPL copy at
offset 0x1042 sectors, firstSectorNumber must be 0x1000
(0x42 sectors * 512 = 0x8400 bytes offset).

In order to test redundant boot board should be closed and
SD/MMC manufacture mode disabled, as secondary boot is not
supported in the SD/MMC manufacture mode, which can be disabled
by blowing DISABLE_SDMMC_MFG (example for iMX8MM):
> fuse prog -y 2 1 0x00800000

For additional details check i.MX 8M Mini Apllication Processor
Reference Manual, 6.1.5.4.5 Redundant boot support for
expansion device chapter.

[1] https://source.codeaurora.org/external/imx/imx-mkimage/
[2] scripts/gen_sit.sh
Change-Id: I0a5cea7295a4197f6c89183d74b4011cada52d4c
Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
2021-05-21 15:01:38 +03:00

126 lines
3.6 KiB
C

/*
* Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64"
#define PLATFORM_LINKER_ARCH aarch64
#define PLATFORM_STACK_SIZE 0x800
#define CACHE_WRITEBACK_GRANULE 64
#define PLAT_PRIMARY_CPU U(0x0)
#define PLATFORM_MAX_CPU_PER_CLUSTER U(4)
#define PLATFORM_CLUSTER_COUNT U(1)
#define PLATFORM_CLUSTER0_CORE_COUNT U(4)
#define PLATFORM_CLUSTER1_CORE_COUNT U(0)
#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT)
#define IMX_PWR_LVL0 MPIDR_AFFLVL0
#define IMX_PWR_LVL1 MPIDR_AFFLVL1
#define IMX_PWR_LVL2 MPIDR_AFFLVL2
#define PWR_DOMAIN_AT_MAX_LVL U(1)
#define PLAT_MAX_PWR_LVL U(2)
#define PLAT_MAX_OFF_STATE U(4)
#define PLAT_MAX_RET_STATE U(1)
#define PLAT_WAIT_RET_STATE PLAT_MAX_RET_STATE
#define PLAT_WAIT_OFF_STATE U(2)
#define PLAT_STOP_OFF_STATE U(3)
#define BL31_BASE U(0x910000)
#define BL31_LIMIT U(0x920000)
/* non-secure uboot base */
#define PLAT_NS_IMAGE_OFFSET U(0x40200000)
/* GICv3 base address */
#define PLAT_GICD_BASE U(0x38800000)
#define PLAT_GICR_BASE U(0x38880000)
#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32)
#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32)
#define MAX_XLAT_TABLES 4
#define MAX_MMAP_REGIONS 14
#define HAB_RVT_BASE U(0x00000880) /* HAB_RVT for i.MX8MQ */
#define IMX_BOOT_UART_BASE U(0x30860000)
#define IMX_BOOT_UART_CLK_IN_HZ 25000000 /* Select 25Mhz oscillator */
#define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE
#define PLAT_CRASH_UART_CLK_IN_HZ 25000000
#define IMX_CONSOLE_BAUDRATE 115200
#define IMX_AIPS_BASE U(0x30200000)
#define IMX_AIPS_SIZE U(0xC00000)
#define IMX_AIPS1_BASE U(0x30200000)
#define IMX_AIPS3_ARB_BASE U(0x30800000)
#define IMX_OCOTP_BASE U(0x30350000)
#define IMX_ANAMIX_BASE U(0x30360000)
#define IMX_CCM_BASE U(0x30380000)
#define IMX_SRC_BASE U(0x30390000)
#define IMX_GPC_BASE U(0x303a0000)
#define IMX_RDC_BASE U(0x303d0000)
#define IMX_CSU_BASE U(0x303e0000)
#define IMX_WDOG_BASE U(0x30280000)
#define IMX_SNVS_BASE U(0x30370000)
#define IMX_NOC_BASE U(0x32700000)
#define IMX_TZASC_BASE U(0x32F80000)
#define IMX_CAAM_BASE U(0x30900000)
#define IMX_IOMUX_GPR_BASE U(0x30340000)
#define IMX_DDRC_BASE U(0x3d400000)
#define IMX_DDRPHY_BASE U(0x3c000000)
#define IMX_DDR_IPS_BASE U(0x3d000000)
#define IMX_ROM_BASE U(0x00000000)
#define IMX_ROM_SIZE U(0x20000)
#define AIPSTZ1_BASE U(0x301f0000)
#define AIPSTZ2_BASE U(0x305f0000)
#define AIPSTZ3_BASE U(0x309f0000)
#define AIPSTZ4_BASE U(0x32df0000)
#define GPV_BASE U(0x32000000)
#define GPV_SIZE U(0x800000)
#define IMX_GIC_BASE PLAT_GICD_BASE
#define IMX_GIC_SIZE U(0x200000)
#define WDOG_WSR U(0x2)
#define WDOG_WCR_WDZST BIT(0)
#define WDOG_WCR_WDBG BIT(1)
#define WDOG_WCR_WDE BIT(2)
#define WDOG_WCR_WDT BIT(3)
#define WDOG_WCR_SRS BIT(4)
#define WDOG_WCR_WDA BIT(5)
#define WDOG_WCR_SRE BIT(6)
#define WDOG_WCR_WDW BIT(7)
#define SRC_A53RCR0 U(0x4)
#define SRC_A53RCR1 U(0x8)
#define SRC_OTG1PHY_SCR U(0x20)
#define SRC_OTG2PHY_SCR U(0x24)
#define SRC_GPR1_OFFSET U(0x74)
#define SRC_GPR10_OFFSET U(0x98)
#define SRC_GPR10_PERSIST_SECONDARY_BOOT BIT(30)
#define SNVS_LPCR U(0x38)
#define SNVS_LPCR_SRTC_ENV BIT(0)
#define SNVS_LPCR_DP_EN BIT(5)
#define SNVS_LPCR_TOP BIT(6)
#define IOMUXC_GPR10 U(0x28)
#define GPR_TZASC_EN BIT(0)
#define GPR_TZASC_EN_LOCK BIT(16)
#define OCRAM_S_BASE U(0x00180000)
#define OCRAM_S_SIZE U(0x8000)
#define OCRAM_S_LIMIT (OCRAM_S_BASE + OCRAM_S_SIZE)
#define COUNTER_FREQUENCY 8000000 /* 8MHz */
#define DEBUG_CONSOLE 0
#define IMX_WDOG_B_RESET