Commit 9719e19a authored by Joanna Farley's avatar Joanna Farley Committed by TrustedFirmware Code Review
Browse files

Merge changes I500ddbe9,I9c10dac9,I53bfff85,I06f7594d,I24bff8d4, ... into integration

* changes:
  nxp lx2160a-aqds: new plat based on soc lx2160a
  NXP lx2160a-rdb: new plat based on SoC lx2160a
  nxp lx2162aqds: new plat based on soc lx2160a
  nxp: errata handling at soc level for lx2160a
  nxp: make file for loading additional ddr image
  nxp: adding support of soc lx2160a
  nxp: deflt hdr files for soc & their platforms
  nxp: platform files for bl2 and bl31 setup
  nxp: warm reset support to retain ddr content
  nxp: nv storage api on platforms
  nxp: supports two mode of trusted board boot
  nxp: fip-handler for additional fip_fuse.bin
  nxp: fip-handler for additional ddr-fip.bin
  nxp: image loader for loading fip image
  nxp: svp & sip smc handling
  nxp: psci platform functions used by lib/psci
  nxp: helper function used by plat & common code
  nxp: add data handler used by bl31
  nxp: adding the driver.mk file
  nxp-tool: for creating pbl file from bl2
  nxp: adding the smmu driver
  nxp: cot using nxp internal and mbedtls
  nxp:driver for crypto h/w accelerator caam
  nxp:add driver support for sd and emmc
  nxp:add qspi driver
  nxp: add flexspi driver support
  nxp: adding gic apis for nxp soc
  nxp: gpio driver support
  nxp: added csu driver
  nxp: driver pmu for nxp soc
  nxp: ddr driver enablement for nxp layerscape soc
  nxp: i2c driver support.
  NXP: Driver for NXP Security Monitor
  NXP: SFP driver support for NXP SoC
  NXP: Interconnect API based on ARM CCN-CCI driver
  NXP: TZC API to configure ddr region
  NXP: Timer API added to enable ARM generic timer
  nxp: add dcfg driver
  nxp:add console driver for nxp platform
  tools: add mechanism to allow platform specific image UUID
  tbbr-cot: conditional definition for the macro
  tbbr-cot: fix the issue of compiling time define
  cert_create: updated tool for platform defined certs, keys & extensions
  tbbr-tools: enable override TRUSTED_KEY_CERT
