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
/*
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stddef.h>
#include <drivers/auth/auth_mod.h>
#if USE_TBBR_DEFS
#include <tools_share/tbbr_oid.h>
#else
#include <platform_oid.h>
#endif
static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_SIG, 0);
static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_SIG_ALG, 0);
static auth_param_type_desc_t sig_hash = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_HASH, 0);
static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
/*
* TBBR Chain of trust definition
*/
static const auth_img_desc_t bl31_image = {
.img_id = BL31_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t scp_bl2_image = {
.img_id = SCP_BL2_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t bl32_image = {
.img_id = BL32_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t bl33_image = {
.img_id = BL33_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
#ifdef POLICY_FUSE_PROVISION
static const auth_img_desc_t fuse_prov_img = {
.img_id = FUSE_PROV_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t fuse_upgrade_img = {
.img_id = FUSE_UP_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
#endif
#ifdef CONFIG_DDR_FIP_IMAGE
static const auth_img_desc_t ddr_imem_udimm_1d_img = {
.img_id = DDR_IMEM_UDIMM_1D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_imem_udimm_2d_img = {
.img_id = DDR_IMEM_UDIMM_2D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_dmem_udimm_1d_img = {
.img_id = DDR_DMEM_UDIMM_1D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_dmem_udimm_2d_img = {
.img_id = DDR_DMEM_UDIMM_2D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_imem_rdimm_1d_img = {
.img_id = DDR_IMEM_RDIMM_1D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_imem_rdimm_2d_img = {
.img_id = DDR_IMEM_RDIMM_2D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_dmem_rdimm_1d_img = {
.img_id = DDR_DMEM_RDIMM_1D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
static const auth_img_desc_t ddr_dmem_rdimm_2d_img = {
.img_id = DDR_DMEM_RDIMM_2D_IMAGE_ID,
.img_type = IMG_PLAT,
.parent = NULL,
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
[0] = {
.type = AUTH_METHOD_SIG,
.param.sig = {
.pk = &non_trusted_world_pk,
.sig = &sig,
.alg = &sig_alg,
.data = &sig_hash
}
}
}
};
#endif
static const auth_img_desc_t * const cot_desc[] = {
[BL31_IMAGE_ID] = &bl31_image,
[SCP_BL2_IMAGE_ID] = &scp_bl2_image,
[BL32_IMAGE_ID] = &bl32_image,
[BL33_IMAGE_ID] = &bl33_image,
#ifdef POLICY_FUSE_PROVISION
[FUSE_PROV_IMAGE_ID] = &fuse_prov_img,
[FUSE_UP_IMAGE_ID] = &fuse_upgrade_img,
#endif
#ifdef CONFIG_DDR_FIP_IMAGE
[DDR_IMEM_UDIMM_1D_IMAGE_ID] = &ddr_imem_udimm_1d_img,
[DDR_IMEM_UDIMM_2D_IMAGE_ID] = &ddr_imem_udimm_2d_img,
[DDR_DMEM_UDIMM_1D_IMAGE_ID] = &ddr_dmem_udimm_1d_img,
[DDR_DMEM_UDIMM_2D_IMAGE_ID] = &ddr_dmem_udimm_2d_img,
[DDR_IMEM_RDIMM_1D_IMAGE_ID] = &ddr_imem_rdimm_1d_img,
[DDR_IMEM_RDIMM_2D_IMAGE_ID] = &ddr_imem_rdimm_2d_img,
[DDR_DMEM_RDIMM_1D_IMAGE_ID] = &ddr_dmem_rdimm_1d_img,
[DDR_DMEM_RDIMM_2D_IMAGE_ID] = &ddr_dmem_rdimm_2d_img,
#endif
};
/* Register the CoT in the authentication module */
REGISTER_COT(cot_desc);
/*
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef CSF_HDR_H
#define CSF_HDR_H
#include "caam.h"
#include "hash.h"
#include "rsa.h"
/* Barker code size in bytes */
#define CSF_BARKER_LEN 4 /* barker code length in ESBC uboot client */
/* header */
#ifdef CSF_HDR_CH3
struct csf_hdr {
uint8_t barker[CSF_BARKER_LEN]; /* 0x00 Barker code */
uint32_t srk_tbl_off; /* 0x04 SRK Table Offset */
struct {
uint8_t num_srk; /* 0x08 No. of keys */
uint8_t srk_sel; /* Key no. to be used */
uint8_t reserve; /* 0x0a rseerved */
} len_kr;
uint8_t ie_flag;
uint32_t uid_flag;
uint32_t psign; /* 0x10 signature offset */
uint32_t sign_len; /* 0x14 length of signature */
union {
struct {
uint32_t sg_table_offset; /* 0x18 SG Table Offset */
uint32_t sg_entries; /* 0x1c no of entries in SG */
} sg_isbc;
uint64_t img_addr; /* 64 bit pointer to ESBC Image */
};
union {
struct {
uint32_t img_size; /* ESBC client img size in bytes */
uint32_t ie_key_sel;
} img;
uint64_t entry_point; /* 0x20-0x24 ESBC entry point */
};
uint32_t fsl_uid_0; /* 0x28 Freescale unique id 0 */
uint32_t fsl_uid_1; /* 0x2c Freescale unique id 1 */
uint32_t oem_uid_0; /* 0x30 OEM unique id 0 */
uint32_t oem_uid_1; /* 0x34 OEM unique id 1 */
uint32_t oem_uid_2; /* 0x38 OEM unique id 2 */
uint32_t oem_uid_3; /* 0x3c OEM unique id 3 */
uint32_t oem_uid_4; /* 0x40 OEM unique id 4 */
uint32_t reserved[3]; /* 0x44 - 0x4f */
};
/* Srk table and key revocation check */
#define UNREVOCABLE_KEY 8
#define REVOC_KEY_ALIGN 7
#define MAX_KEY_ENTRIES 8
#else
/* CSF header for Chassis 2 */
struct csf_hdr {
uint8_t barker[CSF_BARKER_LEN]; /* barker code */
union {
uint32_t pkey; /* public key offset */
uint32_t srk_tbl_off;
};
union {
uint32_t key_len; /* pub key length in bytes */
struct {
uint32_t srk_table_flag:8;
uint32_t srk_sel:8;
uint32_t num_srk:16;
} len_kr;
};
uint32_t psign; /* signature offset */
uint32_t sign_len; /* length of the signature in bytes */
/* SG Table used by ISBC header */
union {
struct {
uint32_t sg_table_offset; /* 0x14 SG Table Offset */
uint32_t sg_entries; /* no of entries in SG table */
} sg_isbc;
struct {
uint32_t reserved1; /* Reserved field */
uint32_t img_size; /* ESBC img size in bytes */
} img;
};
uint32_t entry_point; /* ESBC client entry point */
uint32_t reserved2; /* Scatter gather flag */
uint32_t uid_flag;
uint32_t fsl_uid_0;
uint32_t oem_uid_0;
uint32_t reserved3[2];
uint32_t fsl_uid_1;
uint32_t oem_uid_1;
/* The entries below aren't present in ISBC header */
uint64_t img_addr; /* 64 bit pointer to ESBC Image */
uint32_t ie_flag;
uint32_t ie_key_sel;
};
/* Srk table and key revocation check */
#define UNREVOCABLE_KEY 4
#define REVOC_KEY_ALIGN 3
#define MAX_KEY_ENTRIES 4
#endif
struct srk_table {
uint32_t key_len;
uint8_t pkey[2 * RSA_4K_KEY_SZ_BYTES];
};
/*
* This struct contains the following fields
* length of the segment
* Destination Target ID
* source address
* destination address
*/
struct sg_table {
uint32_t len; /* Length of Image */
uint32_t res1;
union {
uint64_t src_addr; /* SRC Address of Image */
struct {
uint32_t src_addr;
uint32_t dst_addr;
} img;
};
};
int validate_esbc_header(void *img_hdr, void **img_key, uint32_t *key_len,
void **img_sign, uint32_t *sign_len,
enum sig_alg *algo);
int calc_img_hash(struct csf_hdr *hdr, void *img_addr, uint32_t img_size,
uint8_t *img_hash, uint32_t *hash_len);
#endif
#
# Copyright 2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
CSF_HDR_SOURCES := $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/csf_hdr_parser.c
CSF_HDR_SOURCES += $(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/plat_img_parser.c
PLAT_INCLUDES += -I$(PLAT_DRIVERS_PATH)/auth/csf_hdr_parser/
$(eval $(call add_define, CSF_HEADER_PREPENDED))
# 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
# Rules are created for generating and appending CSF header to images before
# FIT image generation
# CST_BL31
define CST_BL31_RULE
$(1): $(2)
@echo " Generating CSF Header for $$@ $$<"
$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
--app $(2) ${BL31_INPUT_FILE}
endef
CST_BL31_SUFFIX := .cst
# CST_BL32
define CST_BL32_RULE
$(1): $(2)
@echo " Generating CSF Header for $$@ $$<"
$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
--app $(2) ${BL32_INPUT_FILE}
endef
CST_BL32_SUFFIX := .cst
# CST_BL33
define CST_BL33_RULE
$(1): $(2)
@echo " Generating CSF Header for $$@ $$<"
$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
--app $(2) ${BL33_INPUT_FILE}
endef
CST_BL33_SUFFIX := .cst
# CST_SCP_BL2
define CST_SCP_BL2_RULE
$(1): $(2)
@echo " Generating CSF Header for $$@ $$<"
$(Q)$(CST_DIR)/create_hdr_esbc --in $(2) --out $(1) --app_off ${CSF_HDR_SZ} \
--app $(2) ${FUSE_INPUT_FILE}
endef
CST_SCP_BL2_SUFFIX := .cst
/*
* Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
* Copyright 2017-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <arch_helpers.h>
#include <cassert.h>
#include <common/debug.h>
#include <csf_hdr.h>
#include <dcfg.h>
#include <drivers/auth/crypto_mod.h>
#include <lib/utils.h>
#include <sfp.h>
/* Maximum OID string length ("a.b.c.d.e.f ...") */
#define MAX_OID_STR_LEN 64
#define LIB_NAME "NXP CSFv2"
#ifdef CSF_HDR_CH3
/* Barker Code for LS Ch3 ESBC Header */
static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
#else
static const uint8_t barker_code[CSF_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
#endif
#define CHECK_KEY_LEN(key_len) (((key_len) == 2 * RSA_1K_KEY_SZ_BYTES) || \
((key_len) == 2 * RSA_2K_KEY_SZ_BYTES) || \
((key_len) == 2 * RSA_4K_KEY_SZ_BYTES))
/* Flag to indicate if values are there in rotpk_hash_table */
bool rotpk_not_dpld = true;
uint8_t rotpk_hash_table[MAX_KEY_ENTRIES][SHA256_BYTES];
uint32_t num_rotpk_hash_entries;
/*
* This function deploys the hashes of the various platform keys in
* rotpk_hash_table. This is done in case of secure boot after comparison
* of table's hash with the hash in SFP fuses. This installation is done
* only in the first header parsing.
*/
static int deploy_rotpk_hash_table(void *srk_buffer, uint16_t num_srk)
{
void *ctx;
int ret = 0;
int i, j = 0;
unsigned int digest_size = SHA256_BYTES;
enum hash_algo algo = SHA256;
uint8_t hash[SHA256_BYTES];
uint32_t srk_hash[SHA256_BYTES/4] __aligned(CACHE_WRITEBACK_GRANULE);
struct srk_table *srktbl = (void *)srk_buffer;
struct sfp_ccsr_regs_t *sfp_ccsr_regs = (void *)(get_sfp_addr()
+ SFP_FUSE_REGS_OFFSET);
if (num_srk > MAX_KEY_ENTRIES) {
return -1;
}
ret = hash_init(algo, &ctx);
if (ret != 0) {
return -1;
}
/* Update hash with that of SRK table */
ret = hash_update(algo, ctx, (uint8_t *)((uint8_t *)srk_buffer),
num_srk * sizeof(struct srk_table));
if (ret != 0) {
return -1;
}
/* Copy hash at destination buffer */
ret = hash_final(algo, ctx, hash, digest_size);
if (ret != 0) {
return -1;
}
/* Add comparison of hash with SFP hash here */
for (i = 0; i < SHA256_BYTES/4; i++) {
srk_hash[i] =
mmio_read_32((uintptr_t)&sfp_ccsr_regs->srk_hash[i]);
}
VERBOSE("SRK table HASH\n");
for (i = 0; i < 8; i++) {
VERBOSE("%x\n", *((uint32_t *)hash + i));
}
if (memcmp(hash, srk_hash, SHA256_BYTES) != 0) {
ERROR("Error in installing ROTPK table\n");
ERROR("SRK hash doesn't match the fuse hash\n");
return -1;
}
/* Hash table already deployed */
if (rotpk_not_dpld == false) {
return 0;
}
for (i = 0; i < num_srk; i++) {
ret = hash_init(algo, &ctx);
if (ret != 0) {
return -1;
}
/* Update hash with that of SRK table */
ret = hash_update(algo, ctx, srktbl[i].pkey, srktbl[i].key_len);
if (ret != 0) {
return -1;
}
/* Copy hash at destination buffer */
ret = hash_final(algo, ctx, rotpk_hash_table[i], digest_size);
if (ret != 0) {
return -1;
}
VERBOSE("Table key %d HASH\n", i);
for (j = 0; j < 8; j++) {
VERBOSE("%x\n", *((uint32_t *)rotpk_hash_table[i] + j));
}
}
rotpk_not_dpld = false;
num_rotpk_hash_entries = num_srk;
return 0;
}
/*
* Calculate hash of ESBC hdr and ESBC. This function calculates the
* single hash of ESBC header and ESBC image
*/
int calc_img_hash(struct csf_hdr *hdr,
void *img_addr, uint32_t img_size,
uint8_t *img_hash, uint32_t *hash_len)
{
void *ctx;
int ret = 0;
unsigned int digest_size = SHA256_BYTES;
enum hash_algo algo = SHA256;
ret = hash_init(algo, &ctx);
/* Copy hash at destination buffer */
if (ret != 0) {
return -1;
}
/* Update hash for CSF Header */
ret = hash_update(algo, ctx, (uint8_t *)hdr, sizeof(struct csf_hdr));
if (ret != 0) {
return -1;
}
/* Update hash with that of SRK table */
ret = hash_update(algo, ctx,
(uint8_t *)((uint8_t *)hdr + hdr->srk_tbl_off),
hdr->len_kr.num_srk * sizeof(struct srk_table));
if (ret != 0) {
return -1;
}
/* Update hash for actual Image */
ret = hash_update(algo, ctx, (uint8_t *)(img_addr), img_size);
if (ret != 0) {
return -1;
}
/* Copy hash at destination buffer */
ret = hash_final(algo, ctx, img_hash, digest_size);
if (ret != 0) {
return -1;
}
*hash_len = digest_size;
VERBOSE("IMG encoded HASH\n");
for (int i = 0; i < 8; i++) {
VERBOSE("%x\n", *((uint32_t *)img_hash + i));
}
return 0;
}
/* This function checks if selected key is revoked or not.*/
static uint32_t is_key_revoked(uint32_t keynum, uint32_t rev_flag)
{
if (keynum == UNREVOCABLE_KEY) {
return 0;
}
if (((uint32_t)(1 << (REVOC_KEY_ALIGN - keynum)) & rev_flag) != 0) {
return 1;
}
return 0;
}
/* Parse the header to extract the type of key,
* Check if key is not revoked
* and return the key , key length and key_type
*/
static int32_t get_key(struct csf_hdr *hdr, uint8_t **key, uint32_t *len,
enum sig_alg *key_type)
{
int i = 0;
uint32_t ret = 0U;
uint32_t key_num, key_revoc_flag;
void *esbc = hdr;
struct srk_table *srktbl = (void *)((uint8_t *)esbc + hdr->srk_tbl_off);
bool sb;
uint32_t mode;
/* We currently support only RSA keys and signature */
*key_type = RSA;
/* Check for number of SRK entries */
if ((hdr->len_kr.num_srk == 0) ||
(hdr->len_kr.num_srk > MAX_KEY_ENTRIES)) {
ERROR("Error in NUM entries in SRK Table\n");
return -1;
}
/*
* Check the key number field. It should be not greater than
* number of entries in SRK table.
*/
key_num = hdr->len_kr.srk_sel;
if ((key_num == 0) || (key_num > hdr->len_kr.num_srk)) {
ERROR("Invalid Key number\n");
return -1;
}
/* Get revoc key from sfp */
key_revoc_flag = get_key_revoc();
/* Check if selected key has been revoked */
ret = is_key_revoked(key_num, key_revoc_flag);
if (ret != 0) {
ERROR("Selected key has been revoked\n");
return -1;
}
/* Check for valid key length - allowed key sized 1k, 2k and 4K */
for (i = 0; i < hdr->len_kr.num_srk; i++) {
if (CHECK_KEY_LEN(srktbl[i].key_len) == 0) {
ERROR("Invalid key length\n");
return -1;
}
}
/* We don't return error from here. While parsing we just try to
* install the srk table. Failure needs to be taken care of in
* case of secure boot. This failure will be handled at the time
* of rotpk comparison in plat_get_rotpk_info function
*/
sb = check_boot_mode_secure(&mode);
if (sb) {
ret = deploy_rotpk_hash_table(srktbl, hdr->len_kr.num_srk);
if (ret != 0) {
ERROR("ROTPK FAILURE\n");
/* For ITS =1 , return failure */
if (mode != 0) {
return -1;
}
ERROR("SECURE BOOT DEV-ENV MODE:\n");
ERROR("\tCHECK ROTPK !\n");
ERROR("\tCONTINUING ON FAILURE...\n");
}
}
/* Return the length of the selected key */
*len = srktbl[key_num - 1].key_len;
/* Point key to the selected key */
*key = (uint8_t *)&(srktbl[key_num - 1].pkey);
return 0;
}
/*
* This function would parse the CSF header and do the following:
* 1. Basic integrity checks
* 2. Key checks and extract the key from SRK/IE Table
* 3. Key hash comparison with SRKH in fuses in case of SRK Table
* 4. OEM/UID checks - To be added
* 5. Hash calculation for various components used in signature
* 6. Signature integrity checks
* return -> 0 on success, -1 on failure
*/
int validate_esbc_header(void *img_hdr, void **img_key, uint32_t *key_len,
void **img_sign, uint32_t *sign_len,
enum sig_alg *algo)
{
struct csf_hdr *hdr = img_hdr;
uint8_t *s;
int32_t ret = 0;
void *esbc = (uint8_t *)img_hdr;
uint8_t *key;
uint32_t klen;
/* check barker code */
if (memcmp(hdr->barker, barker_code, CSF_BARKER_LEN) != 0) {
ERROR("Wrong barker code in header\n");
return -1;
}
ret = get_key(hdr, &key, &klen, algo);
if (ret != 0) {
return -1;
}
/* check signaure */
if (klen == (2 * hdr->sign_len)) {
/* check signature length */
if (((hdr->sign_len == RSA_1K_KEY_SZ_BYTES) ||
(hdr->sign_len == RSA_2K_KEY_SZ_BYTES) ||
(hdr->sign_len == RSA_4K_KEY_SZ_BYTES)) == 0) {
ERROR("Wrong Signature length in header\n");
return -1;
}
} else {
ERROR("RSA key length not twice the signature length\n");
return -1;
}
/* modulus most significant bit should be set */
if ((key[0] & 0x80) == 0U) {
ERROR("RSA Public key MSB not set\n");
return -1;
}
/* modulus value should be odd */
if ((key[klen / 2 - 1] & 0x1) == 0U) {
ERROR("Public key Modulus in header not odd\n");
return -1;
}
/* Check signature value < modulus value */
s = (uint8_t *)(esbc + hdr->psign);
if (!(memcmp(s, key, hdr->sign_len) < 0)) {
ERROR("Signature not less than modulus");
return -1;
}
/* Populate the return addresses */
*img_sign = (void *)(s);
/* Save the length of signature */
*sign_len = hdr->sign_len;
*img_key = (uint8_t *)key;
*key_len = klen;
return ret;
}
/*
* Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform - 1010/1040/2041/3041/4080/5020/5040/9131/9132/9164/4240/C290/LS1
PLATFORM=LS1043
# ESBC Flag. Specify ESBC=0 to sign u-boot and ESBC=1 to sign ESBC images.(default is 0)
ESBC=0
---------------------------------------------------
# Entry Point/Image start address field in the header.[Mandatory]
# (default=ADDRESS of first file specified in images)
ENTRY_POINT=10000000
---------------------------------------------------
# Specify the file name of the keys separated by comma.
# The number of files and key select should lie between 1 and 4 for 1040 and C290.
# For rest of the platforms only one key is required and key select should not be provided.
# USAGE (for 4080/5020/5040/3041/2041/1010/913x): PRI_KEY = <key1.pri>
# USAGE (for 1040/C290/9164/4240/LS1): PRI_KEY = <key1.pri>, <key2.pri>, <key3.pri>, <key4.pri>
# PRI_KEY (Default private key :srk.pri) - [Optional]
PRI_KEY=srk.pri
# PUB_KEY (Default public key :srk.pub) - [Optional]
PUB_KEY=srk.pub
# Please provide KEY_SELECT(between 1 to 4) (Required for 1040/C290/9164/4240/LS1 only) - [Optional]
KEY_SELECT=
---------------------------------------------------
# Specify SG table address, only for (2041/3041/4080/5020/5040) with ESBC=0 - [Optional]
SG_TABLE_ADDR=
---------------------------------------------------
# Specify the target where image will be loaded. (Default is NOR_16B) - [Optional]
# Only required for Non-PBL Devices (1010/1040/9131/9132i/C290)
# Select from - NOR_8B/NOR_16B/NAND_8B_512/NAND_8B_2K/NAND_8B_4K/NAND_16B_512/NAND_16B_2K/NAND_16B_4K/SD/MMC/SPI
IMAGE_TARGET=
---------------------------------------------------
# Specify IMAGE, Max 8 images are possible. DST_ADDR is required only for Non-PBL Platform. [Mandatory]
# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR}
IMAGE_1={bl2.bin,10000000,ffffffff}
IMAGE_2={,,}
IMAGE_3={,,}
IMAGE_4={,,}
IMAGE_5={,,}
IMAGE_6={,,}
IMAGE_7={,,}
IMAGE_8={,,}
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
---------------------------------------------------
# Specify the file names of csf header and sg table. (Default :hdr.out) [Optional]
OUTPUT_HDR_FILENAME=hdr_bl2.out
# Specify the file names of hash file and sign file.
HASH_FILENAME=img_hash.out
INPUT_SIGN_FILENAME=sign.out
# Specify the signature size.It is mandatory when neither public key nor private key is specified.
# Signature size would be [0x80 for 1k key, 0x100 for 2k key, and 0x200 for 4k key].
SIGN_SIZE=
---------------------------------------------------
# Specify the output file name of sg table. (Default :sg_table.out). [Optional]
# Please note that OUTPUT SG BIN is only required for 2041/3041/4080/5020/5040 when ESBC flag is not set.
OUTPUT_SG_BIN=
---------------------------------------------------
# Following fields are Required for 4240/9164/1040/C290 only
# Specify House keeping Area
# Required for 4240/9164/1040/C290 only when ESBC flag is not set. [Mandatory]
HK_AREA_POINTER=
HK_AREA_SIZE=
---------------------------------------------------
# Following field Required for 4240/9164/1040/C290 only
# Specify Secondary Image Flag. (0 or 1) - [Optional]
# (Default is 0)
SEC_IMAGE=0
# Specify Manufacturing Protection Flag. (0 or 1) - [Optional]
# Required only for LS1(Default is 0)
MP_FLAG=1
---------------------------------------------------
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform -
# TRUST 3.2: LX2160
PLATFORM=LS2088
---------------------------------------------------
# Entry Point/Image start address field in the header.[Mandatory]
# (default=ADDRESS of first file specified in images)
# Address can be 64 bit
ENTRY_POINT=1800A000
---------------------------------------------------
# Specify the Key Information.
# PUB_KEY [Mandatory] Comma Separated List
# Usage: <srk1.pub> <srk2.pub> .....
PUB_KEY=srk.pub
# KEY_SELECT [Mandatory]
# USAGE (for TRUST 3.x): (between 1 to 8)
KEY_SELECT=1
# PRI_KEY [Mandatory] Single Key Used for Signing
# USAGE: <srk.pri>
PRI_KEY=srk.pri
---------------------------------------------------
# Specify IMAGE, Max 8 images are possible.
# DST_ADDR is required only for Non-PBL Platform. [Mandatory]
# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR}
# Address can be 64 bit
IMAGE_1={bl2.bin,1800A000,ffffffff}
IMAGE_2={,,}
IMAGE_3={,,}
IMAGE_4={,,}
IMAGE_5={,,}
IMAGE_6={,,}
IMAGE_7={,,}
IMAGE_8={,,}
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID_0=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
OEM_UID_2=
OEM_UID_3=
OEM_UID_4=
---------------------------------------------------
# Specify the output file names [Optional].
# Default Values chosen in Tool
OUTPUT_HDR_FILENAME=hdr_bl2.out
IMAGE_HASH_FILENAME=
RSA_SIGN_FILENAME=
---------------------------------------------------
# Specify The Flags. (0 or 1) - [Optional]
MP_FLAG=0
ISS_FLAG=1
LW_FLAG=0
---------------------------------------------------
# Specify VERBOSE as 1, if you want to Display Header Information [Optional]
VERBOSE=1
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform -
# TRUST 3.2: LX2160
PLATFORM=LX2160
---------------------------------------------------
# Entry Point/Image start address field in the header.[Mandatory]
# (default=ADDRESS of first file specified in images)
# Address can be 64 bit
ENTRY_POINT=1800D000
---------------------------------------------------
# Specify the Key Information.
# PUB_KEY [Mandatory] Comma Separated List
# Usage: <srk1.pub> <srk2.pub> .....
PUB_KEY=srk.pub
# KEY_SELECT [Mandatory]
# USAGE (for TRUST 3.x): (between 1 to 8)
KEY_SELECT=1
# PRI_KEY [Mandatory] Single Key Used for Signing
# USAGE: <srk.pri>
PRI_KEY=srk.pri
---------------------------------------------------
# Specify IMAGE, Max 8 images are possible.
# DST_ADDR is required only for Non-PBL Platform. [Mandatory]
# USAGE : IMAGE_NO = {IMAGE_NAME, SRC_ADDR, DST_ADDR}
# Address can be 64 bit
IMAGE_1={bl2.bin,1800D000,ffffffff}
IMAGE_2={,,}
IMAGE_3={,,}
IMAGE_4={,,}
IMAGE_5={,,}
IMAGE_6={,,}
IMAGE_7={,,}
IMAGE_8={,,}
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID_0=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
OEM_UID_2=
OEM_UID_3=
OEM_UID_4=
---------------------------------------------------
# Specify the output file names [Optional].
# Default Values chosen in Tool
OUTPUT_HDR_FILENAME=hdr_bl2.out
IMAGE_HASH_FILENAME=
RSA_SIGN_FILENAME=
---------------------------------------------------
# Specify The Flags. (0 or 1) - [Optional]
MP_FLAG=0
ISS_FLAG=1
LW_FLAG=0
---------------------------------------------------
# Specify VERBOSE as 1, if you want to Display Header Information [Optional]
VERBOSE=1
/*
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform - 1010/1040/2041/3041/4080/5020/5040/9131/9132/9164/4240/C290/LS1
PLATFORM=LS1043
# ESBC Flag. Specify ESBC=0 to sign u-boot and ESBC=1 to sign ESBC images.(default is 0)
ESBC=1
---------------------------------------------------
# Specify the file name of the keys separated by comma.
# PRI_KEY (Default private key :srk.pri) - [Optional]
PRI_KEY=srk.pri
# PUB_KEY (Default public key :srk.pub) - [Optional]
PUB_KEY=srk.pub
# Please provide KEY_SELECT(between 1 to 4) (Required for 1040/C290/9164/4240 only) - [Optional]
KEY_SELECT=1
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
---------------------------------------------------
/*
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
ESBC=1
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform -
# TRUST 3.0: LS2085
# TRUST 3.1: LS2088, LS1088
PLATFORM=LS2088
---------------------------------------------------
# Specify the Key Information.
# PUB_KEY [Mandatory] Comma Separated List
# Usage: <srk1.pub> <srk2.pub> .....
PUB_KEY=srk.pub
# KEY_SELECT [Mandatory]
# USAGE (for TRUST 3.x): (between 1 to 8)
KEY_SELECT=1
# PRI_KEY [Mandatory] Single Key Used for Signing
# USAGE: <srk.pri>
PRI_KEY=srk.pri
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID_0=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
OEM_UID_2=
OEM_UID_3=
OEM_UID_4=
---------------------------------------------------
/*
* Copyright 2016-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform -
# TRUST 3.0: LS2085
# TRUST 3.1: LS2088, LS1088
PLATFORM=LS2088
---------------------------------------------------
# Specify the Key Information.
# PUB_KEY [Mandatory] Comma Separated List
# Usage: <srk1.pub> <srk2.pub> .....
PUB_KEY=srk.pub
# KEY_SELECT [Mandatory]
# USAGE (for TRUST 3.x): (between 1 to 8)
KEY_SELECT=1
# PRI_KEY [Mandatory] Single Key Used for Signing
# USAGE: <srk.pri>
PRI_KEY=srk.pri
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID_0=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
OEM_UID_2=
OEM_UID_3=
OEM_UID_4=
---------------------------------------------------
# Specify The Flags. (0 or 1) - [Optional]
MP_FLAG=0
ISS_FLAG=1
LW_FLAG=0
---------------------------------------------------
# Specify VERBOSE as 1, if you want to Display Header Information [Optional]
VERBOSE=1
---------------------------------------------------
/*
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
---------------------------------------------------
# Specify the platform. [Mandatory]
# Choose Platform -
# TRUST 3.0: LS2085
# TRUST 3.1: LS2088, LS1088
PLATFORM=LX2160
---------------------------------------------------
# Specify the Key Information.
# PUB_KEY [Mandatory] Comma Separated List
# Usage: <srk1.pub> <srk2.pub> .....
PUB_KEY=srk.pub
# KEY_SELECT [Mandatory]
# USAGE (for TRUST 3.x): (between 1 to 8)
KEY_SELECT=1
# PRI_KEY [Mandatory] Single Key Used for Signing
# USAGE: <srk.pri>
PRI_KEY=srk.pri
---------------------------------------------------
# Specify OEM AND FSL ID to be populated in header. [Optional]
# e.g FSL_UID_0=11111111
FSL_UID_0=
FSL_UID_1=
OEM_UID_0=
OEM_UID_1=
OEM_UID_2=
OEM_UID_3=
OEM_UID_4=
---------------------------------------------------
# Specify The Flags. (0 or 1) - [Optional]
MP_FLAG=0
ISS_FLAG=1
LW_FLAG=0
---------------------------------------------------
# Specify VERBOSE as 1, if you want to Display Header Information [Optional]
VERBOSE=1
---------------------------------------------------
/*
* Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
* Copyright 2017-2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <arch_helpers.h>
#include <common/debug.h>
#include <csf_hdr.h>
#include <drivers/auth/crypto_mod.h>
#include <drivers/auth/img_parser_mod.h>
#include <lib/utils.h>
#include <sfp.h>
/* Temporary variables to speed up the authentication parameters search. These
* variables are assigned once during the integrity check and used any time an
* authentication parameter is requested, so we do not have to parse the image
* again.
*/
/* Hash of Image + CSF Header + SRK table */
uint8_t img_hash[SHA256_BYTES] __aligned(CACHE_WRITEBACK_GRANULE);
uint32_t hash_len;
/* Key being used for authentication
* Points to the key in CSF header copied in DDR
* ESBC client key
*/
void *img_key;
uint32_t key_len;
/* ESBC client signature */
void *img_sign;
uint32_t sign_len;
enum sig_alg alg;
/* Maximum OID string length ("a.b.c.d.e.f ...") */
#define MAX_OID_STR_LEN 64
#define LIB_NAME "NXP CSFv2"
/*
* Clear all static temporary variables.
*/
static void clear_temp_vars(void)
{
#define ZERO_AND_CLEAN(x) \
do { \
zeromem(&x, sizeof(x)); \
clean_dcache_range((uintptr_t)&x, sizeof(x)); \
} while (0)
ZERO_AND_CLEAN(img_key);
ZERO_AND_CLEAN(img_sign);
ZERO_AND_CLEAN(img_hash);
ZERO_AND_CLEAN(key_len);
ZERO_AND_CLEAN(hash_len);
ZERO_AND_CLEAN(sign_len);
#undef ZERO_AND_CLEAN
}
/* Exported functions */
static void init(void)
{
clear_temp_vars();
}
/*
* This function would check the integrity of the CSF header
*/
static int check_integrity(void *img, unsigned int img_len)
{
int ret;
/*
* The image file has been successfully loaded till here.
*
* Flush the image to main memory so that it can be authenticated
* by CAAM, a HW accelerator regardless of cache and MMU state.
*/
flush_dcache_range((uintptr_t) img, img_len);
/*
* Image is appended at an offset of 16K (IMG_OFFSET) to the header.
* So the size in header should be equal to img_len - IMG_OFFSET
*/
VERBOSE("Barker code is %x\n", *(unsigned int *)img);
ret = validate_esbc_header(img, &img_key, &key_len, &img_sign,
&sign_len, &alg);
if (ret < 0) {
ERROR("Header authentication failed\n");
clear_temp_vars();
return IMG_PARSER_ERR;
}
/* Calculate the hash of various components from the image */
ret = calc_img_hash(img, (uint8_t *)img + CSF_HDR_SZ,
img_len - CSF_HDR_SZ, img_hash, &hash_len);
if (ret != 0) {
ERROR("Issue in hash calculation %d\n", ret);
clear_temp_vars();
return IMG_PARSER_ERR;
}
return IMG_PARSER_OK;
}
/*
* Extract an authentication parameter from CSF header
*
* CSF header has already been parsed and the required information like
* hash of data, signature, length stored in global variables has been
* extracted in chek_integrity function. This data
* is returned back to the caller.
*/
static int get_auth_param(const auth_param_type_desc_t *type_desc,
void *img, unsigned int img_len,
void **param, unsigned int *param_len)
{
int rc = IMG_PARSER_OK;
/* We do not use img because the check_integrity function has already
* extracted the relevant data ( pk, sig_alg, etc)
*/
switch (type_desc->type) {
/* Hash will be returned for comparison with signature */
case AUTH_PARAM_HASH:
*param = (void *)img_hash;
*param_len = (unsigned int)SHA256_BYTES;
break;
/* Return the public key used for signature extracted from the SRK table
* after checks with key revocation
*/
case AUTH_PARAM_PUB_KEY:
/* Get the subject public key */
/* For a 1K key - the length would be 2k/8 = 0x100 bytes
* 2K RSA key - 0x200 , 4K RSA - 0x400
*/
*param = img_key;
*param_len = (unsigned int)key_len;
break;
/* Call a function to tell if signature is RSA or ECDSA. ECDSA to be
* supported in later platforms like LX2 etc
*/
case AUTH_PARAM_SIG_ALG:
/* Algo will be signature - RSA or ECDSA on hash */
*param = (void *)&alg;
*param_len = 4U;
break;
/* Return the signature */
case AUTH_PARAM_SIG:
*param = img_sign;
*param_len = (unsigned int)sign_len;
break;
case AUTH_PARAM_NV_CTR:
default:
rc = IMG_PARSER_ERR_NOT_FOUND;
break;
}
return rc;
}
REGISTER_IMG_PARSER_LIB(IMG_PLAT, LIB_NAME, init,
check_integrity, get_auth_param);
This diff is collapsed.
/*
* Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
#include <console_macros.S>
/* UART16550 Registers */
#define UARTTX 0x0
#define UARTRX 0x0
#define UARTDLL 0x0
#define UARTIER 0x1
#define UARTDLLM 0x1
#define UARTFCR 0x2
#define UARTLCR 0x3
#define UARTLSR 0x5
#define UARTMCR 0x4
/* FIFO Control Register bits */
#define UARTFCR_FIFOMD_16450 (0 << 6)
#define UARTFCR_FIFOMD_16550 (1 << 6)
#define UARTFCR_RXTRIG_1 (0 << 6)
#define UARTFCR_RXTRIG_4 (1 << 6)
#define UARTFCR_RXTRIG_8 (2 << 6)
#define UARTFCR_RXTRIG_16 (3 << 6)
#define UARTFCR_TXTRIG_1 (0 << 4)
#define UARTFCR_TXTRIG_4 (1 << 4)
#define UARTFCR_TXTRIG_8 (2 << 4)
#define UARTFCR_TXTRIG_16 (3 << 4)
#define UARTFCR_DMAEN (1 << 3) /* Enable DMA mode */
#define UARTFCR_TXCLR (1 << 2) /* Clear contents of Tx FIFO */
#define UARTFCR_RXCLR (1 << 1) /* Clear contents of Rx FIFO */
#define UARTFCR_FIFOEN (1 << 0) /* Enable the Tx/Rx FIFO */
#define UARTFCR_64FIFO (1 << 5)
/* Line Control Register bits */
#define UARTLCR_DLAB (1 << 7) /* Divisor Latch Access */
#define UARTLCR_SETB (1 << 6) /* Set BREAK Condition */
#define UARTLCR_SETP (1 << 5) /* Set Parity to LCR[4] */
#define UARTLCR_EVEN (1 << 4) /* Even Parity Format */
#define UARTLCR_PAR (1 << 3) /* Parity */
#define UARTLCR_STOP (1 << 2) /* Stop Bit */
#define UARTLCR_WORDSZ_5 0 /* Word Length of 5 */
#define UARTLCR_WORDSZ_6 1 /* Word Length of 6 */
#define UARTLCR_WORDSZ_7 2 /* Word Length of 7 */
#define UARTLCR_WORDSZ_8 3 /* Word Length of 8 */
/* Line Status Register bits */
#define UARTLSR_RXFIFOEMT (1 << 9) /* Rx Fifo Empty */
#define UARTLSR_TXFIFOFULL (1 << 8) /* Tx Fifo Full */
#define UARTLSR_RXFIFOERR (1 << 7) /* Rx Fifo Error */
#define UARTLSR_TEMT (1 << 6) /* Tx Shift Register Empty */
#define UARTLSR_THRE (1 << 5) /* Tx Holding Register Empty */
#define UARTLSR_BRK (1 << 4) /* Break Condition Detected */
#define UARTLSR_FERR (1 << 3) /* Framing Error */
#define UARTLSR_PERR (1 << 3) /* Parity Error */
#define UARTLSR_OVRF (1 << 2) /* Rx Overrun Error */
#define UARTLSR_RDR (1 << 2) /* Rx Data Ready */
#define CONSOLE_T_16550_BASE CONSOLE_T_BASE
/*
* "core" functions are low-level implementations that don't require
* writable memory and are thus safe to call in BL1 crash context.
*/
.globl nxp_console_16550_core_init
.globl nxp_console_16550_core_putc
.globl nxp_console_16550_core_getc
.globl nxp_console_16550_core_flush
.globl console_16550_putc
.globl console_16550_getc
.globl console_16550_flush
/* -----------------------------------------------
* int nxp_console_16550_core_init(uintptr_t base_addr,
* unsigned int uart_clk, unsigned int baud_rate)
* Function to initialize the console without a
* C Runtime to print debug information. This
* function will be accessed by console_init and
* crash reporting.
* In: x0 - console base address
* w1 - Uart clock in Hz
* w2 - Baud rate
* Out: return 1 on success, 0 on error
* Clobber list : x1, x2, x3
* -----------------------------------------------
*/
func nxp_console_16550_core_init
/* Check the input base address */
cbz x0, init_fail
/* Check baud rate and uart clock for sanity */
cbz w1, init_fail
cbz w2, init_fail
/* Program the baudrate */
/* Divisor = Uart clock / (16 * baudrate) */
lsl w2, w2, #4
udiv w2, w1, w2
and w1, w2, #0xff /* w1 = DLL */
lsr w2, w2, #8
and w2, w2, #0xff /* w2 = DLLM */
ldrb w3, [x0, #UARTLCR]
orr w3, w3, #UARTLCR_DLAB
strb w3, [x0, #UARTLCR] /* enable DLL, DLLM programming */
strb w1, [x0, #UARTDLL] /* program DLL */
strb w2, [x0, #UARTDLLM] /* program DLLM */
mov w2, #~UARTLCR_DLAB
and w3, w3, w2
strb w3, [x0, #UARTLCR] /* disable DLL, DLLM programming */
/* 8n1 */
mov w3, #3
strb w3, [x0, #UARTLCR]
/* no interrupt */
mov w3, #0
strb w3, [x0, #UARTIER]
/* enable fifo, DMA */
mov w3, #(UARTFCR_FIFOEN |UARTFCR_TXCLR | UARTFCR_RXCLR)
strb w3, [x0, #UARTFCR]
/* DTR + RTS */
mov w3, #3
str w3, [x0, #UARTMCR]
mov w0, #1
ret
init_fail:
mov w0, #0
ret
endfunc nxp_console_16550_core_init
.globl nxp_console_16550_register
/* -----------------------------------------------
* int nxp_console_16550_register(uintptr_t baseaddr,
* uint32_t clock, uint32_t baud,
* console_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 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 (ignored if w1 is 0)
* x3 - pointer to empty console_t struct
* Out: return 1 on success, 0 on error
* Clobber list : x0, x1, x2, x6, x7, x14
* -----------------------------------------------
*/
func nxp_console_16550_register
mov x7, x30
mov x6, x3
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 nxp_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
register_fail:
ret x7
endfunc nxp_console_16550_register
/* --------------------------------------------------------
* int console_16550_core_putc(int c, uintptr_t base_addr)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
* x1 - console base address
* Out : return -1 on error else return character.
* Clobber list : x2
* --------------------------------------------------------
*/
func nxp_console_16550_core_putc
#if ENABLE_ASSERTIONS
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Prepend '\r' to '\n' */
cmp w0, #'\n'
b.ne 2f
/* Check if the transmit FIFO is full */
1: ldrb w2, [x1, #UARTLSR]
and w2, w2, #UARTLSR_THRE /* #(UARTLSR_TEMT | UARTLSR_THRE)*/
cmp w2, #(UARTLSR_THRE)
b.ne 1b
mov w2, #'\r'
strb w2, [x1, #UARTTX]
ldrb w2, [x1, #UARTFCR]
orr w2, w2, #UARTFCR_TXCLR
/* Check if the transmit FIFO is full */
2: ldrb w2, [x1, #UARTLSR]
and w2, w2, #(UARTLSR_THRE)
cmp w2, #(UARTLSR_THRE)
b.ne 2b
strb w0, [x1, #UARTTX]
ret
endfunc nxp_console_16550_core_putc
/* --------------------------------------------------------
* int console_16550_putc(int c, console_t *console)
* Function to output a character over the console. It
* returns the character printed on success or -1 on error.
* In : w0 - character to be printed
* x1 - pointer to console_t structure
* Out : return -1 on error else return character.
* Clobber list : x2
* --------------------------------------------------------
*/
func console_16550_putc
#if ENABLE_ASSERTIONS
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr x1, [x1, #CONSOLE_T_16550_BASE]
b nxp_console_16550_core_putc
endfunc console_16550_putc
/* ---------------------------------------------
* int console_16550_core_getc(uintptr_t base_addr)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
* In : x0 - console base address
* Out : w0 - character if available, else -1
* Clobber list : x0, x1
* ---------------------------------------------
*/
func nxp_console_16550_core_getc
#if ENABLE_ASSERTIONS
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Check if the receive FIFO is empty */
1: ldrb w1, [x0, #UARTLSR]
tbz w1, #UARTLSR_RDR, 1b
ldrb w0, [x0, #UARTRX]
ret
no_char:
mov w0, #ERROR_NO_PENDING_CHAR
ret
endfunc nxp_console_16550_core_getc
/* ---------------------------------------------
* int console_16550_getc(console_t *console)
* Function to get a character from the console.
* It returns the character grabbed on success
* or -1 on if no character is available.
* In : x0 - pointer to console_t structure
* Out : w0 - character if available, else -1
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_16550_getc
#if ENABLE_ASSERTIONS
cmp x1, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr x0, [x0, #CONSOLE_T_16550_BASE]
b nxp_console_16550_core_getc
endfunc console_16550_getc
/* ---------------------------------------------
* int console_16550_core_flush(uintptr_t base_addr)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - console base address
* Out : return -1 on error else return 0.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func nxp_console_16550_core_flush
#if ENABLE_ASSERTIONS
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
/* Loop until the transmit FIFO is empty */
1: ldrb w1, [x0, #UARTLSR]
and w1, w1, #(UARTLSR_THRE)
cmp w1, #(UARTLSR_THRE)
b.ne 1b
mov w0, #0
ret
endfunc nxp_console_16550_core_flush
/* ---------------------------------------------
* int console_16550_flush(console_t *console)
* Function to force a write of all buffered
* data that hasn't been output.
* In : x0 - pointer to console_t structure
* Out : return -1 on error else return 0.
* Clobber list : x0, x1
* ---------------------------------------------
*/
func console_16550_flush
#if ENABLE_ASSERTIONS
cmp x0, #0
ASM_ASSERT(ne)
#endif /* ENABLE_ASSERTIONS */
ldr x0, [x0, #CONSOLE_T_16550_BASE]
b nxp_console_16550_core_flush
endfunc console_16550_flush
#
# Copyright 2021 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
#------------------------------------------------------------------------------
#
# Select the CORE files
#
# -----------------------------------------------------------------------------
ifeq (${ADD_CONSOLE},)
ADD_CONSOLE := 1
PLAT_INCLUDES += -I$(PLAT_DRIVERS_PATH)/console
ifeq ($(CONSOLE), NS16550)
NXP_CONSOLE := NS16550
$(eval $(call add_define_val,NXP_CONSOLE,${NXP_CONSOLE}))
CONSOLE_SOURCES := $(PLAT_DRIVERS_PATH)/console/16550_console.S \
$(PLAT_DRIVERS_PATH)/console/console_16550.c
else
ifeq ($(CONSOLE), PL011)
CONSOLE_SOURCES := drivers/arm/pl011/aarch64/pl011_console.S \
${PLAT_DRIVERS_PATH}/console/console_pl011.c
else
$(error -> CONSOLE not set!)
endif
endif
ifeq (${BL_COMM_CONSOLE_NEEDED},yes)
BL_COMMON_SOURCES += ${CONSOLE_SOURCES}
else
ifeq (${BL2_CONSOLE_NEEDED},yes)
BL2_SOURCES += ${CONSOLE_SOURCES}
endif
ifeq (${BL31_CONSOLE_NEEDED},yes)
BL31_SOURCES += ${CONSOLE_SOURCES}
endif
endif
endif
# -----------------------------------------------------------------------------
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <common/debug.h>
#include <dcfg.h>
#include <lib/utils.h>
#include <plat_console.h>
/*
* Perform Arm specific early platform setup. At this moment we only initialize
* the console and the memory layout.
*/
void plat_console_init(uintptr_t nxp_console_addr, uint32_t uart_clk_div,
uint32_t baud)
{
struct sysinfo sys;
static console_t nxp_console;
zeromem(&sys, sizeof(sys));
if (get_clocks(&sys)) {
ERROR("System clocks are not set\n");
panic();
}
nxp_console_16550_register(nxp_console_addr,
(sys.freq_platform/uart_clk_div),
baud, &nxp_console);
}
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <assert.h>
#include <common/debug.h>
#include <dcfg.h>
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <lib/utils.h>
/*
* Perform Arm specific early platform setup. At this moment we only initialize
* the console and the memory layout.
*/
void plat_console_init(uintptr_t nxp_console_addr, uint32_t uart_clk_div,
uint32_t baud)
{
struct sysinfo sys;
static console_t nxp_console;
zeromem(&sys, sizeof(sys));
if (get_clocks(&sys)) {
ERROR("System clocks are not set\n");
panic();
}
console_pl011_register(nxp_console_addr,
(sys.freq_platform/uart_clk_div),
baud, &nxp_console);
}
/*
* Copyright 2021 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef PLAT_CONSOLE_H
#define PLAT_CONSOLE_H
#include <stdint.h>
#include <drivers/console.h>
#if (NXP_CONSOLE == NS16550)
/*
* NXP specific UART - 16550 configuration
*
* Initialize a NXP 16550 console instance and register it with the console
* 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 nxp_console_16550_register(uintptr_t baseaddr, uint32_t clock,
uint32_t baud, console_t *console);
#endif
/*
* Function to initialize platform's console
* and register with console framework
*/
void plat_console_init(uintptr_t nxp_console_addr, uint32_t uart_clk_div,
uint32_t baud);
#endif
#
# Copyright 2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
#
ifeq (${ADD_CAAM},)
ADD_CAAM := 1
CAAM_DRIVER_PATH := drivers/nxp/crypto/caam
CAAM_DRIVER_SOURCES += $(wildcard $(CAAM_DRIVER_PATH)/src/*.c)
PLAT_INCLUDES += -I$(CAAM_DRIVER_PATH)/include
ifeq (${BL_COMM_CRYPTO_NEEDED},yes)
BL_COMMON_SOURCES += ${CAAM_DRIVER_SOURCES}
else
ifeq (${BL2_CRYPTO_NEEDED},yes)
BL2_SOURCES += ${CAAM_DRIVER_SOURCES}
endif
ifeq (${BL31_CRYPTO_NEEDED},yes)
BL31_SOURCES += ${CAAM_DRIVER_SOURCES}
endif
endif
endif
/*
* Copyright 2017-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef CAAM_H
#define CAAM_H
#include "caam_io.h"
#include "sec_jr_driver.h"
/* Job ring 3 is reserved for usage by sec firmware */
#define DEFAULT_JR 3
#if defined(CONFIG_CHASSIS_3_2) || defined(CONFIG_CHASSIS_2)
#define CAAM_JR0_OFFSET 0x10000
#define CAAM_JR1_OFFSET 0x20000
#define CAAM_JR2_OFFSET 0x30000
#define CAAM_JR3_OFFSET 0x40000
#endif
enum sig_alg {
RSA,
ECC
};
/* This function does basic SEC Initialization */
int sec_init(uintptr_t nxp_caam_addr);
int config_sec_block(void);
uintptr_t get_caam_addr(void);
/* This function is used to submit jobs to JR */
int run_descriptor_jr(struct job_descriptor *desc);
/* This function is used to instatiate the HW RNG is already not instantiated */
int hw_rng_instantiate(void);
/* This function is used to return random bytes of byte_len from HW RNG */
int get_rand_bytes_hw(uint8_t *bytes, int byte_len);
/* This function is used to set the hw unique key from HW CAAM */
int get_hw_unq_key_blob_hw(uint8_t *hw_key, int size);
/* This function is used to fetch random number from
* CAAM of length either of 4 bytes or 8 bytes depending
* rngWidth value.
*/
unsigned long long get_random(int rngWidth);
#endif /* CAAM_H */
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