Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx

master
Tom Rini 10 years ago
commit 1c6f6a6ef9
  1. 20
      arch/arm/include/asm/arch-ls102xa/config.h
  2. 28
      arch/powerpc/cpu/mpc85xx/cpu.c
  3. 140
      arch/powerpc/cpu/mpc85xx/speed.c
  4. 91
      arch/powerpc/cpu/mpc8xxx/cpu.c
  5. 20
      arch/powerpc/include/asm/config_mpc85xx.h
  6. 35
      arch/powerpc/include/asm/fsl_secure_boot.h
  7. 22
      arch/powerpc/include/asm/immap_85xx.h
  8. 5
      arch/powerpc/include/asm/processor.h
  9. 6
      board/freescale/common/Makefile
  10. 34
      board/freescale/common/cmd_esbc_validate.c
  11. 840
      board/freescale/common/fsl_validate.c
  12. 15
      board/freescale/t104xrdb/ddr.c
  13. 29
      board/freescale/t104xrdb/ddr.h
  14. 105
      doc/README.Heterogeneous-SoCs
  15. 41
      doc/README.esbc_validate
  16. 3
      drivers/crypto/rsa_mod_exp/Makefile
  17. 8
      drivers/misc/Kconfig
  18. 1
      drivers/misc/Makefile
  19. 146
      drivers/misc/fsl_sec_mon.c
  20. 2
      include/common.h
  21. 1
      include/configs/T104xRDB.h
  22. 11
      include/e500.h
  23. 58
      include/fsl_sec_mon.h
  24. 128
      include/fsl_secboot_err.h
  25. 85
      include/fsl_sfp.h
  26. 199
      include/fsl_validate.h
  27. 3
      lib/rsa/Makefile

@ -27,6 +27,8 @@
#define CONFIG_SYS_FSL_SCFG_ADDR (CONFIG_SYS_IMMR + 0x00570000)
#define CONFIG_SYS_FSL_SEC_ADDR (CONFIG_SYS_IMMR + 0x700000)
#define CONFIG_SYS_FSL_JR0_ADDR (CONFIG_SYS_IMMR + 0x710000)
#define CONFIG_SYS_SEC_MON_ADDR (CONFIG_SYS_IMMR + 0x00e90000)
#define CONFIG_SYS_SFP_ADDR (CONFIG_SYS_IMMR + 0x00e80200)
#define CONFIG_SYS_FSL_SERDES_ADDR (CONFIG_SYS_IMMR + 0x00ea0000)
#define CONFIG_SYS_FSL_GUTS_ADDR (CONFIG_SYS_IMMR + 0x00ee0000)
#define CONFIG_SYS_FSL_LS1_CLK_ADDR (CONFIG_SYS_IMMR + 0x00ee1000)
@ -95,7 +97,25 @@
#define CONFIG_SYS_FSL_DSPI_BE
#define CONFIG_SYS_FSL_QSPI_BE
#define CONFIG_SYS_FSL_DCU_BE
#define CONFIG_SYS_FSL_SEC_MON_LE
#define CONFIG_SYS_FSL_SEC_LE
#define CONFIG_SYS_FSL_SFP_VER_3_2
#define CONFIG_SYS_FSL_SFP_BE
#define CONFIG_SYS_FSL_SRK_LE
#define CONFIG_KEY_REVOCATION
#define CONFIG_FSL_ISBC_KEY_EXT
#ifdef CONFIG_SECURE_BOOT
#define CONFIG_CMD_ESBC_VALIDATE
#define CONFIG_FSL_SEC_MON
#define CONFIG_SHA_PROG_HW_ACCEL
#define CONFIG_DM
#define CONFIG_RSA
#define CONFIG_RSA_FREESCALE_EXP
#ifndef CONFIG_FSL_CAAM
#define CONFIG_FSL_CAAM
#endif
#endif
#define DCU_LAYER_MAX_NUM 16

@ -73,6 +73,11 @@ int checkcpu (void)
unsigned int i, core, nr_cores = cpu_numcores();
u32 mask = cpu_mask();
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned int j, dsp_core, dsp_numcores = cpu_num_dspcores();
u32 dsp_mask = cpu_dsp_mask();
#endif
svr = get_svr();
major = SVR_MAJ(svr);
minor = SVR_MIN(svr);
@ -166,6 +171,16 @@ int checkcpu (void)
printf("CPU%d:%-4s MHz, ", core,
strmhz(buf1, sysinfo.freq_processor[core]));
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
for_each_cpu(j, dsp_core, dsp_numcores, dsp_mask) {
if (!(j & 3))
printf("\n ");
printf("DSP CPU%d:%-4s MHz, ", j,
strmhz(buf1, sysinfo.freq_processor_dsp[dsp_core]));
}
#endif
printf("\n CCB:%-4s MHz,", strmhz(buf1, sysinfo.freq_systembus));
printf("\n");
@ -224,6 +239,19 @@ int checkcpu (void)
printf(" QE:%-4s MHz\n", strmhz(buf1, sysinfo.freq_qe));
#endif
#if defined(CONFIG_SYS_CPRI)
printf(" ");
printf("CPRI:%-4s MHz", strmhz(buf1, sysinfo.freq_cpri));
#endif
#if defined(CONFIG_SYS_MAPLE)
printf("\n ");
printf("MAPLE:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple));
printf("MAPLE-ULB:%-4s MHz, ", strmhz(buf1, sysinfo.freq_maple_ulb));
printf("MAPLE-eTVPE:%-4s MHz\n",
strmhz(buf1, sysinfo.freq_maple_etvpe));
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
for (i = 0; i < CONFIG_SYS_NUM_FMAN; i++) {
printf(" FMAN%d: %s MHz\n", i + 1,

@ -34,6 +34,10 @@ void get_sys_info(sys_info_t *sys_info)
#ifdef CONFIG_FSL_CORENET
volatile ccsr_clk_t *clk = (void *)(CONFIG_SYS_FSL_CORENET_CLK_ADDR);
unsigned int cpu;
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned int dsp_cpu;
uint rcw_tmp1, rcw_tmp2;
#endif
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
int cc_group[12] = CONFIG_SYS_FSL_CLUSTER_CLOCKS;
#endif
@ -157,6 +161,7 @@ void get_sys_info(sys_info_t *sys_info)
else
freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
}
#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
/*
* As per CHASSIS2 architeture total 12 clusters are posible and
@ -181,6 +186,20 @@ void get_sys_info(sys_info_t *sys_info)
sys_info->freq_processor[cpu] =
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
for_each_cpu(i, dsp_cpu, cpu_num_dspcores(), cpu_dsp_mask()) {
int dsp_cluster = fsl_qoriq_dsp_core_to_cluster(dsp_cpu);
u32 c_pll_sel = (in_be32
(&clk->clkcsr[dsp_cluster].clkcncsr) >> 27)
& 0xf;
u32 cplx_pll = core_cplx_PLL[c_pll_sel];
cplx_pll += cc_group[dsp_cluster] - 1;
sys_info->freq_processor_dsp[dsp_cpu] =
freq_c_pll[cplx_pll] / core_cplx_pll_div[c_pll_sel];
}
#endif
#if defined(CONFIG_PPC_B4860) || defined(CONFIG_PPC_B4420) || \
defined(CONFIG_PPC_T2080) || defined(CONFIG_PPC_T2081)
#define FM1_CLK_SEL 0xe0000000
@ -243,6 +262,127 @@ void get_sys_info(sys_info_t *sys_info)
sys_info->freq_qman = sys_info->freq_systembus / CONFIG_QBMAN_CLK_DIV;
#endif
#if defined(CONFIG_SYS_MAPLE)
#define CPRI_CLK_SEL 0x1C000000
#define CPRI_CLK_SHIFT 26
#define CPRI_ALT_CLK_SEL 0x00007000
#define CPRI_ALT_CLK_SHIFT 12
rcw_tmp1 = in_be32(&gur->rcwsr[7]); /* Reading RCW bits: 224-255*/
rcw_tmp2 = in_be32(&gur->rcwsr[15]); /* Reading RCW bits: 480-511*/
/* For MAPLE and CPRI frequency */
switch ((rcw_tmp1 & CPRI_CLK_SEL) >> CPRI_CLK_SHIFT) {
case 1:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK];
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK];
break;
case 2:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 2;
break;
case 3:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 3;
break;
case 4:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK] / 4;
break;
case 5:
if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
>> CPRI_ALT_CLK_SHIFT) == 6) {
sys_info->freq_maple =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
sys_info->freq_cpri =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 2;
}
if (((rcw_tmp2 & CPRI_ALT_CLK_SEL)
>> CPRI_ALT_CLK_SHIFT) == 7) {
sys_info->freq_maple =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
sys_info->freq_cpri =
freq_c_pll[CONFIG_SYS_CPRI_CLK - 2] / 3;
}
break;
case 6:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 2;
break;
case 7:
sys_info->freq_maple = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
sys_info->freq_cpri = freq_c_pll[CONFIG_SYS_CPRI_CLK + 1] / 3;
break;
default:
printf("Error: Unknown MAPLE/CPRI clock select!\n");
}
/* For MAPLE ULB and eTVPE frequencies */
#define ULB_CLK_SEL 0x00000038
#define ULB_CLK_SHIFT 3
#define ETVPE_CLK_SEL 0x00000007
#define ETVPE_CLK_SHIFT 0
switch ((rcw_tmp2 & ULB_CLK_SEL) >> ULB_CLK_SHIFT) {
case 1:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK];
break;
case 2:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 2;
break;
case 3:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 3;
break;
case 4:
sys_info->freq_maple_ulb = freq_c_pll[CONFIG_SYS_ULB_CLK] / 4;
break;
case 5:
sys_info->freq_maple_ulb = sys_info->freq_systembus;
break;
case 6:
sys_info->freq_maple_ulb =
freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 2;
break;
case 7:
sys_info->freq_maple_ulb =
freq_c_pll[CONFIG_SYS_ULB_CLK - 1] / 3;
break;
default:
printf("Error: Unknown MAPLE ULB clock select!\n");
}
switch ((rcw_tmp2 & ETVPE_CLK_SEL) >> ETVPE_CLK_SHIFT) {
case 1:
sys_info->freq_maple_etvpe = freq_c_pll[CONFIG_SYS_ETVPE_CLK];
break;
case 2:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 2;
break;
case 3:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 3;
break;
case 4:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK] / 4;
break;
case 5:
sys_info->freq_maple_etvpe = sys_info->freq_systembus;
break;
case 6:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 2;
break;
case 7:
sys_info->freq_maple_etvpe =
freq_c_pll[CONFIG_SYS_ETVPE_CLK - 1] / 3;
break;
default:
printf("Error: Unknown MAPLE eTVPE clock select!\n");
}
#endif
#ifdef CONFIG_SYS_DPAA_FMAN
#ifndef CONFIG_FM_PLAT_CLK_DIV
switch ((rcw_tmp & FM1_CLK_SEL) >> FM1_CLK_SHIFT) {

@ -133,6 +133,53 @@ u32 compute_ppc_cpumask(void)
return mask;
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
u32 compute_dsp_cpumask(void)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
int i = CONFIG_DSP_CLUSTER_START, count = 0;
u32 cluster, type, dsp_mask = 0;
do {
int j;
cluster = in_be32(&gur->tp_cluster[i].lower);
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
type = init_type(cluster, j);
if (type) {
if (TP_ITYP_TYPE(type) == TP_ITYP_TYPE_SC)
dsp_mask |= 1 << count;
count++;
}
}
i++;
} while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
return dsp_mask;
}
int fsl_qoriq_dsp_core_to_cluster(unsigned int core)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
int count = 0, i = CONFIG_DSP_CLUSTER_START;
u32 cluster;
do {
int j;
cluster = in_be32(&gur->tp_cluster[i].lower);
for (j = 0; j < TP_INIT_PER_CLUSTER; j++) {
if (init_type(cluster, j)) {
if (count == core)
return i;
count++;
}
}
i++;
} while ((cluster & TP_CLUSTER_EOC) != TP_CLUSTER_EOC);
return -1; /* cannot identify the cluster */
}
#endif
int fsl_qoriq_core_to_cluster(unsigned int core)
{
ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@ -198,8 +245,43 @@ __weak u32 cpu_mask(void)
return cpu->mask;
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
__weak u32 cpu_dsp_mask(void)
{
ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR;
struct cpu_type *cpu = gd->arch.cpu;
/* better to query feature reporting register than just assume 1 */
if (cpu == &cpu_type_unknown)
return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >>
MPC8xxx_PICFRR_NCPU_SHIFT) + 1;
if (cpu->dsp_num_cores == 0)
return compute_dsp_cpumask();
return cpu->dsp_mask;
}
/*
* Return the number of cores on this SOC.
* Return the number of SC/DSP cores on this SOC.
*/
__weak int cpu_num_dspcores(void)
{
struct cpu_type *cpu = gd->arch.cpu;
/*
* Report # of cores in terms of the cpu_mask if we haven't
* figured out how many there are yet
*/
if (cpu->dsp_num_cores == 0)
return hweight32(cpu_dsp_mask());
return cpu->dsp_num_cores;
}
#endif
/*
* Return the number of PPC cores on this SOC.
*/
__weak int cpu_numcores(void)
{
@ -215,6 +297,7 @@ __weak int cpu_numcores(void)
return cpu->num_cores;
}
/*
* Check if the given core ID is valid
*
@ -248,6 +331,12 @@ int fixup_cpu(void)
cpu->num_cores = cpu_numcores();
}
#ifdef CONFIG_HETROGENOUS_CLUSTERS
if (cpu->dsp_num_cores == 0) {
cpu->dsp_mask = cpu_dsp_mask();
cpu->dsp_num_cores = cpu_num_dspcores();
}
#endif
return 0;
}

@ -25,6 +25,8 @@
/* IP endianness */
#define CONFIG_SYS_FSL_IFC_BE
#define CONFIG_SYS_FSL_SEC_BE
#define CONFIG_SYS_FSL_SFP_BE
#define CONFIG_SYS_FSL_SEC_MON_BE
/* Number of TLB CAM entries we have on FSL Book-E chips */
#if defined(CONFIG_E500MC)
@ -201,7 +203,7 @@
#elif defined(CONFIG_P1013)
#define CONFIG_MAX_CPUS 1
#define CONFIG_SYS_FSL_NUM_LAWS 12
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 2
@ -285,7 +287,7 @@
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2
#define CONFIG_TSECV2
#define CONFIG_SYS_FSL_SEC_COMPAT 2
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_CCSRBAR_DEFAULT 0xff700000
#define CONFIG_SYS_FSL_ERRATUM_ELBC_A001
#define CONFIG_SYS_FSL_ERRATUM_ESDHC111
@ -689,13 +691,22 @@
#define CONFIG_FSL_CORENET /* Freescale CoreNet platform */
#define CONFIG_SYS_FSL_QORIQ_CHASSIS2 /* Freescale Chassis generation 2 */
#define CONFIG_SYS_FSL_QMAN_V3 /* QMAN version 3 */
#define CONFIG_HETROGENOUS_CLUSTERS /* DSP/SC3900 core clusters */
#define CONFIG_PPC_CLUSTER_START 0 /*Start index of ppc clusters*/
#define CONFIG_DSP_CLUSTER_START 1 /*Start index of dsp clusters*/
#define CONFIG_SYS_FSL_NUM_LAWS 32
#define CONFIG_SYS_FSL_SRDS_1
#define CONFIG_SYS_FSL_SRDS_2
#define CONFIG_SYS_MAPLE
#define CONFIG_SYS_CPRI
#define CONFIG_SYS_FSL_NUM_CC_PLLS 5
#define CONFIG_SYS_FSL_SEC_COMPAT 4
#define CONFIG_SYS_NUM_FMAN 1
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_FM1_CLK 0
#define CONFIG_SYS_CPRI_CLK 3
#define CONFIG_SYS_ULB_CLK 4
#define CONFIG_SYS_ETVPE_CLK 1
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_4_7
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 4
#define CONFIG_SYS_FMAN_V3
@ -718,8 +729,9 @@
#ifdef CONFIG_PPC_B4860
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 4
#define CONFIG_MAX_CPUS 4
#define CONFIG_MAX_DSP_CPUS 12
#define CONFIG_NUM_DSP_CPUS 6
#define CONFIG_SYS_FSL_SRDS_NUM_PLLS 2
#define CONFIG_SYS_FSL_NUM_CC_PLLS 4
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 4, 4, 4 }
#define CONFIG_SYS_NUM_FM1_DTSEC 6
#define CONFIG_SYS_NUM_FM1_10GEC 2
@ -731,9 +743,9 @@
#define CONFIG_SYS_FSL_SRIO_LIODN
#else
#define CONFIG_MAX_CPUS 2
#define CONFIG_MAX_DSP_CPUS 2
#define CONFIG_SYS_FSL_SRDS_NUM_PLLS 1
#define CONFIG_SYS_FSL_CORES_PER_CLUSTER 2
#define CONFIG_SYS_FSL_NUM_CC_PLLS 4
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 4 }
#define CONFIG_SYS_NUM_FM1_DTSEC 4
#define CONFIG_SYS_NUM_FM1_10GEC 0

@ -6,6 +6,19 @@
#ifndef __FSL_SECURE_BOOT_H
#define __FSL_SECURE_BOOT_H
#include <asm/config_mpc85xx.h>
#ifdef CONFIG_SECURE_BOOT
#define CONFIG_CMD_ESBC_VALIDATE
#define CONFIG_FSL_SEC_MON
#define CONFIG_SHA_PROG_HW_ACCEL
#define CONFIG_DM
#define CONFIG_RSA
#define CONFIG_RSA_FREESCALE_EXP
#ifndef CONFIG_FSL_CAAM
#define CONFIG_FSL_CAAM
#endif
#endif
#ifdef CONFIG_SECURE_BOOT
#if defined(CONFIG_FSL_CORENET)
@ -28,9 +41,31 @@
defined(CONFIG_PPC_T1023) || \
defined(CONFIG_PPC_T1024)
#define CONFIG_SYS_CPC_REINIT_F
#define CONFIG_KEY_REVOCATION
#undef CONFIG_SYS_INIT_L3_ADDR
#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
#endif
#if defined(CONFIG_C29XPCIE)
#define CONFIG_KEY_REVOCATION
#endif
#if defined(CONFIG_PPC_P3041) || \
defined(CONFIG_PPC_P4080) || \
defined(CONFIG_PPC_P5020) || \
defined(CONFIG_PPC_P5040) || \
defined(CONFIG_PPC_P2041)
#define CONFIG_FSL_TRUST_ARCH_v1
#endif
#if defined(CONFIG_FSL_CORENET)
/* The key used for verification of next level images
* is picked up from an Extension Table which has
* been verified by the ISBC (Internal Secure boot Code)
* in boot ROM of the SoC
*/
#define CONFIG_FSL_ISBC_KEY_EXT
#endif
#endif
#endif

@ -17,6 +17,7 @@
#include <asm/fsl_i2c.h>
#include <fsl_ifc.h>
#include <fsl_sec.h>
#include <fsl_sfp.h>
#include <asm/fsl_lbc.h>
#include <asm/fsl_fman.h>
#include <fsl_immap.h>
@ -2823,21 +2824,6 @@ struct ccsr_pman {
u8 res_f4[0xf0c];
};
#endif
#ifdef CONFIG_SYS_FSL_SFP_VER_3_0
struct ccsr_sfp_regs {
u32 ospr; /* 0x200 */
u32 reserved0[14];
u32 srk_hash[8]; /* 0x23c Super Root Key Hash */
u32 oem_uid; /* 0x9c OEM Unique ID */
u8 reserved2[0x04];
u32 ovpr; /* 0xA4 Intent To Secure */
u8 reserved4[0x08];
u32 fsl_uid; /* 0xB0 FSL Unique ID */
u8 reserved5[0x04];
u32 fsl_spfr0; /* Scratch Pad Fuse Register 0 */
u32 fsl_spfr1; /* Scratch Pad Fuse Register 1 */
};
#endif
#ifdef CONFIG_FSL_CORENET
#define CONFIG_SYS_FSL_CORENET_CCM_OFFSET 0x0000
@ -2897,6 +2883,7 @@ struct ccsr_sfp_regs {
#define CONFIG_SYS_MPC85xx_SATA2_OFFSET 0x221000
#define CONFIG_SYS_FSL_SEC_OFFSET 0x300000
#define CONFIG_SYS_FSL_JR0_OFFSET 0x301000
#define CONFIG_SYS_SEC_MON_OFFSET 0x314000
#define CONFIG_SYS_FSL_CORENET_PME_OFFSET 0x316000
#define CONFIG_SYS_FSL_QMAN_OFFSET 0x318000
#define CONFIG_SYS_FSL_BMAN_OFFSET 0x31a000
@ -2964,7 +2951,7 @@ struct ccsr_sfp_regs {
#endif
#define CONFIG_SYS_MPC85xx_SERDES2_OFFSET 0xE3100
#define CONFIG_SYS_MPC85xx_SERDES1_OFFSET 0xE3000
#define CONFIG_SYS_SNVS_OFFSET 0xE6000
#define CONFIG_SYS_SEC_MON_OFFSET 0xE6000
#define CONFIG_SYS_SFP_OFFSET 0xE7000
#define CONFIG_SYS_MPC85xx_CPM_OFFSET 0x80000
#define CONFIG_SYS_FSL_QMAN_OFFSET 0x88000
@ -3094,6 +3081,9 @@ struct ccsr_sfp_regs {
#define CONFIG_SYS_SFP_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_SFP_OFFSET)
#define CONFIG_SYS_SEC_MON_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_SEC_MON_OFFSET)
#define TSEC_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_TSEC1_OFFSET)
#define MDIO_BASE_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MDIO1_OFFSET)

@ -1202,12 +1202,17 @@ struct cpu_type {
u32 soc_ver;
u32 num_cores;
u32 mask; /* which cpu(s) actually exist */
#ifdef CONFIG_HETROGENOUS_CLUSTERS
u32 dsp_num_cores;
u32 dsp_mask; /* which DSP cpu(s) actually exist */
#endif
};
struct cpu_type *identify_cpu(u32 ver);
int fixup_cpu(void);
int fsl_qoriq_core_to_cluster(unsigned int core);
int fsl_qoriq_dsp_core_to_cluster(unsigned int core);
#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
#define CPU_TYPE_ENTRY(n, v, nc) \

@ -72,4 +72,10 @@ obj-$(CONFIG_P5020DS) += p_corenet/
obj-$(CONFIG_P5040DS) += p_corenet/
obj-$(CONFIG_LS102XA_NS_ACCESS) += ns_access.o
ifdef CONFIG_SECURE_BOOT
obj-y += fsl_validate.o
obj-$(CONFIG_CMD_ESBC_VALIDATE) += cmd_esbc_validate.o
endif
endif

@ -0,0 +1,34 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
#include <fsl_validate.h>
static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
if (argc < 2)
return cmd_usage(cmdtp);
return fsl_secboot_validate(cmdtp, flag, argc, argv);
}
/***************************************************/
static char esbc_validate_help_text[] =
"esbc_validate hdr_addr <hash_val> - Validates signature using\n"
" RSA verification\n"
" $hdr_addr Address of header of the image\n"
" to be validated.\n"
" $hash_val -Optional\n"
" It provides Hash of public/srk key to be\n"
" used to verify signature.\n";
U_BOOT_CMD(
esbc_validate, 3, 0, do_esbc_validate,
"Validates signature on a given image using RSA verification",
esbc_validate_help_text
);

@ -0,0 +1,840 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <fsl_validate.h>
#include <fsl_secboot_err.h>
#include <fsl_sfp.h>
#include <fsl_sec.h>
#include <command.h>
#include <malloc.h>
#include <dm/uclass.h>
#include <u-boot/rsa-mod-exp.h>
#include <hash.h>
#include <fsl_secboot_err.h>
#ifndef CONFIG_MPC85xx
#include <asm/arch/immap_ls102xa.h>
#endif
#define SHA256_BITS 256
#define SHA256_BYTES (256/8)
#define SHA256_NIBBLES (256/4)
#define NUM_HEX_CHARS (sizeof(ulong) * 2)
/* This array contains DER value for SHA-256 */
static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
0x04, 0x20
};
static u8 hash_val[SHA256_BYTES];
static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
void branch_to_self(void) __attribute__ ((noreturn));
/*
* This function will put core in infinite loop.
* This will be called when the ESBC can not proceed further due
* to some unknown errors.
*/
void branch_to_self(void)
{
printf("Core is in infinite loop due to errors.\n");
self:
goto self;
}
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
static u32 check_ie(struct fsl_secboot_img_priv *img)
{
if (img->hdr.ie_flag)
return 1;
return 0;
}
/* This function returns the CSF Header Address of uboot
* For MPC85xx based platforms, the LAW mapping for NOR
* flash changes in uboot code. Hence the offset needs
* to be calculated and added to the new NOR flash base
* address
*/
#if defined(CONFIG_MPC85xx)
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
ulong flash_addr, addr;
int found = 0;
int i = 0;
for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
flash_addr = flash_info[i].start[0];
addr = flash_info[i].start[0] + csf_flash_offset;
if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
debug("Barker found on addr %lx\n", addr);
found = 1;
break;
}
}
if (!found)
return -1;
*csf_addr = addr;
*flash_base_addr = flash_addr;
return 0;
}
#else
/* For platforms like LS1020, correct flash address is present in
* the header. So the function reqturns flash base address as 0
*/
int get_csf_base_addr(ulong *csf_addr, ulong *flash_base_addr)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
if (memcmp((u8 *)csf_hdr_addr, barker_code, ESBC_BARKER_LEN))
return -1;
*csf_addr = csf_hdr_addr;
*flash_base_addr = 0;
return 0;
}
#endif
static int get_ie_info_addr(ulong *ie_addr)
{
struct fsl_secboot_img_hdr *hdr;
struct fsl_secboot_sg_table *sg_tbl;
ulong flash_base_addr, csf_addr;
if (get_csf_base_addr(&csf_addr, &flash_base_addr))
return -1;
hdr = (struct fsl_secboot_img_hdr *)csf_addr;
/* For SoC's with Trust Architecture v1 with corenet bus
* the sg table field in CSF header has absolute address
* for sg table in memory. In other Trust Architecture,
* this field specifies the offset of sg table from the
* base address of CSF Header
*/
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
sg_tbl = (struct fsl_secboot_sg_table *)
(((ulong)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
flash_base_addr);
#else
sg_tbl = (struct fsl_secboot_sg_table *)(csf_addr +
(ulong)hdr->psgtable);
#endif
/* IE Key Table is the first entry in the SG Table */
#if defined(CONFIG_MPC85xx)
*ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
flash_base_addr;
#else
*ie_addr = sg_tbl->src_addr;
#endif
debug("IE Table address is %lx\n", *ie_addr);
return 0;
}
#endif
#ifdef CONFIG_KEY_REVOCATION
/* This function checks srk_table_flag in header and set/reset srk_flag.*/
static u32 check_srk(struct fsl_secboot_img_priv *img)
{
if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
return 1;
return 0;
}
/* This function returns ospr's key_revoc values.*/
static u32 get_key_revoc(void)
{
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
OSPR_KEY_REVOC_SHIFT;
}
/* This function checks if selected key is revoked or not.*/
static u32 is_key_revoked(u32 keynum, u32 rev_flag)
{
if (keynum == UNREVOCABLE_KEY)
return 0;
if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
return 1;
return 0;
}
/* It validates srk_table key lengths.*/
static u32 validate_srk_tbl(struct srk_table *tbl, u32 num_entries)
{
int i = 0;
for (i = 0; i < num_entries; i++) {
if (!((tbl[i].key_len == 2 * KEY_SIZE_BYTES/4) ||
(tbl[i].key_len == 2 * KEY_SIZE_BYTES/2) ||
(tbl[i].key_len == 2 * KEY_SIZE_BYTES)))
return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
}
return 0;
}
#endif
/* This function return length of public key.*/
static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
{
return img->key_len;
}
/*
* Handles the ESBC uboot client header verification failure.
* This function handles all the errors which might occur in the
* parsing and checking of ESBC uboot client header. It will also
* set the error bits in the SEC_MON.
*/
static void fsl_secboot_header_verification_failure(void)
{
struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
(CONFIG_SYS_SEC_MON_ADDR);
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
/* 29th bit of OSPR is ITS */
u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
/*
* Read the SEC_MON status register
* Read SSM_ST field
*/
sts = sec_mon_in32(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
if (its == 1)
change_sec_mon_state(HPSR_SSM_ST_TRUST,
HPSR_SSM_ST_SOFT_FAIL);
else
change_sec_mon_state(HPSR_SSM_ST_TRUST,
HPSR_SSM_ST_NON_SECURE);
}
printf("Generating reset request\n");
do_reset(NULL, 0, 0, NULL);
}
/*
* Handles the ESBC uboot client image verification failure.
* This function handles all the errors which might occur in the
* public key hash comparison and signature verification of
* ESBC uboot client image. It will also
* set the error bits in the SEC_MON.
*/
static void fsl_secboot_image_verification_failure(void)
{
struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
(CONFIG_SYS_SEC_MON_ADDR);
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
u32 its = sfp_in32(&sfp_regs->ospr) & ITS_MASK >> ITS_BIT;
/*
* Read the SEC_MON status register
* Read SSM_ST field
*/
sts = sec_mon_in32(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) == HPSR_SSM_ST_TRUST) {
if (its == 1) {
change_sec_mon_state(HPSR_SSM_ST_TRUST,
HPSR_SSM_ST_SOFT_FAIL);
printf("Generating reset request\n");
do_reset(NULL, 0, 0, NULL);
} else {
change_sec_mon_state(HPSR_SSM_ST_TRUST,
HPSR_SSM_ST_NON_SECURE);
}
}
}
static void fsl_secboot_bootscript_parse_failure(void)
{
fsl_secboot_header_verification_failure();
}
/*
* Handles the errors in esbc boot.
* This function handles all the errors which might occur in the
* esbc boot phase. It will call the appropriate api to log the
* errors and set the error bits in the SEC_MON.
*/
void fsl_secboot_handle_error(int error)
{
const struct fsl_secboot_errcode *e;
for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
e++) {
if (e->errcode == error)
printf("ERROR :: %x :: %s\n", error, e->name);
}
switch (error) {
case ERROR_ESBC_CLIENT_HEADER_BARKER:
case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
#ifdef CONFIG_KEY_REVOCATION
case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
/*@fallthrough@*/
case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
case ERROR_IE_TABLE_NOT_FOUND:
#endif
fsl_secboot_header_verification_failure();
break;
case ERROR_ESBC_SEC_RESET:
case ERROR_ESBC_SEC_DEQ:
case ERROR_ESBC_SEC_ENQ:
case ERROR_ESBC_SEC_DEQ_TO:
case ERROR_ESBC_SEC_JOBQ_STATUS:
case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
fsl_secboot_image_verification_failure();
break;
case ERROR_ESBC_MISSING_BOOTM:
fsl_secboot_bootscript_parse_failure();
break;
case ERROR_ESBC_WRONG_CMD:
default:
branch_to_self();
break;
}
}
static void fsl_secblk_handle_error(int error)
{
switch (error) {
case ERROR_ESBC_SEC_ENQ:
fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
break;
case ERROR_ESBC_SEC_DEQ:
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
break;
case ERROR_ESBC_SEC_DEQ_TO:
fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
break;
default:
printf("Job Queue Output status %x\n", error);
fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
break;
}
}
/*
* Calculate hash of key obtained via offset present in ESBC uboot
* client hdr. This function calculates the hash of key which is obtained
* through offset present in ESBC uboot client header.
*/
static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
{
struct hash_algo *algo;
void *ctx;
int i, srk = 0;
int ret = 0;
const char *algo_name = "sha256";
/* Calculate hash of the esbc key */
ret = hash_progressive_lookup_algo(algo_name, &algo);
if (ret)
return ret;
ret = algo->hash_init(algo, &ctx);
if (ret)
return ret;
/* Update hash for ESBC key */
#ifdef CONFIG_KEY_REVOCATION
if (check_srk(img)) {
ret = algo->hash_update(algo, ctx,
(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
srk = 1;
}
#endif
if (!srk)
ret = algo->hash_update(algo, ctx,
img->img_key, img->key_len, 1);
if (ret)
return ret;
/* Copy hash at destination buffer */
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
if (ret)
return ret;
for (i = 0; i < SHA256_BYTES; i++)
img->img_key_hash[i] = hash_val[i];
return 0;
}
/*
* Calculate hash of ESBC hdr and ESBC. This function calculates the
* single hash of ESBC header and ESBC image. If SG flag is on, all
* SG entries are also hashed alongwith the complete SG table.
*/
static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
{
struct hash_algo *algo;
void *ctx;
int ret = 0;
int key_hash = 0;
const char *algo_name = "sha256";
/* Calculate the hash of the ESBC */
ret = hash_progressive_lookup_algo(algo_name, &algo);
if (ret)
return ret;
ret = algo->hash_init(algo, &ctx);
/* Copy hash at destination buffer */
if (ret)
return ret;
/* Update hash for CSF Header */
ret = algo->hash_update(algo, ctx,
(u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
if (ret)
return ret;
/* Update the hash with that of srk table if srk flag is 1
* If IE Table is selected, key is not added in the hash
* If neither srk table nor IE key table available, add key
* from header in the hash calculation
*/
#ifdef CONFIG_KEY_REVOCATION
if (check_srk(img)) {
ret = algo->hash_update(algo, ctx,
(u8 *)(img->ehdrloc + img->hdr.srk_tbl_off),
img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
key_hash = 1;
}
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
if (!key_hash && check_ie(img))
key_hash = 1;
#endif
if (!key_hash)
ret = algo->hash_update(algo, ctx,
img->img_key, img->hdr.key_len, 0);
if (ret)
return ret;
/* Update hash for actual Image */
ret = algo->hash_update(algo, ctx,
(u8 *)img->hdr.pimg, img->hdr.img_size, 1);
if (ret)
return ret;
/* Copy hash at destination buffer */
ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
if (ret)
return ret;
return 0;
}
/*
* Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
* pointers for padding, DER value and hash. And finally, constructs EM'
* which includes hash of complete CSF header and ESBC image. If SG flag
* is on, hash of SG table and entries is also included.
*/
static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
{
/*
* RSA PKCSv1.5 encoding format for encoded message is below
* EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
* PS is Padding String
* DER is DER value for SHA-256
* Hash is SHA-256 hash
* *********************************************************
* representative points to first byte of EM initially and is
* filled with 0x0
* representative is incremented by 1 and second byte is filled
* with 0x1
* padding points to third byte of EM
* digest points to full length of EM - 32 bytes
* hash_id (DER value) points to 19 bytes before pDigest
* separator is one byte which separates padding and DER
*/
size_t len;
u8 *representative;
u8 *padding, *digest;
u8 *hash_id, *separator;
int i;
len = (get_key_len(img) / 2) - 1;
representative = img->img_encoded_hash_second;
representative[0] = 0;
representative[1] = 1; /* block type 1 */
padding = &representative[2];
digest = &representative[1] + len - 32;
hash_id = digest - sizeof(hash_identifier);
separator = hash_id - 1;
/* fill padding area pointed by padding with 0xff */
memset(padding, 0xff, separator - padding);
/* fill byte pointed by separator */
*separator = 0;
/* fill SHA-256 DER value pointed by HashId */
memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
/* fill hash pointed by Digest */
for (i = 0; i < SHA256_BYTES; i++)
digest[i] = hash_val[i];
}
/*
* Reads and validates the ESBC client header.
* This function reads key and signature from the ESBC client header.
* If Scatter/Gather flag is on, lengths and offsets of images
* present as SG entries are also read. This function also checks
* whether the header is valid or not.
*/
static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
{
char buf[20];
struct fsl_secboot_img_hdr *hdr = &img->hdr;
void *esbc = (u8 *)img->ehdrloc;
u8 *k, *s;
#ifdef CONFIG_KEY_REVOCATION
u32 ret;
u32 key_num, key_revoc_flag, size;
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
struct ie_key_info *ie_info;
u32 ie_num, ie_revoc_flag, ie_key_len;
#endif
int key_found = 0;
/* check barker code */
if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
return ERROR_ESBC_CLIENT_HEADER_BARKER;
sprintf(buf, "%p", hdr->pimg);
setenv("img_addr", buf);
if (!hdr->img_size)
return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
/* Key checking*/
#ifdef CONFIG_KEY_REVOCATION
if (check_srk(img)) {
if ((hdr->len_kr.num_srk == 0) ||
(hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
key_num = hdr->len_kr.srk_sel;
if (key_num == 0 || key_num > hdr->len_kr.num_srk)
return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
/* Get revoc key from sfp */
key_revoc_flag = get_key_revoc();
ret = is_key_revoked(key_num, key_revoc_flag);
if (ret)
return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
size = hdr->len_kr.num_srk * sizeof(struct srk_table);
memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
ret = validate_srk_tbl(img->srk_tbl, hdr->len_kr.num_srk);
if (ret != 0)
return ret;
img->key_len = img->srk_tbl[key_num - 1].key_len;
memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
img->key_len);
key_found = 1;
}
#endif
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
if (!key_found && check_ie(img)) {
if (get_ie_info_addr(&img->ie_addr))
return ERROR_IE_TABLE_NOT_FOUND;
ie_info = (struct ie_key_info *)img->ie_addr;
if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
ie_num = hdr->ie_key_sel;
if (ie_num == 0 || ie_num > ie_info->num_keys)
return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
ie_revoc_flag = ie_info->key_revok;
if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
if (!((ie_key_len == 2 * KEY_SIZE_BYTES / 4) ||
(ie_key_len == 2 * KEY_SIZE_BYTES / 2) ||
(ie_key_len == 2 * KEY_SIZE_BYTES)))
return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
ie_key_len);
img->key_len = ie_key_len;
key_found = 1;
}
#endif
if (key_found == 0) {
/* check key length */
if (!((hdr->key_len == 2 * KEY_SIZE_BYTES / 4) ||
(hdr->key_len == 2 * KEY_SIZE_BYTES / 2) ||
(hdr->key_len == 2 * KEY_SIZE_BYTES)))
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
img->key_len = hdr->key_len;
key_found = 1;
}
/* check signaure */
if (get_key_len(img) == 2 * hdr->sign_len) {
/* check signature length */
if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
(hdr->sign_len == KEY_SIZE_BYTES / 2) ||
(hdr->sign_len == KEY_SIZE_BYTES)))
return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
} else {
return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
}
memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
/* No SG support */
if (hdr->sg_flag)
return ERROR_ESBC_CLIENT_HEADER_SG;
/* modulus most significant bit should be set */
k = (u8 *)&img->img_key;
if ((k[0] & 0x80) == 0)
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
/* modulus value should be odd */
if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
/* Check signature value < modulus value */
s = (u8 *)&img->img_sign;
if (!(memcmp(s, k, hdr->sign_len) < 0))
return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
return ESBC_VALID_HDR;
}
static inline int str2longbe(const char *p, ulong *num)
{
char *endptr;
ulong tmp;
if (!p) {
return 0;
} else {
tmp = simple_strtoul(p, &endptr, 16);
if (sizeof(ulong) == 4)
*num = cpu_to_be32(tmp);
else
*num = cpu_to_be64(tmp);
}
return *p != '\0' && *endptr == '\0';
}
int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
ulong hash[SHA256_BYTES/sizeof(ulong)];
char hash_str[NUM_HEX_CHARS + 1];
ulong addr = simple_strtoul(argv[1], NULL, 16);
struct fsl_secboot_img_priv *img;
struct fsl_secboot_img_hdr *hdr;
void *esbc;
int ret, i, hash_cmd = 0;
u32 srk_hash[8];
uint32_t key_len;
struct key_prop prop;
#if !defined(USE_HOSTCC)
struct udevice *mod_exp_dev;
#endif
if (argc == 3) {
char *cp = argv[2];
int i = 0;
if (*cp == '0' && *(cp + 1) == 'x')
cp += 2;
/* The input string expected is in hex, where
* each 4 bits would be represented by a hex
* sha256 hash is 256 bits long, which would mean
* num of characters = 256 / 4
*/
if (strlen(cp) != SHA256_NIBBLES) {
printf("%s is not a 256 bits hex string as expected\n",
argv[2]);
return -1;
}
for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
NUM_HEX_CHARS);
hash_str[NUM_HEX_CHARS] = '\0';
if (!str2longbe(hash_str, &hash[i])) {
printf("%s is not a 256 bits hex string ",
argv[2]);
return -1;
}
}
hash_cmd = 1;
}
img = malloc(sizeof(struct fsl_secboot_img_priv));
if (!img)
return -1;
memset(img, 0, sizeof(struct fsl_secboot_img_priv));
hdr = &img->hdr;
img->ehdrloc = addr;
esbc = (u8 *)img->ehdrloc;
memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
/* read and validate esbc header */
ret = read_validate_esbc_client_header(img);
if (ret != ESBC_VALID_HDR) {
fsl_secboot_handle_error(ret);
goto exit;
}
/* SRKH present in SFP */
for (i = 0; i < NUM_SRKH_REGS; i++)
srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
/*
* Calculate hash of key obtained via offset present in
* ESBC uboot client hdr
*/
ret = calc_img_key_hash(img);
if (ret) {
fsl_secblk_handle_error(ret);
goto exit;
}
/* Compare hash obtained above with SRK hash present in SFP */
if (hash_cmd)
ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
else
ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
if (!hash_cmd && check_ie(img))
ret = 0;
#endif
if (ret != 0) {
fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
goto exit;
}
ret = calc_esbchdr_esbc_hash(img);
if (ret) {
fsl_secblk_handle_error(ret);
goto exit;
}
/* Construct encoded hash EM' wrt PKCSv1.5 */
construct_img_encoded_hash_second(img);
/* Fill prop structure for public key */
memset(&prop, 0, sizeof(struct key_prop));
key_len = get_key_len(img) / 2;
prop.modulus = img->img_key;
prop.public_exponent = img->img_key + key_len;
prop.num_bits = key_len * 8;
prop.exp_len = key_len;
ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
if (ret) {
printf("RSA: Can't find Modular Exp implementation\n");
return -EINVAL;
}
ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
&prop, img->img_encoded_hash);
if (ret) {
fsl_secblk_handle_error(ret);
goto exit;
}
/*
* compare the encoded messages EM' and EM wrt RSA PKCSv1.5
* memcmp returns zero on success
* memcmp returns non-zero on failure
*/
ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
img->hdr.sign_len);
if (ret) {
fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_EM);
goto exit;
}
printf("esbc_validate command successful\n");
exit:
return 0;
}

@ -16,21 +16,6 @@
DECLARE_GLOBAL_DATA_PTR;
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
unsigned int controller_number,
unsigned int dimm_number)
{
const char dimm_model[] = "RAW timing DDR";
if ((controller_number == 0) && (dimm_number == 0)) {
memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t));
memset(pdimm->mpart, 0, sizeof(pdimm->mpart));
memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1);
}
return 0;
}
void fsl_ddr_board_options(memctl_options_t *popts,
dimm_params_t *pdimm,
unsigned int ctrl_num)

@ -6,35 +6,6 @@
#ifndef __DDR_H__
#define __DDR_H__
dimm_params_t ddr_raw_timing = {
.n_ranks = 2,
.rank_density = 2147483648u,
.capacity = 4294967296u,
.primary_sdram_width = 64,
.ec_sdram_width = 8,
.registered_dimm = 0,
.mirrored_dimm = 0,
.n_row_addr = 15,
.n_col_addr = 10,
.n_banks_per_sdram_device = 8,
.edc_config = 2, /* ECC */
.burst_lengths_bitmask = 0x0c,
.tckmin_x_ps = 1071,
.caslat_x = 0xfe << 4, /* 5,6,7,8,9,10,11 */
.taa_ps = 13125,
.twr_ps = 15000,
.trcd_ps = 13125,
.trrd_ps = 6000,
.trp_ps = 13125,
.tras_ps = 34000,
.trc_ps = 48125,
.trfc_ps = 260000,
.twtr_ps = 7500,
.trtp_ps = 7500,
.refresh_rate_ps = 7800000,
.tfaw_ps = 35000,
};
struct board_specific_parameters {
u32 n_ranks;
u32 datarate_mhz_high;

@ -0,0 +1,105 @@
DSP side awareness for Freescale heterogeneous multicore chips based on
StarCore and Power Architecture
===============================================================
powerpc/mpc85xx code ve APIs and function to get the number,
configuration and frequencies of all PowerPC cores and devices
connected to them, but it didnt have the similar code ofr HEterogeneous
SC3900/DSP cores and such devices like CPRI, MAPLE, MAPLE-ULB etc.
Code for DSP side awareness provides such functionality for Freescale
Heterogeneous SoCs which are chasis-2 compliant like B4860 and B4420
As part of this feature, following changes have been made:
==========================================================
1. Changed files:
=================
- arch/powerpc/cpu/mpc85xx/cpu.c
Code added in this file to print the DSP cores and other device's(CPRI,
MAPLE etc) frequencies
- arch/powerpc/cpu/mpc85xx/speed.c
Added Defines and code to extract the frequncy information for all
required cores and devices from RCW and System frequency
- arch/powerpc/cpu/mpc8xxx/cpu.c
Added API to get the number of SC cores in running system and Their BIT
MASK, similar to the code written for PowerPC
- arch/powerpc/include/asm/config_mpc85xx.h
Added top level CONFIG to identify presence of HETEROGENUOUS clusters
in the system and CONFIGS for SC3900/DSP components
- arch/powerpc/include/asm/processor.h
- include/common.h
Added newly added Functions Declaration
- include/e500.h
Global structure updated for dsp cores and other components
2. CONFIGs ADDED
================
CONFIG_HETROGENOUS_CLUSTERS - Define for checking the presence of
DSP/SC3900 core clusters
CONFIG_SYS_FSL_NUM_CC_PLLS - Define for number of PLLs
Though there are only 4 PLLs in B4, but in sequence of PLLs from PLL1 -
PLL5, PLL3 is Reserved(as mentioned in RM), so this define contains the
value as 5 not 4, to iterate over all PLLs while coding
CONFIG_SYS_MAPLE - Define for MAPLE Baseband Accelerator
CONFIG_SYS_CPRI - Define for CPRI Interface
CONFIG_PPC_CLUSTER_START - Start index of ppc clusters
CONFIG_DSP_CLUSTER_START - Start index of dsp clusters
Following are the defines for PLL's index that provide the Clocking to
CPRI, ULB and ETVE components
CONFIG_SYS_CPRI_CLK - Define PLL index for CPRI clock
CONFIG_SYS_ULB_CLK - Define PLL index for ULB clock
CONFIG_SYS_ETVPE_CLK - Define PLL index for ETVPE clock
3. Changes in MPC85xx_SYS_INFO Global structure
===============================================
DSP cores and other device's components have been added in this structure.
freq_processor_dsp[CONFIG_MAX_DSP_CPUS] - Array to contain the DSP core's frequencies
freq_cpri - To store CPRI frequency
freq_maple - To store MAPLE frequency
freq_maple_ulb - To store MAPLE-ULB frequency
freq_maple_etvpe - To store MAPLE-eTVPE frequency
4. U-BOOT LOGS
==============
4.1 B4860QDS board
Boot from NOR flash
U-Boot 2014.07-00222-g70587a8-dirty (Aug 07 2014 - 13:15:47)
CPU0: B4860E, Version: 2.0, (0x86880020)
Core: e6500, Version: 2.0, (0x80400020) Clock Configuration:
CPU0:1600 MHz, CPU1:1600 MHz, CPU2:1600 MHz, CPU3:1600 MHz,
DSP CPU0:1200 MHz, DSP CPU1:1200 MHz, DSP CPU2:1200 MHz, DSP CPU3:1200 MHz,
DSP CPU4:1200 MHz, DSP CPU5:1200 MHz,
CCB:666.667 MHz,
DDR:933.333 MHz (1866.667 MT/s data rate) (Asynchronous), IFC:166.667 MHz
CPRI:600 MHz
MAPLE:600 MHz, MAPLE-ULB:800 MHz, MAPLE-eTVPE:1000 MHz
FMAN1: 666.667 MHz
QMAN: 333.333 MHz
CPUn - PowerPC core
DSP CPUn - SC3900 core
Shaveta Leekha(shaveta@freescale.com)
Created August 7, 2014
===========================================

@ -0,0 +1,41 @@
/*
* (C) Copyright 2015
*
* SPDX-License-Identifier: GPL-2.0+
*/
esbc_validate command
========================================
1. esbc_validate command is meant for validating header and
signature of images (Boot Script and ESBC uboot client).
SHA-256 and RSA operations are performed using SEC block in HW.
This command works on both PBL based and Non PBL based Freescale
platforms.
Command usage:
esbc_validate img_hdr_addr [pub_key_hash]
esbc_validate hdr_addr <hash_val>
Validates signature using RSA verification.
$hdr_addr Address of header of the image to be validated.
$hash_val -Optional. It provides Hash of public/srk key to be
used to verify signature.
2. ESBC uboot client can be linux. Additionally, rootfs and device
tree blob can also be signed.
3. In the event of header or signature failure in validation,
ITS and ITF bits determine further course of action.
4. In case of soft failure, appropriate error is dumped on console.
5. In case of hard failure, SoC is issued RESET REQUEST after
dumping error on the console.
6. KEY REVOCATION Feature:
QorIQ platforms like B4/T4 have support of srk key table and key
revocation in ISBC code in Silicon.
The srk key table allows the user to have a key table with multiple
keys and revoke any key in case of particular key gets compromised.
In case the ISBC code uses the key revocation and srk key table to
verify the u-boot code, the subsequent chain of trust should also
use the same.
6. ISBC KEY EXTENSION Feature:
This feature allows large number of keys to be used for esbc validation
of images. A set of public keys is being signed and validated by ISBC
which can be further used for esbc validation of images.

@ -4,4 +4,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_RSA) += mod_exp_uclass.o mod_exp_sw.o
obj-$(CONFIG_RSA) += mod_exp_uclass.o
obj-$(CONFIG_RSA_SOFTWARE_EXP) += mod_exp_sw.o

@ -53,3 +53,11 @@ config DM_CROS_EC
but otherwise makes few changes. Since cros_ec also supports
LPC (which doesn't support driver model yet), a full
conversion is not yet possible.
config CONFIG_FSL_SEC_MON
bool "Enable FSL SEC_MON Driver"
help
Freescale Security Monitor block is responsible for monitoring
system states.
Security Monitor can be transitioned on any security failures,
like software violations or hardware security violations.

@ -28,3 +28,4 @@ obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
obj-$(CONFIG_STATUS_LED) += status_led.o
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o

@ -0,0 +1,146 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <fsl_sec_mon.h>
int change_sec_mon_state(u32 initial_state, u32 final_state)
{
struct ccsr_sec_mon_regs *sec_mon_regs = (void *)
(CONFIG_SYS_SEC_MON_ADDR);
u32 sts = sec_mon_in32(&sec_mon_regs->hp_stat);
int timeout = 10;
if ((sts & HPSR_SSM_ST_MASK) != initial_state)
return -1;
if (initial_state == HPSR_SSM_ST_TRUST) {
switch (final_state) {
case HPSR_SSM_ST_NON_SECURE:
printf("SEC_MON state transitioning to Soft Fail.\n");
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_SV);
/*
* poll till SEC_MON is in
* Soft Fail state
*/
while (((sts & HPSR_SSM_ST_MASK) !=
HPSR_SSM_ST_SOFT_FAIL)) {
while (timeout) {
sts = sec_mon_in32
(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) ==
HPSR_SSM_ST_SOFT_FAIL)
break;
udelay(10);
timeout--;
}
}
if (timeout == 0) {
printf("SEC_MON state transition timeout.\n");
return -1;
}
timeout = 10;
printf("SEC_MON state transitioning to Non Secure.\n");
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SSM_ST);
/*
* poll till SEC_MON is in
* Non Secure state
*/
while (((sts & HPSR_SSM_ST_MASK) !=
HPSR_SSM_ST_NON_SECURE)) {
while (timeout) {
sts = sec_mon_in32
(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) ==
HPSR_SSM_ST_NON_SECURE)
break;
udelay(10);
timeout--;
}
}
if (timeout == 0) {
printf("SEC_MON state transition timeout.\n");
return -1;
}
break;
case HPSR_SSM_ST_SOFT_FAIL:
printf("SEC_MON state transitioning to Soft Fail.\n");
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
/*
* polling loop till SEC_MON is in
* Soft Fail state
*/
while (((sts & HPSR_SSM_ST_MASK) !=
HPSR_SSM_ST_SOFT_FAIL)) {
while (timeout) {
sts = sec_mon_in32
(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) ==
HPSR_SSM_ST_SOFT_FAIL)
break;
udelay(10);
timeout--;
}
}
if (timeout == 0) {
printf("SEC_MON state transition timeout.\n");
return -1;
}
break;
default:
return -1;
}
} else if (initial_state == HPSR_SSM_ST_NON_SECURE) {
switch (final_state) {
case HPSR_SSM_ST_SOFT_FAIL:
printf("SEC_MON state transitioning to Soft Fail.\n");
sec_mon_setbits32(&sec_mon_regs->hp_com, HPCOMR_SW_FSV);
/*
* polling loop till SEC_MON is in
* Soft Fail state
*/
while (((sts & HPSR_SSM_ST_MASK) !=
HPSR_SSM_ST_SOFT_FAIL)) {
while (timeout) {
sts = sec_mon_in32
(&sec_mon_regs->hp_stat);
if ((sts & HPSR_SSM_ST_MASK) ==
HPSR_SSM_ST_SOFT_FAIL)
break;
udelay(10);
timeout--;
}
}
if (timeout == 0) {
printf("SEC_MON state transition timeout.\n");
return -1;
}
break;
default:
return -1;
}
}
return 0;
}

@ -553,7 +553,9 @@ static inline int cpumask_next(int cpu, unsigned int mask)
iter++, cpu = cpumask_next(cpu, mask)) \
int cpu_numcores (void);
int cpu_num_dspcores(void);
u32 cpu_mask (void);
u32 cpu_dsp_mask(void);
int is_core_valid (unsigned int);
int probecpu (void);
int checkcpu (void);

@ -220,7 +220,6 @@
#define CONFIG_CHIP_SELECTS_PER_CTRL (2 * CONFIG_DIMM_SLOTS_PER_CTLR)
#define CONFIG_DDR_SPD
#define CONFIG_SYS_DDR_RAW_TIMING
#define CONFIG_SYS_FSL_DDR3
#define CONFIG_SYS_SPD_BUS_NUM 0

@ -11,6 +11,9 @@
typedef struct
{
unsigned long freq_processor[CONFIG_MAX_CPUS];
#ifdef CONFIG_HETROGENOUS_CLUSTERS
unsigned long freq_processor_dsp[CONFIG_MAX_DSP_CPUS];
#endif
unsigned long freq_systembus;
unsigned long freq_ddrbus;
unsigned long freq_localbus;
@ -24,6 +27,14 @@ typedef struct
#ifdef CONFIG_SYS_DPAA_PME
unsigned long freq_pme;
#endif
#ifdef CONFIG_SYS_CPRI
unsigned long freq_cpri;
#endif
#ifdef CONFIG_SYS_MAPLE
unsigned long freq_maple;
unsigned long freq_maple_ulb;
unsigned long freq_maple_etvpe;
#endif
#ifdef CONFIG_SYS_FSL_SINGLE_SOURCE_CLK
unsigned char diff_sysclk;
#endif

@ -0,0 +1,58 @@
/*
* Common internal memory map for some Freescale SoCs
*
* Copyright 2015 Freescale Semiconductor, Inc.
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __FSL_SEC_MON_H
#define __FSL_SEC_MON_H
#include <common.h>
#include <asm/io.h>
#ifdef CONFIG_SYS_FSL_SEC_MON_LE
#define sec_mon_in32(a) in_le32(a)
#define sec_mon_out32(a, v) out_le32(a, v)
#define sec_mon_in16(a) in_le16(a)
#define sec_mon_clrbits32 clrbits_le32
#define sec_mon_setbits32 setbits_le32
#elif defined(CONFIG_SYS_FSL_SEC_MON_BE)
#define sec_mon_in32(a) in_be32(a)
#define sec_mon_out32(a, v) out_be32(a, v)
#define sec_mon_in16(a) in_be16(a)
#define sec_mon_clrbits32 clrbits_be32
#define sec_mon_setbits32 setbits_be32
#else
#error Neither CONFIG_SYS_FSL_SEC_MON_LE nor CONFIG_SYS_FSL_SEC_MON_BE defined
#endif
struct ccsr_sec_mon_regs {
u8 reserved0[0x04];
u32 hp_com; /* 0x04 SEC_MON_HP Command Register */
u8 reserved2[0x0c];
u32 hp_stat; /* 0x08 SEC_MON_HP Status Register */
};
#define HPCOMR_SW_SV 0x100 /* Security Violation bit */
#define HPCOMR_SW_FSV 0x200 /* Fatal Security Violation bit */
#define HPCOMR_SSM_ST 0x1 /* SSM_ST field in SEC_MON command */
#define HPSR_SSM_ST_CHECK 0x900 /* SEC_MON is in check state */
#define HPSR_SSM_ST_NON_SECURE 0xb00 /* SEC_MON is in non secure state */
#define HPSR_SSM_ST_TRUST 0xd00 /* SEC_MON is in trusted state */
#define HPSR_SSM_ST_SOFT_FAIL 0x300 /* SEC_MON is in soft fail state */
#define HPSR_SSM_ST_MASK 0xf00 /* Mask for SSM_ST field */
/*
* SEC_MON read. This specifies the possible reads
* from the SEC_MON
*/
enum {
SEC_MON_SSM_ST,
SEC_MON_SW_FSV,
SEC_MON_SW_SV,
};
int change_sec_mon_state(uint32_t initial_state, uint32_t final_state);
#endif /* __FSL_SEC_MON_H */

@ -0,0 +1,128 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _FSL_SECBOOT_ERR_H
#define _FSL_SECBOOT_ERR_H
#define ERROR_ESBC_PAMU_INIT 0x100000
#define ERROR_ESBC_SEC_RESET 0x200000
#define ERROR_ESBC_SEC_INIT 0x400000
#define ERROR_ESBC_SEC_DEQ 0x800000
#define ERROR_ESBC_SEC_DEQ_TO 0x1000000
#define ERROR_ESBC_SEC_ENQ 0x2000000
#define ERROR_ESBC_SEC_JOBQ_STATUS 0x4000000
#define ERROR_ESBC_CLIENT_CPUID_NO_MATCH 0x1
#define ERROR_ESBC_CLIENT_HDR_LOC 0x2
#define ERROR_ESBC_CLIENT_HEADER_BARKER 0x4
#define ERROR_ESBC_CLIENT_HEADER_KEY_LEN 0x8
#define ERROR_ESBC_CLIENT_HEADER_SIG_LEN 0x10
#define ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED 0x11
#define ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY 0x12
#define ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM 0x13
#define ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN 0x14
#define ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED 0x15
#define ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY 0x16
#define ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM 0x17
#define ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN 0x18
#define ERROR_IE_TABLE_NOT_FOUND 0x19
#define ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN 0x20
#define ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1 0x40
#define ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2 0x80
#define ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD 0x100
#define ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP 0x200
#define ERROR_ESBC_CLIENT_HASH_COMPARE_KEY 0x400
#define ERROR_ESBC_CLIENT_HASH_COMPARE_EM 0x800
#define ERROR_ESBC_CLIENT_SSM_TRUSTSTS 0x1000
#define ERROR_ESBC_CLIENT_BAD_ADDRESS 0x2000
#define ERROR_ESBC_CLIENT_MISC 0x4000
#define ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD 0x8000
#define ERROR_ESBC_CLIENT_HEADER_SG 0x10000
#define ERROR_ESBC_CLIENT_HEADER_IMG_SIZE 0x20000
#define ERROR_ESBC_WRONG_CMD 0x40000
#define ERROR_ESBC_MISSING_BOOTM 0x80000
#define ERROR_ESBC_CLIENT_MAX 0x0
struct fsl_secboot_errcode {
int errcode;
const char *name;
};
static const struct fsl_secboot_errcode fsl_secboot_errcodes[] = {
{ ERROR_ESBC_PAMU_INIT,
"Error in initializing PAMU"},
{ ERROR_ESBC_SEC_RESET,
"Error in resetting Job ring of SEC"},
{ ERROR_ESBC_SEC_INIT,
"Error in initializing SEC"},
{ ERROR_ESBC_SEC_ENQ,
"Error in enqueue operation by SEC"},
{ ERROR_ESBC_SEC_DEQ_TO,
"Dequeue operation by SEC is timed out"},
{ ERROR_ESBC_SEC_DEQ,
"Error in dequeue operation by SEC"},
{ ERROR_ESBC_SEC_JOBQ_STATUS,
"Error in status of the job submitted to SEC"},
{ ERROR_ESBC_CLIENT_CPUID_NO_MATCH,
"Current core is not boot core i.e core0" },
{ ERROR_ESBC_CLIENT_HDR_LOC,
"Header address not in allowed memory range" },
{ ERROR_ESBC_CLIENT_HEADER_BARKER,
"Wrong barker code in header" },
{ ERROR_ESBC_CLIENT_HEADER_KEY_LEN,
"Wrong public key length in header" },
{ ERROR_ESBC_CLIENT_HEADER_SIG_LEN,
"Wrong signature length in header" },
{ ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN,
"Public key length not twice of signature length" },
{ ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1,
"Public key Modulus most significant bit not set" },
{ ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2,
"Public key Modulus in header not odd" },
{ ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD,
"Signature not less than modulus" },
{ ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP,
"Entry point not in allowed space or one of the SG entries" },
{ ERROR_ESBC_CLIENT_HASH_COMPARE_KEY,
"Public key hash comparison failed" },
{ ERROR_ESBC_CLIENT_HASH_COMPARE_EM,
"RSA verification failed" },
{ ERROR_ESBC_CLIENT_SSM_TRUSTSTS,
"SNVS not in TRUSTED state" },
{ ERROR_ESBC_CLIENT_BAD_ADDRESS,
"Bad address error" },
{ ERROR_ESBC_CLIENT_MISC,
"Miscallaneous error" },
{ ERROR_ESBC_CLIENT_HEADER_SG,
"No SG support" },
{ ERROR_ESBC_CLIENT_HEADER_IMG_SIZE,
"Invalid Image size" },
{ ERROR_ESBC_WRONG_CMD,
"Unknown cmd/Wrong arguments. Core in infinite loop"},
{ ERROR_ESBC_MISSING_BOOTM,
"Bootm command missing from bootscript" },
{ ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED,
"Selected key is revoked" },
{ ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY,
"Wrong key entry" },
{ ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM,
"Wrong key is selected" },
{ ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN,
"Wrong srk public key len in header" },
{ ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED,
"Selected IE key is revoked" },
{ ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY,
"Wrong key entry in IE Table" },
{ ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM,
"Wrong IE key is selected" },
{ ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN,
"Wrong IE public key len in header" },
{ ERROR_IE_TABLE_NOT_FOUND,
"Information about IE Table missing" },
{ ERROR_ESBC_CLIENT_MAX, "NULL" }
};
void fsl_secboot_handle_error(int error);
#endif

@ -0,0 +1,85 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _FSL_SFP_SNVS_
#define _FSL_SFP_SNVS_
#include <common.h>
#include <config.h>
#include <asm/io.h>
#ifdef CONFIG_SYS_FSL_SRK_LE
#define srk_in32(a) in_le32(a)
#else
#define srk_in32(a) in_be32(a)
#endif
#ifdef CONFIG_SYS_FSL_SFP_LE
#define sfp_in32(a) in_le32(a)
#define sfp_out32(a, v) out_le32(a, v)
#define sfp_in16(a) in_le16(a)
#elif defined(CONFIG_SYS_FSL_SFP_BE)
#define sfp_in32(a) in_be32(a)
#define sfp_out32(a, v) out_be32(a, v)
#define sfp_in16(a) in_be16(a)
#else
#error Neither CONFIG_SYS_FSL_SFP_LE nor CONFIG_SYS_FSL_SFP_BE is defined
#endif
/* Number of SRKH registers */
#define NUM_SRKH_REGS 8
#ifdef CONFIG_SYS_FSL_SFP_VER_3_2
struct ccsr_sfp_regs {
u32 ospr; /* 0x200 */
u32 ospr1; /* 0x204 */
u32 reserved1[4];
u32 fswpr; /* 0x218 FSL Section Write Protect */
u32 fsl_uid; /* 0x21c FSL UID 0 */
u32 fsl_uid_1; /* 0x220 FSL UID 0 */
u32 reserved2[12];
u32 srk_hash[8]; /* 0x254 Super Root Key Hash */
u32 oem_uid; /* 0x274 OEM UID 0*/
u32 oem_uid_1; /* 0x278 OEM UID 1*/
u32 oem_uid_2; /* 0x27c OEM UID 2*/
u32 oem_uid_3; /* 0x280 OEM UID 3*/
u32 oem_uid_4; /* 0x284 OEM UID 4*/
u32 reserved3[8];
};
#elif defined(CONFIG_SYS_FSL_SFP_VER_3_0)
struct ccsr_sfp_regs {
u32 ospr; /* 0x200 */
u32 reserved0[14];
u32 srk_hash[NUM_SRKH_REGS]; /* 0x23c Super Root Key Hash */
u32 oem_uid; /* 0x9c OEM Unique ID */
u8 reserved2[0x04];
u32 ovpr; /* 0xA4 Intent To Secure */
u8 reserved4[0x08];
u32 fsl_uid; /* 0xB0 FSL Unique ID */
u8 reserved5[0x04];
u32 fsl_spfr0; /* Scratch Pad Fuse Register 0 */
u32 fsl_spfr1; /* Scratch Pad Fuse Register 1 */
};
#else
struct ccsr_sfp_regs {
u8 reserved0[0x40];
u32 ospr; /* 0x40 OEM Security Policy Register */
u8 reserved2[0x38];
u32 srk_hash[8]; /* 0x7c Super Root Key Hash */
u32 oem_uid; /* 0x9c OEM Unique ID */
u8 reserved4[0x4];
u32 ovpr; /* 0xA4 OEM Validation Policy Register */
u8 reserved8[0x8];
u32 fsl_uid; /* 0xB0 FSL Unique ID */
};
#endif
#define ITS_MASK 0x00000004
#define ITS_BIT 2
#define OSPR_KEY_REVOC_SHIFT 13
#define OSPR_KEY_REVOC_MASK 0x0000e000
#endif

@ -0,0 +1,199 @@
/*
* Copyright 2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _FSL_VALIDATE_H_
#define _FSL_VALIDATE_H_
#include <fsl_sec.h>
#include <fsl_sec_mon.h>
#include <command.h>
#include <linux/types.h>
#define WORD_SIZE 4
/* Minimum and maximum size of RSA signature length in bits */
#define KEY_SIZE 4096
#define KEY_SIZE_BYTES (KEY_SIZE/8)
#define KEY_SIZE_WORDS (KEY_SIZE_BYTES/(WORD_SIZE))
extern struct jobring jr;
#ifdef CONFIG_KEY_REVOCATION
/* Srk table and key revocation check */
#define SRK_FLAG 0x01
#define UNREVOCABLE_KEY 4
#define ALIGN_REVOC_KEY 3
#define MAX_KEY_ENTRIES 4
#endif
/* Barker code size in bytes */
#define ESBC_BARKER_LEN 4 /* barker code length in ESBC uboot client */
/* header */
/* No-error return values */
#define ESBC_VALID_HDR 0 /* header is valid */
/* Maximum number of SG entries allowed */
#define MAX_SG_ENTRIES 8
/*
* ESBC uboot client header structure.
* The struct contain the following fields
* barker code
* public key offset
* pub key length
* signature offset
* length of the signature
* ptr to SG table
* no of entries in SG table
* esbc ptr
* size of esbc
* esbc entry point
* Scatter gather flag
* UID flag
* FSL UID
* OEM UID
* Here, pub key is modulus concatenated with exponent
* of equal length
*/
struct fsl_secboot_img_hdr {
u8 barker[ESBC_BARKER_LEN]; /* barker code */
union {
u32 pkey; /* public key offset */
#ifdef CONFIG_KEY_REVOCATION
u32 srk_tbl_off;
#endif
};
union {
u32 key_len; /* pub key length in bytes */
#ifdef CONFIG_KEY_REVOCATION
struct {
u32 srk_table_flag:8;
u32 srk_sel:8;
u32 num_srk:16;
} len_kr;
#endif
};
u32 psign; /* signature offset */
u32 sign_len; /* length of the signature in bytes */
union {
struct fsl_secboot_sg_table *psgtable; /* ptr to SG table */
u8 *pimg; /* ptr to ESBC client image */
};
union {
u32 sg_entries; /* no of entries in SG table */
u32 img_size; /* ESBC client image size in bytes */
};
ulong img_start; /* ESBC client entry point */
u32 sg_flag; /* Scatter gather flag */
u32 uid_flag;
u32 fsl_uid_0;
u32 oem_uid_0;
u32 reserved1[2];
u32 fsl_uid_1;
u32 oem_uid_1;
u32 reserved2[2];
u32 ie_flag;
u32 ie_key_sel;
};
#if defined(CONFIG_FSL_ISBC_KEY_EXT)
struct ie_key_table {
u32 key_len;
u8 pkey[2 * KEY_SIZE_BYTES];
};
struct ie_key_info {
uint32_t key_revok;
uint32_t num_keys;
struct ie_key_table ie_key_tbl[32];
};
#endif
#ifdef CONFIG_KEY_REVOCATION
struct srk_table {
u32 key_len;
u8 pkey[2 * KEY_SIZE_BYTES];
};
#endif
/*
* SG table.
*/
#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
/*
* This struct contains the following fields
* length of the segment
* source address
*/
struct fsl_secboot_sg_table {
u32 len; /* length of the segment in bytes */
ulong src_addr; /* ptr to the data segment */
};
#else
/*
* This struct contains the following fields
* length of the segment
* Destination Target ID
* source address
* destination address
*/
struct fsl_secboot_sg_table {
u32 len;
u32 trgt_id;
ulong src_addr;
ulong dst_addr;
};
#endif
/*
* ESBC private structure.
* Private structure used by ESBC to store following fields
* ESBC client key
* ESBC client key hash
* ESBC client Signature
* Encoded hash recovered from signature
* Encoded hash of ESBC client header plus ESBC client image
*/
struct fsl_secboot_img_priv {
uint32_t hdr_location;
ulong ie_addr;
u32 key_len;
struct fsl_secboot_img_hdr hdr;
u8 img_key[2 * KEY_SIZE_BYTES]; /* ESBC client key */
u8 img_key_hash[32]; /* ESBC client key hash */
#ifdef CONFIG_KEY_REVOCATION
struct srk_table srk_tbl[MAX_KEY_ENTRIES];
#endif
u8 img_sign[KEY_SIZE_BYTES]; /* ESBC client signature */
u8 img_encoded_hash[KEY_SIZE_BYTES]; /* EM wrt RSA PKCSv1.5 */
/* Includes hash recovered after
* signature verification
*/
u8 img_encoded_hash_second[KEY_SIZE_BYTES];/* EM' wrt RSA PKCSv1.5 */
/* Includes hash of
* ESBC client header plus
* ESBC client image
*/
struct fsl_secboot_sg_table sgtbl[MAX_SG_ENTRIES]; /* SG table */
u32 ehdrloc; /* ESBC client location */
};
int fsl_secboot_validate(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[]);
int fsl_secboot_blob_encap(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[]);
int fsl_secboot_blob_decap(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[]);
#endif

@ -7,4 +7,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o rsa-mod-exp.o
obj-$(CONFIG_FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o

Loading…
Cancel
Save