parents b59444ea f359a382
// SPDX-License-Identifier: BSD-3-Clause
/*
* Copyright 2020 NXP
*/
/**
* @Flash info
*
*/
#ifndef FLASH_INFO_H
#define FLASH_INFO_H
#define SZ_16M_BYTES 0x1000000U
#if defined(CONFIG_MT25QU512A)
#define F_SECTOR_64K 0x10000U
#define F_PAGE_256 0x100U
#define F_SECTOR_4K 0x1000U
#define F_FLASH_SIZE_BYTES 0x4000000U
#define F_SECTOR_ERASE_SZ F_SECTOR_64K
#ifdef CONFIG_FSPI_4K_ERASE
#define F_SECTOR_ERASE_SZ F_SECTOR_4K
#endif
#elif defined(CONFIG_MX25U25645G)
#define F_SECTOR_64K 0x10000U
#define F_PAGE_256 0x100U
#define F_SECTOR_4K 0x1000U
#define F_FLASH_SIZE_BYTES 0x2000000U
#define F_SECTOR_ERASE_SZ F_SECTOR_64K
#ifdef CONFIG_FSPI_4K_ERASE
#define F_SECTOR_ERASE_SZ F_SECTOR_4K
#endif
#elif defined(CONFIG_MX25U51245G)
#define F_SECTOR_64K 0x10000U
#define F_PAGE_256 0x100U
#define F_SECTOR_4K 0x1000U
#define F_FLASH_SIZE_BYTES 0x4000000U
#define F_SECTOR_ERASE_SZ F_SECTOR_64K
#ifdef CONFIG_FSPI_4K_ERASE
#define F_SECTOR_ERASE_SZ F_SECTOR_4K
#endif
#elif defined(CONFIG_MT35XU512A)
#define F_SECTOR_128K 0x20000U
#define F_SECTOR_32K 0x8000U
#define F_PAGE_256 0x100U
#define F_SECTOR_4K 0x1000U
#define F_FLASH_SIZE_BYTES 0x4000000U
#define F_SECTOR_ERASE_SZ F_SECTOR_128K
#ifdef CONFIG_FSPI_4K_ERASE
#define F_SECTOR_ERASE_SZ F_SECTOR_4K
#endif
#ifdef NXP_WARM_BOOT
#define FLASH_WR_COMP_WAIT_BY_NOP_COUNT 0x20000
#endif
#endif
#endif /* FLASH_INFO_H */
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/*!
* @file fspi_api.h
* @brief This file contains the FlexSPI/FSPI API to communicate
* to attached Slave device.
* @addtogroup FSPI_API
* @{
*/
#ifndef FSPI_API_H
#define FSPI_API_H
#if DEBUG_FLEXSPI
#define SZ_57M 0x3900000u
#endif
/*!
* Basic set of APIs.
*/
/*!
* @details AHB read/IP Read, decision to be internal to API
* Minimum Read size = 1Byte
* @param[in] src_off source offset from where data to read from flash
* @param[out] des Destination location where data needs to be copied
* @param[in] len length in Bytes,where 1-word=4-bytes/32-bits
*
* @return XSPI_SUCCESS or error code
*/
int xspi_read(uint32_t src_off, uint32_t *des, uint32_t len);
/*!
* @details Sector erase, Minimum size
* 256KB(0x40000)/128KB(0x20000)/64K(0x10000)/4K(0x1000)
* depending upon flash, Calls xspi_wren() internally
* @param[out] erase_offset Destination erase location on flash which
* has to be erased, needs to be multiple of 0x40000/0x20000/0x10000
* @param[in] erase_len length in bytes in Hex like 0x100000 for 1MB, minimum
* erase size is 1 sector(0x40000/0x20000/0x10000)
*
* @return XSPI_SUCCESS or error code
*/
int xspi_sector_erase(uint32_t erase_offset, uint32_t erase_len);
/*!
* @details IP write, For writing data to flash, calls xspi_wren() internally.
* Single/multiple page write can start @any offset, but performance will be low
* due to ERRATA
* @param[out] dst_off Destination location on flash where data needs to
* be written
* @param[in] src source offset from where data to be read
* @param[in] len length in bytes,where 1-word=4-bytes/32-bits
*
* @return XSPI_SUCCESS or error code
*/
int xspi_write(uint32_t dst_off, void *src, uint32_t len);
/*!
* @details fspi_init, Init function.
* @param[in] uint32_t base_reg_addr
* @param[in] uint32_t flash_start_addr
*
* @return XSPI_SUCCESS or error code
*/
int fspi_init(uint32_t base_reg_addr, uint32_t flash_start_addr);
/*!
* @details is_flash_busy, Check if any erase or write or lock is
* pending on flash/slave
* @param[in] void
*
* @return TRUE/FLASE
*/
bool is_flash_busy(void);
/*!
* Advanced set of APIs.
*/
/*!
* @details Write enable, to be used by advance users only.
* Step 1 for sending write commands to flash.
* @param[in] dst_off destination offset where data will be written
*
* @return XSPI_SUCCESS or error code
*/
int xspi_wren(uint32_t dst_off);
/*!
* @details AHB read, meaning direct memory mapped access to flash,
* Minimum Read size = 1Byte
* @param[in] src_off source offset from where data to read from flash,
* needs to be word aligned
* @param[out] des Destination location where data needs to be copied
* @param[in] len length in Bytes,where 1-word=4-bytes/32-bits
*
* @return XSPI_SUCCESS or error code
*/
int xspi_ahb_read(uint32_t src_off, uint32_t *des, uint32_t len);
/*!
* @details IP read, READ via RX buffer from flash, minimum READ size = 1Byte
* @param[in] src_off source offset from where data to be read from flash
* @param[out] des Destination location where data needs to be copied
* @param[in] len length in Bytes,where 1-word=4-bytes/32-bits
*
* @return XSPI_SUCCESS or error code
*/
int xspi_ip_read(uint32_t src_off, uint32_t *des, uint32_t len);
/*!
* @details CHIP erase, Erase complete chip in one go
*
* @return XSPI_SUCCESS or error code
*/
int xspi_bulk_erase(void);
/*!
* Add test cases to confirm flash read/erase/write functionality.
*/
void fspi_test(uint32_t fspi_test_addr, uint32_t size, int extra);
#endif /* FSPI_API_H */
/*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
/* error codes */
#ifndef XSPI_ERROR_CODES_H
#define XSPI_ERROR_CODES_H
#include <errno.h>
typedef enum {
XSPI_SUCCESS = 0,
XSPI_READ_FAIL = ELAST + 1,
XSPI_ERASE_FAIL,
XSPI_IP_READ_FAIL,
XSPI_AHB_READ_FAIL,
XSPI_IP_WRITE_FAIL,
XSPI_AHB_WRITE_FAIL,
XSPI_BLOCK_TIMEOUT,
XSPI_UNALIGN_ADDR,
XSPI_UNALIGN_SIZE,
} XSPI_STATUS_CODES;
#undef ELAST
#define ELAST XSPI_STATUS_CODES.XSPI_UNALIGN_SIZE
#endif
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef NXP_SMMU_H
#define NXP_SMMU_H
#define SMMU_SCR0 (0x0)
#define SMMU_NSCR0 (0x400)
#define SCR0_CLIENTPD_MASK 0x00000001
#define SCR0_USFCFG_MASK 0x00000400
static inline void bypass_smmu(uintptr_t smmu_base_addr)
{
uint32_t val;
val = (mmio_read_32(smmu_base_addr + SMMU_SCR0) | SCR0_CLIENTPD_MASK) &
~(SCR0_USFCFG_MASK);
mmio_write_32((smmu_base_addr + SMMU_SCR0), val);
val = (mmio_read_32(smmu_base_addr + SMMU_NSCR0) | SCR0_CLIENTPD_MASK) &
~(SCR0_USFCFG_MASK);
mmio_write_32((smmu_base_addr + SMMU_NSCR0), val);
}
#endif
......@@ -163,4 +163,9 @@
*/
#define MHZ_TICKS_PER_SEC U(1000000)
/*
* Ticks elapsed in one second with a signal of 1 KHz
*/
#define KHZ_TICKS_PER_SEC U(1000)
#endif /* UTILS_DEF_H */
/*
* Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2014-2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
......@@ -82,6 +82,10 @@
#define UUID_FW_CONFIG \
{{0x58, 0x07, 0xe1, 0x6a}, {0x84, 0x59}, {0x47, 0xbe}, 0x8e, 0xd5, {0x64, 0x8e, 0x8d, 0xdd, 0xab, 0x0e} }
#ifdef PLAT_DEF_FIP_UUID
#include <plat_def_fip_uuid.h>
#endif
typedef struct fip_toc_header {
uint32_t name;
uint32_t serial_number;
......
......@@ -160,4 +160,7 @@
#define SP_PKG7_HASH_OID "1.3.6.1.4.1.4128.2100.1307"
#define SP_PKG8_HASH_OID "1.3.6.1.4.1.4128.2100.1308"
#ifdef PLAT_DEF_OID
#include <platform_oid.h>
#endif
#endif /* TBBR_OID_H */
#
# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
# Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
......@@ -33,7 +33,7 @@
#
# Certificate generation tool default parameters
TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt
TRUSTED_KEY_CERT ?= ${BUILD_PLAT}/trusted_key.crt
FWU_CERT := ${BUILD_PLAT}/fwu_cert.crt
# Default non-volatile counter values (overridable by the platform)
......
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <asm_macros.S>
#include "bl31_data.h"
#include "plat_psci.h"
#include "platform_def.h"
.global _getCoreData
.global _setCoreData
.global _getCoreState
.global _setCoreState
.global _init_global_data
.global _get_global_data
.global _set_global_data
.global _initialize_psci
.global _init_task_flags
.global _set_task1_start
.global _set_task1_done
/* Function returns the specified data field value from the specified cpu
* core data area
* in: x0 = core mask lsb
* x1 = data field name/offset
* out: x0 = data value
* uses x0, x1, x2, [x13, x14, x15]
*/
func _getCoreData
/* generate a 0-based core number from the input mask */
clz x2, x0
mov x0, #63
sub x0, x0, x2
/* x0 = core number (0-based) */
/* x1 = field offset */
/* determine if this is bootcore or secondary core */
cbnz x0, 1f
/* get base address for bootcore data */
ldr x2, =BC_PSCI_BASE
add x2, x2, x1
b 2f
1: /* get base address for secondary core data */
/* x0 = core number (0-based) */
/* x1 = field offset */
/* generate number of regions to offset */
mov x2, #SEC_REGION_SIZE
mul x2, x2, x0
/* x1 = field offset */
/* x2 = region offset */
/* generate the total offset to data element */
sub x1, x2, x1
/* x1 = total offset to data element */
/* get the base address */
ldr x2, =SECONDARY_TOP
/* apply offset to base addr */
sub x2, x2, x1
2:
/* x2 = data element address */
dc ivac, x2
dsb sy
isb
/* read data */
ldr x0, [x2]
ret
endfunc _getCoreData
/* Function returns the SoC-specific state of the specified cpu
* in: x0 = core mask lsb
* out: x0 = data value
* uses x0, x1, x2, [x13, x14, x15]
*/
func _getCoreState
mov x1, #CORE_STATE_DATA
/* generate a 0-based core number from the input mask */
clz x2, x0
mov x0, #63
sub x0, x0, x2
/* x0 = core number (0-based) */
/* x1 = field offset */
/* determine if this is bootcore or secondary core */
cbnz x0, 1f
/* get base address for bootcore data */
ldr x2, =BC_PSCI_BASE
add x2, x2, x1
b 2f
1: /* get base address for secondary core data */
/* x0 = core number (0-based) */
/* x1 = field offset */
/* generate number of regions to offset */
mov x2, #SEC_REGION_SIZE
mul x2, x2, x0
/* x1 = field offset */
/* x2 = region offset */
/* generate the total offset to data element */
sub x1, x2, x1
/* x1 = total offset to data element */
/* get the base address */
ldr x2, =SECONDARY_TOP
/* apply offset to base addr */
sub x2, x2, x1
2:
/* x2 = data element address */
dc ivac, x2
dsb sy
isb
/* read data */
ldr x0, [x2]
ret
endfunc _getCoreState
/* Function writes the specified data value into the specified cpu
* core data area
* in: x0 = core mask lsb
* x1 = data field offset
* x2 = data value to write/store
* out: none
* uses x0, x1, x2, x3, [x13, x14, x15]
*/
func _setCoreData
/* x0 = core mask */
/* x1 = field offset */
/* x2 = data value */
clz x3, x0
mov x0, #63
sub x0, x0, x3
/* x0 = core number (0-based) */
/* x1 = field offset */
/* x2 = data value */
/* determine if this is bootcore or secondary core */
cbnz x0, 1f
/* get base address for bootcore data */
ldr x3, =BC_PSCI_BASE
add x3, x3, x1
b 2f
1: /* get base address for secondary core data */
/* x0 = core number (0-based) */
/* x1 = field offset */
/* x2 = data value */
/* generate number of regions to offset */
mov x3, #SEC_REGION_SIZE
mul x3, x3, x0
/* x1 = field offset */
/* x2 = data value */
/* x3 = region offset */
/* generate the total offset to data element */
sub x1, x3, x1
/* x1 = total offset to data element */
/* x2 = data value */
ldr x3, =SECONDARY_TOP
/* apply offset to base addr */
sub x3, x3, x1
2:
/* x2 = data value */
/* x3 = data element address */
str x2, [x3]
dc cvac, x3
dsb sy
isb
ret
endfunc _setCoreData
/* Function stores the specified core state
* in: x0 = core mask lsb
* x1 = data value to write/store
* out: none
* uses x0, x1, x2, x3, [x13, x14, x15]
*/
func _setCoreState
mov x2, #CORE_STATE_DATA
clz x3, x0
mov x0, #63
sub x0, x0, x3
/* x0 = core number (0-based) */
/* x1 = data value */
/* x2 = field offset */
/* determine if this is bootcore or secondary core */
cbnz x0, 1f
/* get base address for bootcore data */
ldr x3, =BC_PSCI_BASE
add x3, x3, x2
b 2f
1: /* get base address for secondary core data */
/* x0 = core number (0-based) */
/* x1 = data value */
/* x2 = field offset */
/* generate number of regions to offset */
mov x3, #SEC_REGION_SIZE
mul x3, x3, x0
/* x1 = data value */
/* x2 = field offset */
/* x3 = region offset */
/* generate the total offset to data element */
sub x2, x3, x2
/* x1 = data value */
/* x2 = total offset to data element */
ldr x3, =SECONDARY_TOP
/* apply offset to base addr */
sub x3, x3, x2
2:
/* x1 = data value */
/* x3 = data element address */
str x1, [x3]
dc civac, x3
dsb sy
isb
ret
endfunc _setCoreState
/* Function sets the task1 start
* in: w0 = value to set flag to
* out: none
* uses x0, x1
*/
func _set_task1_start
ldr x1, =SMC_TASK1_BASE
add x1, x1, #TSK_START_OFFSET
str w0, [x1]
dc cvac, x1
dsb sy
isb
ret
endfunc _set_task1_start
/* Function sets the state of the task 1 done flag
* in: w0 = value to set flag to
* out: none
* uses x0, x1
*/
func _set_task1_done
ldr x1, =SMC_TASK1_BASE
add x1, x1, #TSK_DONE_OFFSET
str w0, [x1]
dc cvac, x1
dsb sy
isb
ret
endfunc _set_task1_done
/* Function initializes the smc global data entries
* Note: the constant LAST_SMC_GLBL_OFFSET must reference the last entry in the
* smc global region
* in: none
* out: none
* uses x0, x1, x2
*/
func _init_global_data
ldr x1, =SMC_GLBL_BASE
/* x1 = SMC_GLBL_BASE */
mov x2, #LAST_SMC_GLBL_OFFSET
add x2, x2, x1
1:
str xzr, [x1]
dc cvac, x1
cmp x2, x1
add x1, x1, #8
b.hi 1b
dsb sy
isb
ret
endfunc _init_global_data
/* Function gets the value of the specified global data element
* in: x0 = offset of data element
* out: x0 = requested data element
* uses x0, x1
*/
func _get_global_data
ldr x1, =SMC_GLBL_BASE
add x1, x1, x0
dc ivac, x1
isb
ldr x0, [x1]
ret
endfunc _get_global_data
/* Function sets the value of the specified global data element
* in: x0 = offset of data element
* x1 = value to write
* out: none
* uses x0, x1, x2
*/
func _set_global_data
ldr x2, =SMC_GLBL_BASE
add x0, x0, x2
str x1, [x0]
dc cvac, x0
dsb sy
isb
ret
endfunc _set_global_data
/* Function initializes the core data areas
* only executed by the boot core
* in: none
* out: none
* uses: x0, x1, x2, x3, x4, x5, x6, x7, [x13, x14, x15]
*/
func _initialize_psci
mov x7, x30
/* initialize the bootcore psci data */
ldr x5, =BC_PSCI_BASE
mov x6, #CORE_RELEASED
str x6, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5], #8
dc cvac, x5
str xzr, [x5]
dc cvac, x5
dsb sy
isb
/* see if we have any secondary cores */
mov x4, #PLATFORM_CORE_COUNT
sub x4, x4, #1
cbz x4, 3f
/* initialize the secondary core's psci data */
ldr x5, =SECONDARY_TOP
/* core mask lsb for core 1 */
mov x3, #2
sub x5, x5, #SEC_REGION_SIZE
/* x3 = core1 mask lsb */
/* x4 = number of secondary cores */
/* x5 = core1 psci data base address */
2:
/* set core state in x6 */
mov x0, x3
mov x6, #CORE_IN_RESET
bl _soc_ck_disabled
cbz x0, 1f
mov x6, #CORE_DISABLED
1:
add x2, x5, #CORE_STATE_DATA
str x6, [x2]
dc cvac, x2
add x2, x5, #SPSR_EL3_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #CNTXT_ID_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #START_ADDR_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #LINK_REG_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #GICC_CTLR_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #ABORT_FLAG_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #SCTLR_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #CPUECTLR_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #AUX_01_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #AUX_02_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #AUX_03_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #AUX_04_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #AUX_05_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #SCR_EL3_DATA
str xzr, [x2]
dc cvac, x2
add x2, x5, #HCR_EL2_DATA
str xzr, [x2]
dc cvac, x2
dsb sy
isb
sub x4, x4, #1
cbz x4, 3f
/* generate next core mask */
lsl x3, x3, #1
/* decrement base address to next data area */
sub x5, x5, #SEC_REGION_SIZE
b 2b
3:
mov x30, x7
ret
endfunc _initialize_psci
/* Function initializes the soc init task flags
* in: none
* out: none
* uses x0, x1, [x13, x14, x15]
*/
func _init_task_flags
/* get the base address of the first task structure */
ldr x0, =SMC_TASK1_BASE
/* x0 = task1 base address */
str wzr, [x0, #TSK_START_OFFSET]
str wzr, [x0, #TSK_DONE_OFFSET]
str wzr, [x0, #TSK_CORE_OFFSET]
dc cvac, x0
/* move to task2 structure */
add x0, x0, #SMC_TASK_OFFSET
str wzr, [x0, #TSK_START_OFFSET]
str wzr, [x0, #TSK_DONE_OFFSET]
str wzr, [x0, #TSK_CORE_OFFSET]
dc cvac, x0
/* move to task3 structure */
add x0, x0, #SMC_TASK_OFFSET
str wzr, [x0, #TSK_START_OFFSET]
str wzr, [x0, #TSK_DONE_OFFSET]
str wzr, [x0, #TSK_CORE_OFFSET]
dc cvac, x0
/* move to task4 structure */
add x0, x0, #SMC_TASK_OFFSET
str wzr, [x0, #TSK_START_OFFSET]
str wzr, [x0, #TSK_DONE_OFFSET]
str wzr, [x0, #TSK_CORE_OFFSET]
dc cvac, x0
dsb sy
isb
ret
endfunc _init_task_flags
/*
* Copyright 2018-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <asm_macros.S>
#include <drivers/console.h>
#include <lib/cpus/aarch64/cortex_a72.h>
#include <platform_def.h>
.globl plat_crash_console_init
.globl plat_crash_console_putc
.globl plat_crash_console_flush
.globl plat_core_pos
.globl plat_my_core_pos
.globl plat_core_mask
.globl plat_my_core_mask
.globl plat_core_pos_by_mpidr
.globl _disable_ldstr_pfetch_A53
.globl _disable_ldstr_pfetch_A72
.global _set_smmu_pagesz_64
/* int plat_crash_console_init(void)
* Function to initialize the crash console
* without a C Runtime to print crash report.
* Clobber list : x0 - x4
*/
/* int plat_crash_console_init(void)
* Use normal console by default. Switch it to crash
* mode so serial consoles become active again.
* NOTE: This default implementation will only work for
* crashes that occur after a normal console (marked
* valid for the crash state) has been registered with
* the console framework. To debug crashes that occur
* earlier, the platform has to override these functions
* with an implementation that initializes a console
* driver with hardcoded parameters. See
* docs/porting-guide.rst for more information.
*/
func plat_crash_console_init
mov x3, x30
mov x0, #CONSOLE_FLAG_CRASH
bl console_switch_state
mov x0, #1
ret x3
endfunc plat_crash_console_init
/* void plat_crash_console_putc(int character)
* Output through the normal console by default.
*/
func plat_crash_console_putc
b console_putc
endfunc plat_crash_console_putc
/* void plat_crash_console_flush(void)
* Flush normal console by default.
*/
func plat_crash_console_flush
b console_flush
endfunc plat_crash_console_flush
/* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
*/
func plat_core_pos_by_mpidr
b plat_core_pos
endfunc plat_core_pos_by_mpidr
#if (SYMMETRICAL_CLUSTERS)
/* unsigned int plat_my_core_mask(void)
* generate a mask bit for this core
*/
func plat_my_core_mask
mrs x0, MPIDR_EL1
b plat_core_mask
endfunc plat_my_core_mask
/* unsigned int plat_core_mask(u_register_t mpidr)
* generate a lsb-based mask bit for the core specified by mpidr in x0.
*
* SoC core = ((cluster * cpu_per_cluster) + core)
* mask = (1 << SoC core)
*/
func plat_core_mask
mov w1, wzr
mov w2, wzr
/* extract cluster */
bfxil w1, w0, #8, #8
/* extract cpu # */
bfxil w2, w0, #0, #8
mov w0, wzr
/* error checking */
cmp w1, #NUMBER_OF_CLUSTERS
b.ge 1f
cmp w2, #CORES_PER_CLUSTER
b.ge 1f
mov w0, #CORES_PER_CLUSTER
mul w1, w1, w0
add w1, w1, w2
mov w2, #0x1
lsl w0, w2, w1
1:
ret
endfunc plat_core_mask
/*
* unsigned int plat_my_core_pos(void)
* generate a linear core number for this core
*/
func plat_my_core_pos
mrs x0, MPIDR_EL1
b plat_core_pos
endfunc plat_my_core_pos
/*
* unsigned int plat_core_pos(u_register_t mpidr)
* Generate a linear core number for the core specified by mpidr.
*
* SoC core = ((cluster * cpu_per_cluster) + core)
* Returns -1 if mpidr invalid
*/
func plat_core_pos
mov w1, wzr
mov w2, wzr
bfxil w1, w0, #8, #8 /* extract cluster */
bfxil w2, w0, #0, #8 /* extract cpu # */
mov w0, #-1
/* error checking */
cmp w1, #NUMBER_OF_CLUSTERS
b.ge 1f
cmp w2, #CORES_PER_CLUSTER
b.ge 1f
mov w0, #CORES_PER_CLUSTER
mul w1, w1, w0
add w0, w1, w2
1:
ret
endfunc plat_core_pos
#endif
/* this function disables the load-store prefetch of the calling core
* Note: this function is for A72 cores ONLY
* in: none
* out: none
* uses x0
*/
func _disable_ldstr_pfetch_A72
mrs x0, CORTEX_A72_CPUACTLR_EL1
tst x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
b.eq 1f
b 2f
.align 6
1:
dsb sy
isb
orr x0, x0, #CORTEX_A72_CPUACTLR_EL1_DISABLE_L1_DCACHE_HW_PFTCH
msr CORTEX_A72_CPUACTLR_EL1, x0
isb
2:
ret
endfunc _disable_ldstr_pfetch_A72
/*
* Function sets the SACR pagesize to 64k
*/
func _set_smmu_pagesz_64
ldr x1, =NXP_SMMU_ADDR
ldr w0, [x1, #0x10]
orr w0, w0, #1 << 16 /* setting to 64K page */
str w0, [x1, #0x10]
ret
endfunc _set_smmu_pagesz_64
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef PLAT_DEF_FIP_UUID_H
#define PLAT_DEF_FIP_UUID_H
/* PHy images configs */
#define UUID_DDR_IMEM_UDIMM_1D \
{{0x5b, 0xdb, 0xe3, 0x83}, {0xd1, 0x9f}, {0xc7, 0x06}, 0xd4, 0x91, {0x76, 0x4f, 0x9d, 0x23, 0x2d, 0x2d} }
#define UUID_DDR_IMEM_UDIMM_2D \
{{0xfa, 0x0e, 0xeb, 0x21}, {0xe0, 0x7f}, {0x8e, 0x65}, 0x95, 0xd8, {0x2b, 0x94, 0xf6, 0xb8, 0x28, 0x0a} }
#define UUID_DDR_DMEM_UDIMM_1D \
{{0xba, 0xbb, 0xfd, 0x7e}, {0x5b, 0xf0}, {0xeb, 0xb8}, 0xeb, 0x71, {0xb1, 0x85, 0x07, 0xdd, 0xe1, 0x32} }
#define UUID_DDR_DMEM_UDIMM_2D \
{{0xb6, 0x99, 0x61, 0xda}, {0xf9, 0x92}, {0x4b, 0x9e}, 0x0c, 0x49, {0x74, 0xa5, 0xe0, 0x5c, 0xbe, 0xc3} }
#define UUID_DDR_IMEM_RDIMM_1D \
{{0x42, 0x33, 0x66, 0x52}, {0xd8, 0x94}, {0x4d, 0xc1}, 0x91, 0xcc, {0x26, 0x8f, 0x7a, 0x67, 0xf1, 0xa2} }
#define UUID_DDR_IMEM_RDIMM_2D \
{{0x2e, 0x95, 0x73, 0xba}, {0xb5, 0xca}, {0x7c, 0xc7}, 0xef, 0xc9, {0x5e, 0xb0, 0x42, 0xec, 0x08, 0x7a} }
#define UUID_DDR_DMEM_RDIMM_1D \
{{0x1c, 0x51, 0x17, 0xed}, {0x30, 0x0d}, {0xae, 0xba}, 0x87, 0x03, {0x1f, 0x37, 0x85, 0xec, 0xe1, 0x44} }
#define UUID_DDR_DMEM_RDIMM_2D \
{{0xe9, 0x0a, 0x90, 0x78}, {0x11, 0xd6}, {0x8b, 0xba}, 0x24, 0x35, {0xec, 0x10, 0x75, 0x4f, 0x56, 0xa5} }
#define UUID_DDR_FW_KEY_CERT \
{{0xac, 0x4b, 0xb8, 0x9c}, {0x8f, 0xb9}, {0x11, 0xea}, 0xbc, 0x55, {0x02, 0x42, 0xac, 0x12, 0x00, 0x03} }
#define UUID_DDR_UDIMM_FW_CONTENT_CERT \
{{0x2c, 0x7f, 0x52, 0x54}, {0x70, 0x92}, {0x48, 0x40}, 0x8c, 0x34, {0x87, 0x4b, 0xbf, 0xbd, 0x9d, 0x89} }
#define UUID_DDR_RDIMM_FW_CONTENT_CERT \
{{0x94, 0xc3, 0x63, 0x30}, {0x7c, 0xf7}, {0x4f, 0x1d}, 0xaa, 0xcd, {0xb5, 0x80, 0xb2, 0xc2, 0x40, 0xa5} }
#define UUID_FUSE_PROV \
{{0xec, 0x45, 0x90, 0x42}, {0x30, 0x0d}, {0xae, 0xba}, 0x87, 0x03, {0x1f, 0x37, 0x85, 0xec, 0xe1, 0x44} }
#define UUID_FUSE_UP \
{{0x89, 0x46, 0xef, 0x78}, {0x11, 0xd6}, {0x8b, 0xba}, 0x24, 0x35, {0xec, 0x10, 0x75, 0x4f, 0x56, 0xa5} }
#endif /* PLAT_DEF_FIP_UUID_H */
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef NXP_IMG_DEF_H
#define NXP_IMG_DEF_H
#include <export/common/tbbr/tbbr_img_def_exp.h>
#ifdef CONFIG_DDR_FIP_IMAGE
/* DDR FIP IMAGE ID */
#define DDR_FIP_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS
#define DDR_IMEM_UDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 1
#define DDR_IMEM_UDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 2
#define DDR_DMEM_UDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 3
#define DDR_DMEM_UDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 4
#define DDR_IMEM_RDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 5
#define DDR_IMEM_RDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 6
#define DDR_DMEM_RDIMM_1D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 7
#define DDR_DMEM_RDIMM_2D_IMAGE_ID MAX_IMG_IDS_WITH_SPMDS + 8
#define DDR_FW_KEY_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 9
#define DDR_UDIMM_FW_CONTENT_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 10
#define DDR_RDIMM_FW_CONTENT_CERT_ID MAX_IMG_IDS_WITH_SPMDS + 11
/* Max Images */
#define MAX_IMG_WITH_DDR_IDS MAX_IMG_IDS_WITH_SPMDS + 12
#else
#define MAX_IMG_WITH_DDR_IDS MAX_IMG_IDS_WITH_SPMDS
#endif
#ifdef POLICY_FUSE_PROVISION
/* FUSE FIP IMAGE ID */
#define FUSE_FIP_IMAGE_ID MAX_IMG_WITH_DDR_IDS
#define FUSE_PROV_IMAGE_ID MAX_IMG_WITH_DDR_IDS + 1
#define FUSE_UP_IMAGE_ID MAX_IMG_WITH_DDR_IDS + 2
#define MAX_IMG_WITH_FIMG_IDS MAX_IMG_WITH_DDR_IDS + 3
#else
#define MAX_IMG_WITH_FIMG_IDS MAX_IMG_WITH_DDR_IDS
#endif
#define MAX_NUMBER_IDS MAX_IMG_WITH_FIMG_IDS
#endif /* NXP_IMG_DEF_H */
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#define DDR_FW_CONTENT_CERT_PK_OID "1.3.6.1.4.1.4128.2200.1"
#define DDR_IMEM_UDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.2"
#define DDR_IMEM_UDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.3"
#define DDR_DMEM_UDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.4"
#define DDR_DMEM_UDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.5"
#define DDR_IMEM_RDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.6"
#define DDR_IMEM_RDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.7"
#define DDR_DMEM_RDIMM_1D_HASH_OID "1.3.6.1.4.1.4128.2200.8"
#define DDR_DMEM_RDIMM_2D_HASH_OID "1.3.6.1.4.1.4128.2200.9"
#
# Copyright 2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
#-----------------------------------------------------------------------------
ifeq (${DDR_FIP_IO_STORAGE_ADDED},)
$(eval $(call add_define, PLAT_DEF_FIP_UUID))
$(eval $(call add_define, PLAT_TBBR_IMG_DEF))
$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
DDR_FIP_IO_STORAGE_ADDED := 1
$(eval $(call add_define,CONFIG_DDR_FIP_IMAGE))
FIP_HANDLER_PATH := ${PLAT_COMMON_PATH}/fip_handler
FIP_HANDLER_COMMON_PATH := ${FIP_HANDLER_PATH}/common
DDR_FIP_IO_STORAGE_PATH := ${FIP_HANDLER_PATH}/ddr_fip
PLAT_INCLUDES += -I${FIP_HANDLER_COMMON_PATH}\
-I$(DDR_FIP_IO_STORAGE_PATH)
DDR_FIP_IO_SOURCES += $(DDR_FIP_IO_STORAGE_PATH)/ddr_io_storage.c
$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
ifeq (${BL_COMM_DDR_FIP_IO_NEEDED},yes)
BL_COMMON_SOURCES += ${DDR_FIP_IO_SOURCES}
else
ifeq (${BL2_DDR_FIP_IO_NEEDED},yes)
BL2_SOURCES += ${DDR_FIP_IO_SOURCES}
endif
ifeq (${BL31_DDR_FIP_IO_NEEDED},yes)
BL31_SOURCES += ${DDR_FIP_IO_SOURCES}
endif
endif
endif
#------------------------------------------------
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <string.h>
#include <io_block.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#include <lib/utils.h>
#include <tools_share/firmware_image_package.h>
#include "ddr_io_storage.h"
#include "plat_common.h"
#include "platform_def.h"
/* TBD - Move these defined to the platform_def.h file.
* Keeping them for reference here
*/
extern uintptr_t backend_dev_handle;
static uint32_t ddr_fip;
static uintptr_t ddr_fip_dev_handle;
static io_block_spec_t ddr_fip_block_spec = {
.offset = PLAT_DDR_FIP_OFFSET,
.length = PLAT_DDR_FIP_MAX_SIZE
};
static const io_uuid_spec_t ddr_imem_udimm_1d_uuid_spec = {
.uuid = UUID_DDR_IMEM_UDIMM_1D,
};
static const io_uuid_spec_t ddr_imem_udimm_2d_uuid_spec = {
.uuid = UUID_DDR_IMEM_UDIMM_2D,
};
static const io_uuid_spec_t ddr_dmem_udimm_1d_uuid_spec = {
.uuid = UUID_DDR_DMEM_UDIMM_1D,
};
static const io_uuid_spec_t ddr_dmem_udimm_2d_uuid_spec = {
.uuid = UUID_DDR_DMEM_UDIMM_2D,
};
static const io_uuid_spec_t ddr_imem_rdimm_1d_uuid_spec = {
.uuid = UUID_DDR_IMEM_RDIMM_1D,
};
static const io_uuid_spec_t ddr_imem_rdimm_2d_uuid_spec = {
.uuid = UUID_DDR_IMEM_RDIMM_2D,
};
static const io_uuid_spec_t ddr_dmem_rdimm_1d_uuid_spec = {
.uuid = UUID_DDR_DMEM_RDIMM_1D,
};
static const io_uuid_spec_t ddr_dmem_rdimm_2d_uuid_spec = {
.uuid = UUID_DDR_DMEM_RDIMM_2D,
};
#if TRUSTED_BOARD_BOOT
static const io_uuid_spec_t ddr_fw_key_cert_uuid_spec = {
.uuid = UUID_DDR_FW_KEY_CERT,
};
static const io_uuid_spec_t ddr_udimm_fw_cert_uuid_spec = {
.uuid = UUID_DDR_UDIMM_FW_CONTENT_CERT,
};
static const io_uuid_spec_t ddr_rdimm_fw_cert_uuid_spec = {
.uuid = UUID_DDR_RDIMM_FW_CONTENT_CERT,
};
#endif
static int open_ddr_fip(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
/* By default, ARM platforms load images from the FIP */
static const struct plat_io_policy ddr_policies[] = {
[DDR_FIP_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&backend_dev_handle,
(uintptr_t)&ddr_fip_block_spec,
NULL
},
[DDR_IMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_imem_udimm_1d_uuid_spec,
open_ddr_fip
},
[DDR_IMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_imem_udimm_2d_uuid_spec,
open_ddr_fip
},
[DDR_DMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_dmem_udimm_1d_uuid_spec,
open_ddr_fip
},
[DDR_DMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_dmem_udimm_2d_uuid_spec,
open_ddr_fip
},
[DDR_IMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_imem_rdimm_1d_uuid_spec,
open_ddr_fip
},
[DDR_IMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_imem_rdimm_2d_uuid_spec,
open_ddr_fip
},
[DDR_DMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_dmem_rdimm_1d_uuid_spec,
open_ddr_fip
},
[DDR_DMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_dmem_rdimm_2d_uuid_spec,
open_ddr_fip
},
#if TRUSTED_BOARD_BOOT
[DDR_FW_KEY_CERT_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_fw_key_cert_uuid_spec,
open_ddr_fip
},
[DDR_UDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_udimm_fw_cert_uuid_spec,
open_ddr_fip
},
[DDR_RDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
&ddr_fip_dev_handle,
(uintptr_t)&ddr_rdimm_fw_cert_uuid_spec,
open_ddr_fip
},
#endif
};
static int open_ddr_fip(const uintptr_t spec)
{
int result;
uintptr_t local_image_handle;
/* See if a Firmware Image Package is available */
result = io_dev_init(ddr_fip_dev_handle, (uintptr_t)DDR_FIP_IMAGE_ID);
if (result == 0) {
result = io_open(ddr_fip_dev_handle, spec, &local_image_handle);
if (result == 0) {
VERBOSE("Using FIP\n");
io_close(local_image_handle);
}
}
return result;
}
/* The image can be one of the DDR PHY images, which can be sleected via DDR
* policies
*/
int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec,
int (*check)(const uintptr_t spec))
{
int result = -1;
const struct plat_io_policy *policy;
if (image_id >= (DDR_FIP_IMAGE_ID + ARRAY_SIZE(ddr_policies))) {
return result;
}
policy = &ddr_policies[image_id - DDR_FIP_IMAGE_ID];
if (image_id == DDR_FIP_IMAGE_ID) {
result = check(policy->image_spec);
} else {
result = policy->check(policy->image_spec);
}
if (result == 0) {
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
}
return result;
}
int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
{
int io_result;
size_t ddr_fip_offset = PLAT_DDR_FIP_OFFSET;
/* Open connections to ddr fip and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)&ddr_fip,
&ddr_fip_dev_handle);
assert(io_result == 0);
switch (boot_dev) {
#if QSPI_BOOT
case BOOT_DEVICE_QSPI:
ddr_fip_offset += NXP_QSPI_FLASH_ADDR;
break;
#endif
#if NOR_BOOT
case BOOT_DEVICE_IFC_NOR:
ddr_fip_offset += NXP_NOR_FLASH_ADDR;
break;
#endif
#if FLEXSPI_NOR_BOOT
case BOOT_DEVICE_FLEXSPI_NOR:
ddr_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
break;
#endif
default:
break;
}
ddr_fip_block_spec.offset = ddr_fip_offset;
return io_result;
}
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef DDR_IO_STORAGE_H
#define DDR_IO_STORAGE_H
#include <drivers/io/io_driver.h>
#ifndef PLAT_DDR_FIP_OFFSET
#define PLAT_DDR_FIP_OFFSET 0x800000
#endif
#ifndef PLAT_DDR_FIP_MAX_SIZE
#define PLAT_DDR_FIP_MAX_SIZE 0x32000
#endif
int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev);
int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
uintptr_t *image_spec,
int (*check)(const uintptr_t spec));
#endif /* DDR_IO_STORAGE_H */
#
# Copyright 2018-2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
NEED_FUSE := yes
$(eval $(call add_define, PLAT_DEF_FIP_UUID))
$(eval $(call add_define, POLICY_FUSE_PROVISION))
$(eval $(call add_define, PLAT_TBBR_IMG_DEF))
$(eval $(call SET_NXP_MAKE_FLAG,IMG_LOADR_NEEDED,BL2))
$(eval $(call SET_NXP_MAKE_FLAG,SFP_NEEDED,BL2))
$(eval $(call SET_NXP_MAKE_FLAG,GPIO_NEEDED,BL2))
FIP_HANDLER_PATH := ${PLAT_COMMON_PATH}/fip_handler
FIP_HANDLER_COMMON_PATH := ${FIP_HANDLER_PATH}/common
FUSE_SOURCES := ${FIP_HANDLER_PATH}/fuse_fip/fuse_io_storage.c
PLAT_INCLUDES += -I${FIP_HANDLER_COMMON_PATH}\
-I${FIP_HANDLER_PATH}/fuse_fip
FUSE_FIP_NAME := fuse_fip.bin
fip_fuse: ${BUILD_PLAT}/${FUSE_FIP_NAME}
ifeq (${FUSE_PROV_FILE},)
$(shell cp tools/nxp/plat_fiptool/plat_fiptool.mk ${PLAT_DIR})
else
ifeq (${TRUSTED_BOARD_BOOT},1)
FUSE_PROV_FILE_SB = $(notdir ${FUSE_PROV_FILE})_prov.sb
FUSE_FIP_ARGS += --fuse-prov ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}
FUSE_FIP_DEPS += ${BUILD_PLAT}/${FUSE_PROV_FILE_SB}
else
FUSE_FIP_ARGS += --fuse-prov ${FUSE_PROV_FILE}
FUSE_FIP_DEPS += ${FUSE_PROV_FILE}
endif
endif
ifeq (${FUSE_UP_FILE},)
else
ifeq (${TRUSTED_BOARD_BOOT},1)
FUSE_UP_FILE_SB = $(notdir ${FUSE_UP_FILE})_up.sb
FUSE_FIP_ARGS += --fuse-up ${BUILD_PLAT}/${FUSE_UP_FILE_SB}
FUSE_FIP_DEPS += ${BUILD_PLAT}/${FUSE_UP_FILE_SB}
else
FUSE_FIP_ARGS += --fuse-up ${FUSE_UP_FILE}
FUSE_FIP_DEPS += ${FUSE_UP_FILE}
endif
endif
ifeq (${TRUSTED_BOARD_BOOT},1)
ifeq (${MBEDTLS_DIR},)
else
$(error Error: Trusted Board Boot with X509 certificates not supported with FUSE_PROG build option)
endif
# Path to CST directory is required to generate the CSF header
# and prepend it to image before fip image gets generated
ifeq (${CST_DIR},)
$(error Error: CST_DIR not set)
endif
ifeq (${FUSE_INPUT_FILE},)
FUSE_INPUT_FILE := $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/${CSF_FILE}
endif
ifeq (${FUSE_PROV_FILE},)
else
${BUILD_PLAT}/${FUSE_PROV_FILE_SB}: ${FUSE_PROV_FILE}
@echo " Generating CSF Header for $@ $<"
$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
--app $< ${FUSE_INPUT_FILE}
endif
ifeq (${FUSE_UP_FILE},)
else
${BUILD_PLAT}/${FUSE_UP_FILE_SB}: ${FUSE_UP_FILE}
@echo " Generating CSF Header for $@ $<"
$(CST_DIR)/create_hdr_esbc --in $< --out $@ --app_off ${CSF_HDR_SZ} \
--app $< ${FUSE_INPUT_FILE}
endif
endif
${BUILD_PLAT}/${FUSE_FIP_NAME}: fiptool ${FUSE_FIP_DEPS}
ifeq (${FUSE_FIP_DEPS},)
$(error "Error: FUSE_PROV_FILE or/and FUSE_UP_FILE needs to point to the right file")
endif
${FIPTOOL} create ${FUSE_FIP_ARGS} $@
${FIPTOOL} info $@
@${ECHO_BLANK_LINE}
@echo "Built $@ successfully"
@${ECHO_BLANK_LINE}
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef FUSE_IO_H
#define FUSE_IO_H
#include <drivers/io/io_driver.h>
/* Can be overridden from platform_def.h file.
*/
#ifndef PLAT_FUSE_FIP_OFFSET
#define PLAT_FUSE_FIP_OFFSET 0x880000
#endif
#ifndef PLAT_FUSE_FIP_MAX_SIZE
#define PLAT_FUSE_FIP_MAX_SIZE 0x80000
#endif
int fip_fuse_provisioning(uintptr_t image_buf, uint32_t size);
int fuse_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev);
int plat_get_fuse_image_source(unsigned int image_id,
uintptr_t *dev_handle,
uintptr_t *image_spec,
int (*check)(const uintptr_t spec));
#endif /* FUSE_IO_H */
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <string.h>
#include <common/debug.h>
#include <dcfg.h>
#include <drivers/delay_timer.h>
#include <fuse_prov.h>
#include <io_block.h>
#include <io_driver.h>
#include <io_fip.h>
#include <io_memmap.h>
#include <io_storage.h>
#include <lib/utils.h>
#include <nxp_gpio.h>
#include <sfp.h>
#include <sfp_error_codes.h>
#include <tools_share/firmware_image_package.h>
#include "fuse_io.h"
#include <load_img.h>
#include <plat/common/platform.h>
#include "plat_common.h"
#include "platform_def.h"
extern uintptr_t backend_dev_handle;
static uint32_t fuse_fip;
static uintptr_t fuse_fip_dev_handle;
static io_block_spec_t fuse_fip_block_spec = {
.offset = PLAT_FUSE_FIP_OFFSET,
.length = PLAT_FUSE_FIP_MAX_SIZE
};
static const io_uuid_spec_t fuse_prov_uuid_spec = {
.uuid = UUID_FUSE_PROV,
};
static const io_uuid_spec_t fuse_up_uuid_spec = {
.uuid = UUID_FUSE_UP,
};
static int open_fuse_fip(const uintptr_t spec);
struct plat_io_policy {
uintptr_t *dev_handle;
uintptr_t image_spec;
int (*check)(const uintptr_t spec);
};
/* By default, ARM platforms load images from the FIP */
static const struct plat_io_policy fuse_policies[] = {
[FUSE_FIP_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
&backend_dev_handle,
(uintptr_t)&fuse_fip_block_spec,
NULL
},
[FUSE_PROV_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
&fuse_fip_dev_handle,
(uintptr_t)&fuse_prov_uuid_spec,
open_fuse_fip
},
[FUSE_UP_IMAGE_ID - FUSE_FIP_IMAGE_ID] = {
&fuse_fip_dev_handle,
(uintptr_t)&fuse_up_uuid_spec,
open_fuse_fip
}
};
static int open_fuse_fip(const uintptr_t spec)
{
int result;
uintptr_t local_image_handle;
/* See if a Firmware Image Package is available */
result = io_dev_init(fuse_fip_dev_handle, (uintptr_t)FUSE_FIP_IMAGE_ID);
if (result == 0) {
result = io_open(fuse_fip_dev_handle,
spec,
&local_image_handle);
if (result == 0) {
VERBOSE("Using FIP\n");
io_close(local_image_handle);
}
}
return result;
}
/* The image can be one of the DDR PHY images, which can be sleected via DDR
* policies
*/
int plat_get_fuse_image_source(unsigned int image_id,
uintptr_t *dev_handle,
uintptr_t *image_spec,
int (*check)(const uintptr_t spec))
{
int result;
const struct plat_io_policy *policy;
assert(image_id < (FUSE_FIP_IMAGE_ID + ARRAY_SIZE(fuse_policies)));
policy = &fuse_policies[image_id - FUSE_FIP_IMAGE_ID];
if (image_id == FUSE_FIP_IMAGE_ID) {
result = check(policy->image_spec);
} else {
result = policy->check(policy->image_spec);
}
if (result == 0) {
*image_spec = policy->image_spec;
*dev_handle = *(policy->dev_handle);
}
return result;
}
int fuse_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
{
int io_result;
size_t fuse_fip_offset = PLAT_FUSE_FIP_OFFSET;
/* Open connections to fuse fip and cache the handles */
io_result = io_dev_open(fip_dev_con, (uintptr_t)&fuse_fip,
&fuse_fip_dev_handle);
assert(io_result == 0);
switch (boot_dev) {
#if QSPI_BOOT
case BOOT_DEVICE_QSPI:
fuse_fip_offset += NXP_QSPI_FLASH_ADDR;
break;
#endif
#if NOR_BOOT
case BOOT_DEVICE_IFC_NOR:
fuse_fip_offset += NXP_NOR_FLASH_ADDR;
break;
#endif
#if FLEXSPI_NOR_BOOT
case BOOT_DEVICE_FLEXSPI_NOR:
fuse_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
break;
#endif
default:
break;
}
fuse_fip_block_spec.offset = fuse_fip_offset;
return io_result;
}
int fip_fuse_provisioning(uintptr_t image_buf, uint32_t size)
{
uint32_t bit_num;
uint32_t *gpio_base_addr = NULL;
struct fuse_hdr_t *fuse_hdr = NULL;
uint8_t barker[] = {0x68U, 0x39U, 0x27U, 0x81U};
int ret = -1;
if (sfp_check_oem_wp() == 0) {
ret = load_img(FUSE_PROV_IMAGE_ID, &image_buf, &size);
if (ret != 0) {
ERROR("Failed to load FUSE PRIV image\n");
assert(ret == 0);
}
fuse_hdr = (struct fuse_hdr_t *)image_buf;
/* Check barker code */
if (memcmp(fuse_hdr->barker, barker, sizeof(barker)) != 0) {
ERROR("FUSE Barker code mismatch.\n");
error_handler(ERROR_FUSE_BARKER);
return 1;
}
/* Check if GPIO pin to be set for POVDD */
if (((fuse_hdr->flags >> FLAG_POVDD_SHIFT) & 0x1) != 0) {
gpio_base_addr =
select_gpio_n_bitnum(fuse_hdr->povdd_gpio,
&bit_num);
/*
* Add delay so that Efuse gets the power
* when GPIO is enabled.
*/
ret = set_gpio_bit(gpio_base_addr, bit_num);
mdelay(EFUSE_POWERUP_DELAY_mSec);
} else {
ret = (board_enable_povdd() == true) ? 0 : PLAT_ERROR_ENABLE_POVDD;
}
if (ret != 0) {
ERROR("Error enabling board POVDD: %d\n", ret);
ERROR("Only SFP mirror register will be set.\n");
}
provision_fuses(image_buf, ret == 0);
/* Check if GPIO pin to be reset for POVDD */
if (((fuse_hdr->flags >> FLAG_POVDD_SHIFT) & 0x1) != 0) {
if (gpio_base_addr == NULL) {
gpio_base_addr =
select_gpio_n_bitnum(
fuse_hdr->povdd_gpio,
&bit_num);
}
ret = clr_gpio_bit(gpio_base_addr, bit_num);
} else {
ret = board_disable_povdd() ? 0 : PLAT_ERROR_DISABLE_POVDD;
}
if (ret != 0) {
ERROR("Error disabling board POVDD: %d\n", ret);
}
}
return 0;
}
#
# Copyright 2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
IMG_LOADR_DRIVERS_PATH := ${PLAT_COMMON_PATH}/img_loadr
IMG_LOADR_SOURCES := $(IMG_LOADR_DRIVERS_PATH)/load_img.c
PLAT_INCLUDES += -I$(IMG_LOADR_DRIVERS_PATH)
ifeq (${BL_COMM_IMG_LOADR_NEEDED},yes)
BL_COMMON_SOURCES += ${IMG_LOADR_SOURCES}
else
ifeq (${BL2_IMG_LOADR_NEEDED},yes)
BL2_SOURCES += ${IMG_LOADR_SOURCES}
endif
ifeq (${BL31_IMG_LOADR_NEEDED},yes)
BL31_SOURCES += ${IMG_LOADR_SOURCES}
endif
endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment