Commit feb3649257fb84e623d25485c4b9ec64e5d06fc2

Authored by BJ DevOps Team

Merge remote-tracking branch 'origin/imx_v2020.04' into lf_v2020.04

* origin/imx_v2020.04:
  MA-18775 system will hang about 3s when boot up kernel
  MA-18680-2 Support derive rpmb key from BKEK
  MA-18680-1 Support BKEK generation
  MLK-25287 imx8mq/mp: Use index parameter of gadget interrupt handler
  MLK-25271: new qspihdr subsystem for u-boot q(f)spi boot

Showing 24 changed files Side-by-side Diff

arch/arm/dts/imx8mp-evk.dts
... ... @@ -13,7 +13,7 @@
13 13 compatible = "fsl,imx8mp-evk", "fsl,imx8mp";
14 14  
15 15 chosen {
16   - bootargs = "console=ttymxc1,115200 earlycon=ec_imx6q,0x30890000,115200";
  16 + bootargs = "console=ttymxc1,115200";
17 17 stdout-path = &uart2;
18 18 };
19 19  
arch/arm/mach-imx/Kconfig
... ... @@ -157,6 +157,14 @@
157 157 This is similar to kobs-ng, which is used in Linux as separate
158 158 rootfs package.
159 159  
  160 +config CMD_QSPIHDR
  161 + bool "Q(F)SPI Boot Config Header command"
  162 + depends on DM_SPI_FLASH
  163 + default y
  164 + help
  165 + Boot from Q(F)SPI need a boot config header, this command can
  166 + help to check if header already exists or add one if not.
  167 +
160 168 config FSL_MFGPROT
161 169 bool "Support the 'mfgprot' command"
162 170 depends on IMX_HAB || AHAB_BOOT
arch/arm/mach-imx/Makefile
... ... @@ -78,6 +78,7 @@
78 78 obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
79 79 obj-$(CONFIG_CMD_DEKBLOB) += cmd_dek.o
80 80 obj-$(CONFIG_CMD_NANDBCB) += cmd_nandbcb.o
  81 +obj-$(CONFIG_CMD_QSPIHDR) += cmd_qspihdr.o
81 82 obj-$(CONFIG_IMX_VSERVICE) += imx_vservice.o
82 83 endif
83 84  
arch/arm/mach-imx/cmd_qspihdr.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * Copyright (C) 2021 NXP
  4 + */
  5 +#include <common.h>
  6 +#include <dm.h>
  7 +#include <mapmem.h>
  8 +#include <asm/io.h>
  9 +#include <spi.h>
  10 +#include <spi_flash.h>
  11 +#include <dm/device-internal.h>
  12 +
  13 +static struct spi_flash *flash;
  14 +
  15 +#define QSPI_HDR_TAG 0xc0ffee01 /* c0ffee01 */
  16 +#define QSPI_HDR_TAG_OFF 0x1fc
  17 +#define FSPI_HDR_TAG 0x42464346/* FCFB, bigendian */
  18 +#define FSPI_HDR_TAG_OFF 0x0
  19 +
  20 +#define HDR_LEN 0x200
  21 +
  22 +#ifdef CONFIG_MX7
  23 +#define QSPI_HDR_OFF 0x0
  24 +#define QSPI_DATA_OFF 0x400
  25 +#else
  26 +#define QSPI_HDR_OFF 0x400
  27 +#define QSPI_DATA_OFF 0x1000
  28 +#endif
  29 +
  30 +#ifdef CONFIG_IMX8MM
  31 +#define FSPI_HDR_OFF 0x0
  32 +#define FSPI_DATA_OFF 0x1000
  33 +#else
  34 +#define FSPI_HDR_OFF 0x400
  35 +#define FSPI_DATA_OFF 0x1000
  36 +#endif
  37 +
  38 +#define FLAG_VERBOSE 1
  39 +
  40 +struct qspi_config_parameter {
  41 + u32 dqs_loopback; /* Sets DQS LoopBack Mode to enable Dummy Pad MCR[24] */
  42 + u32 hold_delay; /* No needed on ULT1 */
  43 + u32 hsphs; /* Half Speed Phase Shift */
  44 + u32 hsdly; /* Half Speed Delay Selection */
  45 + u32 device_quad_mode_en; /* Write Command to Device */
  46 + u32 device_cmd; /* Cmd to xfer to device */
  47 + u32 write_cmd_ipcr; /* IPCR value of Write Cmd */
  48 + u32 write_enable_ipcr; /* IPCR value of Write enable */
  49 + u32 cs_hold_time; /* CS hold time in terms of serial clock.(for example 1 serial clock cyle) */
  50 + u32 cs_setup_time; /* CS setup time in terms of serial clock.(for example 1 serial clock cyle) */
  51 + u32 sflash_A1_size; /* interms of Bytes */
  52 + u32 sflash_A2_size; /* interms of Bytes */
  53 + u32 sflash_B1_size; /* interms of Bytes */
  54 + u32 sflash_B2_size; /* interms of Bytes */
  55 + u32 sclk_freq; /* 0 - 18MHz, 1 - 49MHz, 2 - 55MHz, 3 - 60MHz, 4 - 66Mhz, 5 - 76MHz, 6 - 99MHz (only for SDR Mode) */
  56 + u16 busy_bit_offset; /* Flash device busy bit offset in status register */
  57 + u16 busy_bit_polarity; /* Polarity of busy bit, 0 means the busy bit is 1 while busy and vice versa. */
  58 + u32 sflash_type; /* 1 - Single, 2 - Dual, 4 - Quad */
  59 + u32 sflash_port; /* 0 - Only Port-A, 1 - Both PortA and PortB */
  60 + u32 ddr_mode_enable; /* Enable DDR mode if set to TRUE */
  61 + u32 dqs_enable; /* Enable DQS mode if set to TRUE. Bit 0 represents DQS_EN, bit 1 represents DQS_LAT_EN */
  62 + u32 parallel_mode_enable; /* Enable Individual or parrallel mode. */
  63 + u32 portA_cs1; /* Enable Port A CS1 */
  64 + u32 portB_cs1; /* Enable Port B CS1 */
  65 + u32 fsphs; /* Full Speed Phase Selection */
  66 + u32 fsdly; /* Full Speed Phase Selection */
  67 + u32 ddrsmp; /* Select the sampling point for incoming data when serial flash is in DDR mode. */
  68 + u32 command_seq[64]; /* Set of seq to perform optimum read on SFLASH as as per vendor SFLASH */
  69 + u32 read_status_ipcr; /* IPCR value of Read Status Reg */
  70 + u32 enable_dqs_phase; /* Enable DQS phase */
  71 + u32 config_cmds_en; /* Enable config commands */
  72 + u32 config_cmds[4]; /* config commands, used to configure nor flash */
  73 + u32 config_cmds_args[4]; /* config commands argu */
  74 + u32 dqs_pad_setting_override; /* DQS pin pad setting override */
  75 + u32 sclk_pad_setting_override; /* SCLK pin pad setting override */
  76 + u32 data_pad_setting_override; /* DATA pins pad setting override */
  77 + u32 cs_pad_setting_override; /* CS pins pad setting override */
  78 + u32 dqs_loopback_internal; /* 0: dqs loopback from pad, 1: dqs loopback internally */
  79 + u32 dqs_phase_sel; /* dqs phase sel */
  80 + u32 dqs_fa_delay_chain_sel; /* dqs fa delay chain selection */
  81 + u32 dqs_fb_delay_chain_sel; /* dqs fb delay chain selection */
  82 + u32 sclk_fa_delay_chain_sel; /* sclk fa delay chain selection */
  83 + u32 sclk_fb_delay_chain_sel; /* sclk fb delay chain selection */
  84 + u32 misc_clock_enable; /* Misc clock enable, bit 0 means differential clock enable, bit 1 means CK2 clock enable. */
  85 + u32 reserve[15]; /* Reserved area, the total size of configuration structure should be 512 bytes */
  86 + u32 tag; /* QSPI configuration TAG, should be 0xc0ffee01 */
  87 +};
  88 +
  89 +struct fspi_config_parameter {
  90 + u32 tag; /* tag, 0x46434642 ascii 'FCFB' */
  91 + u32 version; /* 0x00000156 ascii bugfix | minor | major | 'V' */
  92 + u16 reserved;
  93 + u8 reserved0[2];
  94 + u8 readSampleClkSrc; /* 0 - internal loopback, 1 - loopback from DQS pad, 2 - loopback from SCK pad, 3 - Flash provided DQS */
  95 + u8 dataHoldTime; /* CS hold time */
  96 + u8 dataSetupTime; /* CS setup time */
  97 + u8 columnAddressWidth; /* 3 - for HyperFlash, 0 - other devices */
  98 + u8 deviceModeCfgEnable; /* device mode configuration enable feature, 0 - disable, 1- enable */
  99 + u8 reserved1[3];
  100 + u32 deviceModeSeq; /* sequence parameter for device mode configuration */
  101 + u32 deviceModeArg; /* device mode argument, effective only when deviceModeCfgEnable = 1 */
  102 + u8 configCmdEnable; /* config command enable feature, 0 - disable, 1 - enable */
  103 + u8 reserved2[3];
  104 + u32 configCmdSeqs[4]; /* sequences for config command, allow 4 separate configuration command sequences */
  105 + u32 configCmdArgs[4]; /* arguments for each separate configuration command sequence */
  106 + u32 controllerMiscOption;
  107 + /*
  108 + *
  109 + * +--------+----------------------------------------------------------+
  110 + * | offset | description |
  111 + * +--------+----------------------------------------------------------+
  112 + * | | differential clock enable |
  113 + * | 0 | |
  114 + * | | 0 - differential clock is not supported |
  115 + * | | 1 - differential clock is supported |
  116 + * +--------+----------------------------------------------------------+
  117 + * | | CK2 enable |
  118 + * | 1 | |
  119 + * | | must set 0 for this silicon |
  120 + * | | |
  121 + * +--------+----------------------------------------------------------+
  122 + * | | parallel mode enable |
  123 + * | 2 | |
  124 + * | | must set 0 for this silicon |
  125 + * | | |
  126 + * +--------+----------------------------------------------------------+
  127 + * | | word addressable enable |
  128 + * | 3 | |
  129 + * | | 0 - device is not word addressable |
  130 + * | | 1 - device is word addressable |
  131 + * +--------+----------------------------------------------------------+
  132 + * | | safe configuration frequency enable |
  133 + * | 4 | |
  134 + * | | 0 - configure external device using specified frequency |
  135 + * | | 1 - configure external device using 30MHz |
  136 + * +--------+----------------------------------------------------------+
  137 + * | 5 | reserved |
  138 + * +--------+----------------------------------------------------------+
  139 + * | | ddr mode enable |
  140 + * | 6 | |
  141 + * | | 0 - external device works using SDR commands |
  142 + * | | 1 - external device works using DDR commands |
  143 + * +--------+----------------------------------------------------------+
  144 + */
  145 + u8 deviceType; /* 1 - serial NOR */
  146 + u8 sflashPadType; /* 1 - single pad, 2 - dual pads, 4 - quad pads, 8 - octal pads */
  147 + u8 serialClkFreq; /* 1 - 20MHz, 2 - 50MHz, 3 - 60MHz, 4 - 80MHz, 5 - 100MHz, 6 - 133MHz, 7 - 166MHz, other values - 20MHz*/
  148 + u8 lutCustomSeqEnable; /* 0 - use pre-defined LUT sequence index and number, 1 - use LUT sequence parameters provided in this block */
  149 + u32 reserved3[2];
  150 + u32 sflashA1Size; /* For SPI NOR, need to fill with actual size, in terms of bytes */
  151 + u32 sflashA2Size; /* same as above */
  152 + u32 sflashB1Size; /* same as above */
  153 + u32 sflashB2Size; /* same as above */
  154 + u32 csPadSettingOverride; /* set to 0 if it is not supported */
  155 + u32 sclkPadSettingOverride; /* set to 0 if it is not supported */
  156 + u32 dataPadSettingOverride; /* set to 0 if it is not supported */
  157 + u32 dqsPadSettingOverride; /* set to 0 if it is not supported */
  158 + u32 timeoutInMs; /* maximum wait time during dread busy status, not used in ROM */
  159 + u32 commandInterval; /* interval of CS deselected period, set to 0 */
  160 + u16 dataValidTime[2]; /* time from clock edge to data valid edge */
  161 + /* This field is used when the FlexSPI root clock is less than 100MHz and the read sample */
  162 + /* clock source is device provided DQS signal without CK2 support. */
  163 + /* [31:16] - data valid time for DLLB in terms of 0.1ns */
  164 + /* [15:0] - data valid time for DLLA in terms of 0.1ns */
  165 + u16 busyOffset; /* busy bit offset, valid range: 0 - 31 */
  166 + u16 busyBitPolarity; /* 0 - busy bit is 1 if device is busy, 1 - busy bit is 0 if device is busy */
  167 + u32 lookupTable[64]; /* lookup table */
  168 + u32 lutCustomSeq[12]; /* customized LUT sequence */
  169 + u32 reserved4[4];
  170 + u32 pageSize; /* page size of serial NOR flash, not used in ROM */
  171 + u32 sectorSize; /* sector size of serial NOR flash, not used in ROM */
  172 + u32 reserved5[14];
  173 +};
  174 +
  175 +struct header_config {
  176 + union {
  177 + struct qspi_config_parameter qspi_hdr_config;
  178 + struct fspi_config_parameter fspi_hdr_config;
  179 + };
  180 +};
  181 +
  182 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  183 +static struct qspi_config_parameter qspi_safe_config = {
  184 + .cs_hold_time = 3,
  185 + .cs_setup_time = 3,
  186 + .sflash_A1_size = 0x4000000,
  187 + .sflash_B1_size = 0x4000000,
  188 + .sflash_type = 1,
  189 + .command_seq[0] = 0x08180403,
  190 + .command_seq[1] = 0x24001c00,
  191 + .tag = 0xc0ffee01,
  192 +};
  193 +
  194 +static struct header_config *safe_config = (struct header_config *)&qspi_safe_config;
  195 +#else
  196 +static struct fspi_config_parameter fspi_safe_config = {
  197 + .tag = 0x42464346,
  198 + .version = 0x56010000,
  199 + .dataHoldTime = 0x3,
  200 + .dataSetupTime = 0x3,
  201 + .deviceType = 0x1,
  202 + .sflashPadType = 0x1,
  203 + .serialClkFreq = 0x2,
  204 + .sflashA1Size = 0x10000000,
  205 + .lookupTable[0] = 0x0818040b,
  206 + .lookupTable[1] = 0x24043008,
  207 +};
  208 +
  209 +static struct header_config *safe_config = (struct header_config *)&fspi_safe_config;
  210 +#endif
  211 +
  212 +static int qspi_erase_update(struct spi_flash *flash, int off, int len, void *buf)
  213 +{
  214 + int size;
  215 + int ret;
  216 +
  217 + size = ROUND(len, flash->sector_size);
  218 + ret = spi_flash_erase(flash, off, size);
  219 + printf("Erase %#x bytes @ %#x %s\n",
  220 + size, off, ret ? "ERROR" : "OK");
  221 + if (ret)
  222 + return ret;
  223 +
  224 + ret = spi_flash_write(flash, off, len, buf);
  225 + printf("Write %#x bytes @ %#x %s\n",
  226 + len, off, ret ? "ERROR" : "OK");
  227 +
  228 + return ret;
  229 +}
  230 +
  231 +static int do_qspihdr_check(int argc, char * const argv[], int flag)
  232 +{
  233 + u32 buf;
  234 + unsigned long addr;
  235 + char *endp;
  236 + void *tmp;
  237 +
  238 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  239 + int off = QSPI_HDR_OFF + QSPI_HDR_TAG_OFF;
  240 + int tag = QSPI_HDR_TAG;
  241 +#else
  242 + int off = FSPI_HDR_OFF + FSPI_HDR_TAG_OFF;
  243 + int tag = FSPI_HDR_TAG;
  244 +#endif
  245 +
  246 + if (argc == 3) {
  247 + /* check data in memory */
  248 + addr = simple_strtoul(argv[2], &endp, 16);
  249 +
  250 + tmp = map_physmem(addr + off, 4, MAP_WRBACK);
  251 + if (!tmp && addr) {
  252 + printf("Failed to map physical memory\n");
  253 + return 1;
  254 + }
  255 +
  256 + if (*(u32 *)tmp == tag) {
  257 + if (flag & FLAG_VERBOSE)
  258 + printf("Found boot config header in memory\n");
  259 + unmap_physmem(tmp, 4);
  260 + return 0;
  261 + } else {
  262 + if (flag & FLAG_VERBOSE)
  263 + printf("NO boot config header in memory\n");
  264 + unmap_physmem(tmp, 4);
  265 + return 1;
  266 + }
  267 + } else {
  268 + spi_flash_read(flash, off, 4, &buf);
  269 +
  270 + if (buf == tag) {
  271 + if (flag & FLAG_VERBOSE)
  272 + printf("Found boot config header in Q(F)SPI\n");
  273 + return 0;
  274 + } else {
  275 + if (flag & FLAG_VERBOSE)
  276 + printf("NO boot config header in Q(F)SPI\n");
  277 + return 1;
  278 + }
  279 + }
  280 +}
  281 +
  282 +static void hdr_dump(void *data)
  283 +{
  284 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  285 + struct qspi_config_parameter *hdr =
  286 + (struct qspi_config_parameter *)data;
  287 +#else
  288 + struct fspi_config_parameter *hdr =
  289 + (struct fspi_config_parameter *)data;
  290 +#endif
  291 + int i;
  292 +
  293 +#define PH(mem, cnt) ( \
  294 +{ \
  295 + if (cnt > 1) { \
  296 + int len = strlen(#mem); \
  297 + char *sub = strchr(#mem, '['); \
  298 + *sub = '\0'; \
  299 + for (i = 0; i < cnt; ++i) \
  300 + printf(" %s[%02d%-*s = %08x\n", \
  301 + #mem, i, 25 - len, "]", \
  302 + (u32)*(&hdr->mem + i)); \
  303 + } else { \
  304 + printf(" %-25s = %0*x\n", \
  305 + #mem, (int)sizeof(hdr->mem), hdr->mem); \
  306 + } \
  307 +} \
  308 +)
  309 +
  310 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  311 + PH(dqs_loopback, 1);
  312 + PH(hold_delay, 1);
  313 + PH(hsphs, 1);
  314 + PH(hsdly, 1);
  315 + PH(device_quad_mode_en, 1);
  316 + PH(write_cmd_ipcr, 1);
  317 + PH(write_enable_ipcr, 1);
  318 + PH(cs_hold_time, 1);
  319 + PH(cs_setup_time, 1);
  320 + PH(sflash_A1_size, 1);
  321 + PH(sflash_A2_size, 1);
  322 + PH(sflash_B1_size, 1);
  323 + PH(sflash_B2_size, 1);
  324 + PH(sclk_freq, 1);
  325 + PH(busy_bit_offset, 1);
  326 + PH(busy_bit_polarity, 1);
  327 + PH(sflash_type, 1);
  328 + PH(sflash_port, 1);
  329 + PH(ddr_mode_enable, 1);
  330 + PH(dqs_enable, 1);
  331 + PH(parallel_mode_enable, 1);
  332 + PH(portA_cs1, 1);
  333 + PH(portB_cs1, 1);
  334 + PH(fsphs, 1);
  335 + PH(fsdly, 1);
  336 + PH(ddrsmp, 1);
  337 + PH(command_seq[0], 64);
  338 + PH(read_status_ipcr, 1);
  339 + PH(enable_dqs_phase, 1);
  340 + PH(config_cmds_en, 1);
  341 + PH(config_cmds[0], 4);
  342 + PH(config_cmds_args[0], 4);
  343 + PH(dqs_pad_setting_override, 1);
  344 + PH(sclk_pad_setting_override, 1);
  345 + PH(data_pad_setting_override, 1);
  346 + PH(cs_pad_setting_override, 1);
  347 + PH(dqs_loopback_internal, 1);
  348 + PH(dqs_phase_sel, 1);
  349 + PH(dqs_fa_delay_chain_sel, 1);
  350 + PH(dqs_fb_delay_chain_sel, 1);
  351 + PH(sclk_fa_delay_chain_sel, 1);
  352 + PH(sclk_fb_delay_chain_sel, 1);
  353 + PH(misc_clock_enable, 1);
  354 + PH(tag, 1);
  355 +#else
  356 + PH(tag, 1);
  357 + PH(version, 1);
  358 + PH(readSampleClkSrc, 1);
  359 + PH(dataHoldTime, 1);
  360 + PH(dataSetupTime, 1);
  361 + PH(columnAddressWidth, 1);
  362 + PH(deviceModeCfgEnable, 1);
  363 + PH(deviceModeSeq, 1);
  364 + PH(deviceModeArg, 1);
  365 + PH(configCmdEnable, 1);
  366 + PH(configCmdSeqs[0], 4);
  367 + PH(configCmdArgs[0], 4);
  368 + PH(controllerMiscOption, 1);
  369 + PH(deviceType, 1);
  370 + PH(sflashPadType, 1);
  371 + PH(serialClkFreq, 1);
  372 + PH(lutCustomSeqEnable, 1);
  373 + PH(sflashA1Size, 1);
  374 + PH(sflashA2Size, 1);
  375 + PH(sflashB1Size, 1);
  376 + PH(sflashB2Size, 1);
  377 + PH(csPadSettingOverride, 1);
  378 + PH(sclkPadSettingOverride, 1);
  379 + PH(dataPadSettingOverride, 1);
  380 + PH(dqsPadSettingOverride, 1);
  381 + PH(timeoutInMs, 1);
  382 + PH(commandInterval, 1);
  383 + PH(dataValidTime[0], 2);
  384 + PH(busyOffset, 1);
  385 + PH(busyBitPolarity, 1);
  386 + PH(lookupTable[0], 64);
  387 + PH(lutCustomSeq[0], 12);
  388 + PH(pageSize, 1);
  389 + PH(sectorSize, 1);
  390 +#endif
  391 +}
  392 +
  393 +static int do_qspihdr_dump(int argc, char * const argv[])
  394 +{
  395 + unsigned long addr;
  396 + char *endp;
  397 + void *tmp;
  398 + void *buf;
  399 +
  400 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  401 + int off = QSPI_HDR_OFF;
  402 +#else
  403 + int off = FSPI_HDR_OFF;
  404 +#endif
  405 +
  406 + if (argc == 3) {
  407 + /* check data in memory */
  408 + if (do_qspihdr_check(3, argv, FLAG_VERBOSE)) {
  409 + /* return 0 in any cases */
  410 + return 0;
  411 + }
  412 +
  413 + addr = simple_strtoul(argv[2], &endp, 16);
  414 +
  415 + tmp = map_physmem(addr + off, HDR_LEN, MAP_WRBACK);
  416 + if (!tmp && addr) {
  417 + printf("Failed to map physical memory\n");
  418 + return 1;
  419 + }
  420 +
  421 + hdr_dump(tmp);
  422 + unmap_physmem(tmp, HDR_LEN);
  423 + } else {
  424 + /* check data in Q(F)SPI */
  425 + buf = malloc(HDR_LEN);
  426 + if (!buf) {
  427 + printf("Failed to alloc memory\n");
  428 + /* return 0 in any cases */
  429 + return 0;
  430 + }
  431 +
  432 + spi_flash_read(flash, off, HDR_LEN, buf);
  433 +
  434 + hdr_dump(buf);
  435 + free(buf);
  436 + }
  437 +
  438 + return 0;
  439 +}
  440 +
  441 +static int do_qspihdr_init(int argc, char * const argv[])
  442 +{
  443 + unsigned long addr, len;
  444 + char *endp;
  445 + int total_len;
  446 + void *tmp;
  447 + void *buf;
  448 + bool hdr_flag = false;
  449 + int ret;
  450 +
  451 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  452 + int hdr_off = QSPI_HDR_OFF;
  453 + int data_off = QSPI_DATA_OFF;
  454 +#else
  455 + int hdr_off = FSPI_HDR_OFF;
  456 + int data_off = FSPI_DATA_OFF;
  457 +
  458 + safe_config->fspi_hdr_config.pageSize = flash->page_size;
  459 + safe_config->fspi_hdr_config.sectorSize = flash->sector_size;
  460 +#endif
  461 +
  462 + addr = simple_strtoul(argv[2], &endp, 16);
  463 + len = simple_strtoul(argv[3], &endp, 16);
  464 +
  465 + total_len = data_off + len;
  466 + if (total_len > flash->size) {
  467 + printf("Error: length %lx over flash size (%#x)\n",
  468 + len, flash->size);
  469 + return 1;
  470 + }
  471 +
  472 + /* check if header exists in this memory area*/
  473 + if (do_qspihdr_check(3, argv, 0) == 0)
  474 + hdr_flag = true;
  475 +
  476 + tmp = map_physmem(addr, len, MAP_WRBACK);
  477 + if (!tmp && addr) {
  478 + printf("Failed to map physical memory\n");
  479 + return 1;
  480 + }
  481 +
  482 + if (hdr_flag)
  483 + goto burn_image;
  484 +
  485 + buf = malloc(total_len);
  486 + if (!buf) {
  487 + printf("Failed to alloc memory\n");
  488 + unmap_physmem(tmp, total_len);
  489 + return 1;
  490 + }
  491 +
  492 + memset(buf, 0xff, total_len);
  493 + memcpy(buf + hdr_off, safe_config, HDR_LEN);
  494 + memcpy(buf + data_off, tmp, len);
  495 +
  496 +burn_image:
  497 + if (hdr_flag) {
  498 + ret = qspi_erase_update(flash, 0, len, tmp);
  499 + } else {
  500 + ret = qspi_erase_update(flash, 0, total_len, buf);
  501 + free(buf);
  502 + }
  503 +
  504 + unmap_physmem(tmp, total_len);
  505 + return ret;
  506 +}
  507 +
  508 +static int do_qspihdr_update(int argc, char * const argv[])
  509 +{
  510 + int len;
  511 + int size;
  512 + void *buf;
  513 + int ret;
  514 +
  515 +#if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_ARCH_MX7ULP)
  516 + int hdr_off = QSPI_HDR_OFF;
  517 +#else
  518 + int hdr_off = FSPI_HDR_OFF;
  519 +#endif
  520 +
  521 + len = hdr_off + HDR_LEN;
  522 + size = ROUND(len, flash->sector_size);
  523 +
  524 + buf = malloc(size);
  525 + if (!buf) {
  526 + printf("Failed to alloc memory\n");
  527 + return 1;
  528 + }
  529 +
  530 + spi_flash_read(flash, 0, size, buf);
  531 + memcpy(buf + hdr_off, safe_config, HDR_LEN);
  532 +
  533 + ret = qspi_erase_update(flash, 0, size, buf);
  534 + free(buf);
  535 +
  536 + return ret;
  537 +}
  538 +
  539 +static int do_qspihdr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  540 +{
  541 + char *cmd;
  542 + unsigned int bus = CONFIG_SF_DEFAULT_BUS;
  543 + unsigned int cs = CONFIG_SF_DEFAULT_CS;
  544 + unsigned int speed = CONFIG_SF_DEFAULT_SPEED;
  545 + unsigned int mode = CONFIG_SF_DEFAULT_MODE;
  546 + int flags = 0;
  547 + int ret;
  548 +
  549 + if (argc < 2)
  550 + goto usage;
  551 +
  552 +#ifdef CONFIG_DM_SPI_FLASH
  553 + struct udevice *new, *bus_dev;
  554 +
  555 + ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new);
  556 + if (!ret)
  557 + device_remove(new, DM_REMOVE_NORMAL);
  558 + flash = NULL;
  559 + ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new);
  560 + if (ret) {
  561 + printf("Failed to initialize SPI flash at %u:%u (error %d)\n",
  562 + bus, cs, ret);
  563 + return 1;
  564 + }
  565 + flash = dev_get_uclass_priv(new);
  566 +#endif
  567 +
  568 + cmd = argv[1];
  569 +
  570 + if (strcmp(cmd, "check") == 0)
  571 + return do_qspihdr_check(argc, argv, flags | FLAG_VERBOSE);
  572 +
  573 + if (strcmp(cmd, "dump") == 0)
  574 + return do_qspihdr_dump(argc, argv);
  575 +
  576 + if (strcmp(cmd, "init") == 0) {
  577 + if (argc < 5)
  578 + goto usage;
  579 + return do_qspihdr_init(argc, argv);
  580 + }
  581 +
  582 + if (strcmp(cmd, "update") == 0) {
  583 + if (argc < 3)
  584 + goto usage;
  585 + return do_qspihdr_update(argc, argv);
  586 + }
  587 +
  588 + return 0;
  589 +usage:
  590 + return CMD_RET_USAGE;
  591 +}
  592 +
  593 +static char qspihdr_help_text[] =
  594 + "check [addr] - check if boot config already exists, 0-yes, 1-no\n"
  595 + " with addr, it will check data in memory of this addr\n"
  596 + " without addr, it will check data in Q(F)SPI chip\n"
  597 + "qspihdr dump [addr] - dump the header information, if exists\n"
  598 + " with addr, it will check data in memory of this addr\n"
  599 + " without addr, it will check data in Q(F)SPI chip\n"
  600 + "qspihdr init addr len safe - burn data to Q(F)SPI with header\n"
  601 + " if data contains header, it will be used, otherwise,\n"
  602 + " safe: most common header, single line, sdr, low freq\n"
  603 + "qspihdr update safe - only update the header in Q(F)SPI\n";
  604 +
  605 +U_BOOT_CMD(qspihdr, 5, 1, do_qspihdr,
  606 + "Q(F)SPI Boot Config sub-system",
  607 + qspihdr_help_text
  608 +);
board/freescale/imx8mp_evk/imx8mp_evk.c
... ... @@ -360,9 +360,9 @@
360 360 .power_down_scale = 2,
361 361 };
362 362  
363   -int usb_gadget_handle_interrupts(void)
  363 +int usb_gadget_handle_interrupts(int index)
364 364 {
365   - dwc3_uboot_handle_interrupt(0);
  365 + dwc3_uboot_handle_interrupt(index);
366 366 return 0;
367 367 }
368 368  
board/freescale/imx8mq_evk/imx8mq_evk.c
... ... @@ -118,9 +118,9 @@
118 118 .power_down_scale = 2,
119 119 };
120 120  
121   -int usb_gadget_handle_interrupts(void)
  121 +int usb_gadget_handle_interrupts(int index)
122 122 {
123   - dwc3_uboot_handle_interrupt(0);
  123 + dwc3_uboot_handle_interrupt(index);
124 124 return 0;
125 125 }
126 126  
board/freescale/imx8mq_val/imx8mq_val.c
... ... @@ -168,9 +168,9 @@
168 168 .power_down_scale = 2,
169 169 };
170 170  
171   -int usb_gadget_handle_interrupts(void)
  171 +int usb_gadget_handle_interrupts(int index)
172 172 {
173   - dwc3_uboot_handle_interrupt(0);
  173 + dwc3_uboot_handle_interrupt(index);
174 174 return 0;
175 175 }
176 176  
drivers/crypto/fsl/desc.h
... ... @@ -15,6 +15,7 @@
15 15  
16 16 #define KEY_BLOB_SIZE 32
17 17 #define MAC_SIZE 16
  18 +#define BKEK_SIZE 32
18 19  
19 20 /* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
20 21 #define MAX_CAAM_DESCSIZE 64
... ... @@ -462,6 +463,9 @@
462 463 #define OP_PROTINFO_HASH_SHA256 0x00000180
463 464 #define OP_PROTINFO_HASH_SHA384 0x00000200
464 465 #define OP_PROTINFO_HASH_SHA512 0x00000280
  466 +
  467 +/* PROTINFO fields for Blob Operations */
  468 +#define OP_PROTINFO_MKVB 0x00000002
465 469  
466 470 /* For non-protocol/alg-only op commands */
467 471 #define OP_ALG_TYPE_SHIFT 24
drivers/crypto/fsl_caam.c
... ... @@ -250,6 +250,42 @@
250 250 }
251 251  
252 252 /*!
  253 + * Use CAAM to derive BKEK
  254 + *
  255 + * @param output_ptr Location address of the output data.
  256 + *
  257 + * @return SUCCESS or ERROR_XXX
  258 + */
  259 +u32 caam_derive_bkek(u8 *output_ptr)
  260 +{
  261 + u32 ret = SUCCESS;
  262 + u32 key_sz = sizeof(skeymod);
  263 + u32 *bkek_desc = g_jrdata.desc;
  264 +
  265 + /* initialize the output array */
  266 + memset(output_ptr, 0, BKEK_SIZE);
  267 +
  268 + /* prepare job descriptor */
  269 + init_job_desc(bkek_desc, 0);
  270 + append_load(bkek_desc, PTR2CAAMDMA(skeymod), key_sz,
  271 + LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
  272 + append_seq_out_ptr_intlen(bkek_desc, PTR2CAAMDMA(output_ptr), BKEK_SIZE, 0);
  273 + append_operation(bkek_desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB | OP_PROTINFO_MKVB);
  274 +
  275 + flush_dcache_range((uintptr_t)output_ptr & ALIGN_MASK,
  276 + ((uintptr_t)output_ptr & ALIGN_MASK)
  277 + + ROUND(BKEK_SIZE, ARCH_DMA_MINALIGN));
  278 +
  279 + ret = do_job(bkek_desc);
  280 +
  281 + if (ret != SUCCESS) {
  282 + printf("Error: output bkek job failed 0x%x\n", ret);
  283 + }
  284 +
  285 + return ret;
  286 +}
  287 +
  288 +/*!
253 289 * Initialize the CAAM.
254 290 *
255 291 */
drivers/fastboot/fb_fsl/fb_fsl_command.c
... ... @@ -45,6 +45,7 @@
45 45  
46 46 #ifdef CONFIG_IMX_TRUSTY_OS
47 47 #include "u-boot/sha256.h"
  48 +#include "trusty/rpmb.h"
48 49 #include <trusty/libtipc.h>
49 50 #endif
50 51  
51 52  
52 53  
... ... @@ -696,18 +697,26 @@
696 697 }
697 698 #endif
698 699 #ifndef CONFIG_AVB_ATX
699   - else if (endswith(cmd, FASTBOOT_SET_RPMB_KEY)) {
700   - if (fastboot_set_rpmb_key(fastboot_buf_addr, fastboot_bytes_received)) {
701   - printf("ERROR set rpmb key failed!\n");
702   - strcpy(response, "FAILset rpmb key failed!");
  700 + else if (endswith(cmd, FASTBOOT_SET_RPMB_STAGED_KEY)) {
  701 + if (fastboot_set_rpmb_staged_key(fastboot_buf_addr, fastboot_bytes_received)) {
  702 + printf("ERROR set rpmb staged key failed!\n");
  703 + strcpy(response, "FAILset rpmb staged key failed!");
703 704 } else
704 705 strcpy(response, "OKAY");
705   - } else if (endswith(cmd, FASTBOOT_SET_RPMB_RANDOM_KEY)) {
706   - if (fastboot_set_rpmb_random_key()) {
707   - printf("ERROR set rpmb random key failed!\n");
708   - strcpy(response, "FAILset rpmb random key failed!");
  706 + } else if (endswith(cmd, FASTBOOT_SET_RPMB_HARDWARE_KEY)) {
  707 + if (fastboot_set_rpmb_hardware_key()) {
  708 + printf("ERROR set rpmb hardware key failed!\n");
  709 + strcpy(response, "FAILset rpmb hardware key failed!");
709 710 } else
710 711 strcpy(response, "OKAY");
  712 + } else if (endswith(cmd, FASTBOOT_ERASE_RPMB)) {
  713 + if (storage_erase_rpmb()) {
  714 + printf("ERROR erase rpmb storage failed!\n");
  715 + strcpy(response, "FAILerase rpmb storage failed!");
  716 + } else {
  717 + printf("erase rpmb storage succeed!\n");
  718 + strcpy(response, "OKAY");
  719 + }
711 720 } else if (endswith(cmd, FASTBOOT_SET_VBMETA_PUBLIC_KEY)) {
712 721 if (avb_set_public_key(fastboot_buf_addr,
713 722 fastboot_bytes_received))
include/configs/imx8mm_evk_android.h
... ... @@ -31,7 +31,8 @@
31 31 #define ANDROID_MCU_FIRMWARE_HEADER_STACK 0x20020000
32 32 #endif
33 33  
34   -#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER)
  34 +#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER) || \
  35 + !defined(CONFIG_SPL_BUILD)
35 36 #undef CONFIG_FSL_CAAM_KB
36 37 #endif
37 38  
include/configs/imx8mn_evk_android.h
... ... @@ -31,7 +31,8 @@
31 31 #define ANDROID_MCU_FIRMWARE_HEADER_STACK 0x20020000
32 32 #endif
33 33  
34   -#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER)
  34 +#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER) || \
  35 + !defined(CONFIG_SPL_BUILD)
35 36 #undef CONFIG_FSL_CAAM_KB
36 37 #endif
37 38  
include/configs/imx8mp_evk_android.h
... ... @@ -31,7 +31,8 @@
31 31 #define ANDROID_MCU_FIRMWARE_HEADER_STACK 0x20020000
32 32 #endif
33 33  
34   -#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER)
  34 +#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER) || \
  35 + !defined(CONFIG_SPL_BUILD)
35 36 #undef CONFIG_FSL_CAAM_KB
36 37 #endif
37 38  
include/configs/imx8mq_evk_android.h
... ... @@ -31,7 +31,8 @@
31 31 #define ANDROID_MCU_FIRMWARE_HEADER_STACK 0x20020000
32 32 #endif
33 33  
34   -#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER)
  34 +#if !defined(CONFIG_IMX_TRUSTY_OS) || !defined(CONFIG_DUAL_BOOTLOADER) || \
  35 + !defined(CONFIG_SPL_BUILD)
35 36 #undef CONFIG_FSL_CAAM_KB
36 37 #endif
37 38  
... ... @@ -86,9 +86,10 @@
86 86  
87 87 #ifdef CONFIG_IMX_TRUSTY_OS
88 88 #ifndef CONFIG_AVB_ATX
89   -#define FASTBOOT_SET_RPMB_KEY "set-rpmb-key"
90   -#define FASTBOOT_SET_RPMB_RANDOM_KEY "set-rpmb-random-key"
  89 +#define FASTBOOT_SET_RPMB_STAGED_KEY "set-rpmb-staged-key"
  90 +#define FASTBOOT_SET_RPMB_HARDWARE_KEY "set-rpmb-hardware-key"
91 91 #define FASTBOOT_SET_VBMETA_PUBLIC_KEY "set-public-key"
  92 +#define FASTBOOT_ERASE_RPMB "erase-rpmb"
92 93 #endif
93 94  
94 95 #define FASTBOOT_SET_CA_RESP "at-set-ca-response"
... ... @@ -172,10 +172,10 @@
172 172 int avb_atx_fuse_perm_attr(uint8_t *staged_buffer, uint32_t size);
173 173  
174 174 /* Initialize rpmb key with the staged key */
175   -int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size);
  175 +int fastboot_set_rpmb_staged_key(uint8_t *staged_buf, uint32_t key_size);
176 176  
177   -/* Initialize rpmb key with random key which is generated by caam rng */
178   -int fastboot_set_rpmb_random_key(void);
  177 +/* Initialize rpmb key with hardware key which is derived from BKEK */
  178 +int fastboot_set_rpmb_hardware_key(void);
179 179  
180 180 /* Generate ATX unlock challenge */
181 181 int avb_atx_get_unlock_challenge(struct AvbAtxOps* atx_ops,
... ... @@ -74,6 +74,7 @@
74 74 ////////////////////////////////////////////////////////////////////////////////
75 75 uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size);
76 76 uint32_t caam_hwrng(uint8_t *output_ptr, uint32_t output_len);
  77 +uint32_t caam_derive_bkek(u8 *output_ptr);
77 78  
78 79 #endif /* __CAAM_H__ */
include/interface/storage/storage.h
... ... @@ -56,6 +56,9 @@
56 56  
57 57 /* transaction support */
58 58 STORAGE_END_TRANSACTION = 9 << STORAGE_REQ_SHIFT,
  59 +
  60 + STORAGE_RPMB_KEY_SET = 12 << STORAGE_REQ_SHIFT,
  61 + STORAGE_RPMB_ERASE_ALL = 13 << STORAGE_REQ_SHIFT,
59 62 };
60 63  
61 64 /**
include/trusty/rpmb.h
... ... @@ -75,5 +75,15 @@
75 75 */
76 76 void rpmb_storage_put_ctx(void *dev);
77 77  
  78 +/*
  79 + * Set rpmb key by secure side.
  80 + */
  81 +int storage_set_rpmb_key(void);
  82 +
  83 +/*
  84 + * Erase rpmb storage by secure side.
  85 + */
  86 +int storage_erase_rpmb(void);
  87 +
78 88 #endif /* TRUSTY_RPMB_H_ */
lib/avb/fsl/fsl_avbkey.c
... ... @@ -26,6 +26,7 @@
26 26 #include "debug.h"
27 27 #include <memalign.h>
28 28 #include "trusty/hwcrypto.h"
  29 +#include "trusty/rpmb.h"
29 30 #include "fsl_atx_attributes.h"
30 31 #include <asm/mach-imx/hab.h>
31 32 #include <asm/arch/sys_proto.h>
32 33  
... ... @@ -301,12 +302,18 @@
301 302 ret = -1;
302 303 goto fail;
303 304 }
304   - /* copy rpmb key to blob */
305   - memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
306 305 caam_open();
307   - if (caam_decap_blob((ulong)extract_key, (ulong)blob,
308   - RPMBKEY_LENGTH)) {
309   - ERR("decap rpmb key error\n");
  306 + if (!strcmp(kp.magic, KEYPACK_MAGIC)) {
  307 + /* Use the key from keyslot. */
  308 + memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
  309 + if (caam_decap_blob((ulong)extract_key, (ulong)blob,
  310 + RPMBKEY_LENGTH)) {
  311 + ERR("decap rpmb key error\n");
  312 + ret = -1;
  313 + goto fail;
  314 + }
  315 + } else if (caam_derive_bkek(extract_key)) {
  316 + ERR("get rpmb key error\n");
310 317 ret = -1;
311 318 goto fail;
312 319 }
... ... @@ -335,6 +342,7 @@
335 342 out_buf += cnt;
336 343 s = 0;
337 344 }
  345 + memset(extract_key, 0, RPMBKEY_LENGTH);
338 346 ret = 0;
339 347  
340 348 fail:
341 349  
... ... @@ -401,12 +409,18 @@
401 409 ret = -1;
402 410 goto fail;
403 411 }
404   - /* copy rpmb key to blob */
405   - memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
406 412 caam_open();
407   - if (caam_decap_blob((ulong)extract_key, (ulong)blob,
408   - RPMBKEY_LENGTH)) {
409   - ERR("decap rpmb key error\n");
  413 + if (!strcmp(kp.magic, KEYPACK_MAGIC)) {
  414 + /* Use the key from keyslot. */
  415 + memcpy(blob, kp.rpmb_keyblob, RPMBKEY_BLOB_LEN);
  416 + if (caam_decap_blob((ulong)extract_key, (ulong)blob,
  417 + RPMBKEY_LENGTH)) {
  418 + ERR("decap rpmb key error\n");
  419 + ret = -1;
  420 + goto fail;
  421 + }
  422 + } else if (caam_derive_bkek(extract_key)) {
  423 + ERR("get rpmb key error\n");
410 424 ret = -1;
411 425 goto fail;
412 426 }
... ... @@ -440,6 +454,7 @@
440 454 if (s != 0)
441 455 s = 0;
442 456 }
  457 + memset(extract_key, 0, RPMBKEY_LENGTH);
443 458 ret = 0;
444 459  
445 460 fail:
... ... @@ -800,13 +815,8 @@
800 815  
801 816 read_keyslot_package(&kp);
802 817 if (strcmp(kp.magic, KEYPACK_MAGIC)) {
803   - if (rpmbkey_is_set()) {
804   - printf("\nFATAL - RPMB key was destroyed!\n");
805   - hang();
806   - } else {
807   - printf("keyslot package magic error, do nothing here!\n");
808   - return 0;
809   - }
  818 + /* Return if the magic doesn't match */
  819 + return 0;
810 820 }
811 821 /* If keyslot package valid, copy it to secure memory */
812 822 fill_secure_keyslot_package(&kp);
... ... @@ -1278,7 +1288,7 @@
1278 1288 return ret;
1279 1289 }
1280 1290  
1281   -int fastboot_set_rpmb_key(uint8_t *staged_buf, uint32_t key_size)
  1291 +int fastboot_set_rpmb_staged_key(uint8_t *staged_buf, uint32_t key_size)
1282 1292 {
1283 1293  
1284 1294 if (memcmp(staged_buf, RPMB_KEY_MAGIC, strlen(RPMB_KEY_MAGIC))) {
1285 1295  
... ... @@ -1290,16 +1300,9 @@
1290 1300 RPMBKEY_LENGTH);
1291 1301 }
1292 1302  
1293   -int fastboot_set_rpmb_random_key(void)
  1303 +int fastboot_set_rpmb_hardware_key(void)
1294 1304 {
1295   - ALLOC_CACHE_ALIGN_BUFFER(uint8_t, rpmb_key, RPMBKEY_LENGTH);
1296   -
1297   - if (hwcrypto_gen_rng((ulong)rpmb_key, RPMBKEY_LENGTH)) {
1298   - printf("error - can't generate random key!\n");
1299   - return -1;
1300   - }
1301   -
1302   - return do_rpmb_key_set(rpmb_key, RPMBKEY_LENGTH);
  1305 + return storage_set_rpmb_key();
1303 1306 }
1304 1307  
1305 1308 int avb_set_public_key(uint8_t *staged_buffer, uint32_t size) {
lib/avb/fsl/fsl_bootctrl.c
... ... @@ -643,13 +643,7 @@
643 643  
644 644 #if !defined(CONFIG_XEN) && defined(CONFIG_IMX_TRUSTY_OS)
645 645 read_keyslot_package(&kp);
646   - if (strcmp(kp.magic, KEYPACK_MAGIC)) {
647   - if (rpmbkey_is_set()) {
648   - printf("\nFATAL - RPMB key was destroyed!\n");
649   - hang();
650   - } else
651   - printf("keyslot package magic error, do nothing here!\n");
652   - } else {
  646 + if (!strcmp(kp.magic, KEYPACK_MAGIC)) {
653 647 /* Set power-on write protection to boot1 partition. */
654 648 if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
655 649 printf("Unable to set power-on write protection to boot1!\n");
lib/trusty/ql-tipc/ipc.c
... ... @@ -177,6 +177,8 @@
177 177 return rc;
178 178 }
179 179  
  180 +extern bool proxy_resp_flag;
  181 +
180 182 int trusty_ipc_recv(struct trusty_ipc_chan *chan,
181 183 const struct trusty_ipc_iovec *iovs, size_t iovs_cnt,
182 184 bool wait)
... ... @@ -194,9 +196,13 @@
194 196 }
195 197 }
196 198  
197   - rc = trusty_ipc_dev_recv(chan->dev, chan->handle, iovs, iovs_cnt);
198   - if (rc < 0)
199   - trusty_error("%s: ipc recv failed (%d)\n", __func__, rc);
  199 + /* Return directly if the iovs have been received. */
  200 + if (!proxy_resp_flag) {
  201 + rc = trusty_ipc_dev_recv(chan->dev, chan->handle, iovs, iovs_cnt);
  202 + if (rc < 0)
  203 + trusty_error("%s: ipc recv failed (%d)\n", __func__, rc);
  204 + } else
  205 + rc = 0;
200 206  
201 207 return rc;
202 208 }
lib/trusty/ql-tipc/libtipc.c
... ... @@ -47,6 +47,14 @@
47 47 void rpmb_storage_put_ctx(void *dev);
48 48 void trusty_ipc_shutdown(void)
49 49 {
  50 + /**
  51 + * Trusty OS is not well initialized when the rpmb
  52 + * key is not set, skip ipc shut down to avoid panic.
  53 + */
  54 + if (!rpmbkey_is_set()) {
  55 + return;
  56 + }
  57 +
50 58 (void)rpmb_storage_proxy_shutdown(_ipc_dev);
51 59 (void)rpmb_storage_put_ctx(rpmb_ctx);
52 60  
... ... @@ -67,6 +75,7 @@
67 75 int trusty_ipc_init(void)
68 76 {
69 77 int rc;
  78 + bool use_keystore = true;
70 79 /* init Trusty device */
71 80 trusty_info("Initializing Trusty device\n");
72 81 rc = trusty_dev_init(&_tdev, NULL);
... ... @@ -88,8 +97,7 @@
88 97 /* start secure storage proxy service */
89 98 rc = rpmb_storage_proxy_init(_ipc_dev, rpmb_ctx);
90 99 if (rc != 0) {
91   - trusty_error("Initlializing RPMB storage proxy service failed (%d)\n",
92   - rc);
  100 + trusty_error("Initlializing RPMB storage proxy service failed (%d)\n", rc);
93 101 #ifndef CONFIG_AVB_ATX
94 102 /* check if rpmb key has been fused. */
95 103 if(rpmbkey_is_set()) {
96 104  
97 105  
... ... @@ -98,12 +106,16 @@
98 106 hang();
99 107 }
100 108 #else
101   - return rc;
  109 + return rc;
102 110 #endif
103   - } else {
104   - /* secure storage service init ok, use trusty backed keystore */
105   - env_set("keystore", "trusty");
  111 + }
106 112  
  113 + /**
  114 + * The proxy service can return success even the storage initialization
  115 + * failed (when the rpmb key not set). Init the avb and keymaster service
  116 + * only when the rpmb key has been set.
  117 + */
  118 + if (rpmbkey_is_set()) {
107 119 rc = avb_tipc_init(_ipc_dev);
108 120 if (rc != 0) {
109 121 trusty_error("Initlializing Trusty AVB client failed (%d)\n", rc);
... ... @@ -115,7 +127,8 @@
115 127 trusty_error("Initlializing Trusty Keymaster client failed (%d)\n", rc);
116 128 return rc;
117 129 }
118   - }
  130 + } else
  131 + use_keystore = false;
119 132  
120 133 #ifndef CONFIG_AVB_ATX
121 134 rc = hwcrypto_tipc_init(_ipc_dev);
... ... @@ -124,6 +137,10 @@
124 137 return rc;
125 138 }
126 139 #endif
  140 +
  141 + /* secure storage service init ok, use trusty backed keystore */
  142 + if (use_keystore)
  143 + env_set("keystore", "trusty");
127 144  
128 145 return TRUSTY_ERR_NONE;
129 146 }
lib/trusty/ql-tipc/rpmb_proxy.c
... ... @@ -37,6 +37,8 @@
37 37 struct storage_msg req_msg;
38 38 static uint8_t req_buf[4096];
39 39 static uint8_t read_buf[4096];
  40 +bool proxy_resp_flag = false;
  41 +static int req_len = 0;
40 42  
41 43 /*
42 44 * Read RPMB request from storage service. Writes message to @msg
... ... @@ -74,6 +76,53 @@
74 76 }
75 77  
76 78 /*
  79 + * Read RPMB response from storage service. Writes message to @msg
  80 + * and @req.
  81 + *
  82 + * @chan: proxy ipc channel
  83 + * @msg: address of storage message header
  84 + * @cmd: cmd corresponding to the request
  85 + * @resp: address of storage message response
  86 + * @resp_len: length of resp in bytes
  87 + */
  88 +static int proxy_read_response(struct trusty_ipc_chan *chan, struct storage_msg *msg,
  89 + uint32_t cmd, void *resp, size_t resp_len)
  90 +{
  91 + int rc;
  92 +
  93 + struct trusty_ipc_iovec resp_iovs[2] = {
  94 + { .base = msg, .len = sizeof(*msg) },
  95 + { .base = resp, .len = resp_len },
  96 + };
  97 + rc = trusty_ipc_recv(chan, resp_iovs, resp ? 2 : 1, true);
  98 + if (rc < 0) {
  99 + /* recv message failed */
  100 + trusty_error("%s: failed (%d) to recv response\n", __func__, rc);
  101 + return rc;
  102 + }
  103 + if (proxy_resp_flag) {
  104 + memcpy(msg, &req_msg, sizeof(struct storage_msg));
  105 + if (resp)
  106 + memcpy(resp, req_buf, req_len);
  107 + rc = req_len + sizeof(struct storage_msg);
  108 + proxy_resp_flag = false;
  109 + }
  110 +
  111 + if ((size_t)rc < sizeof(*msg)) {
  112 + /* malformed message */
  113 + trusty_error("%s: malformed request (%zu)\n", __func__, (size_t)rc);
  114 + return TRUSTY_ERR_GENERIC;
  115 + }
  116 +
  117 + if (msg->cmd != (cmd | STORAGE_RESP_BIT)) {
  118 + trusty_error("malformed response, cmd: 0x%x\n", msg->cmd);
  119 + return TRUSTY_ERR_GENERIC;
  120 + }
  121 +
  122 + return rc - sizeof(*msg); /* return payload size */
  123 +}
  124 +
  125 +/*
77 126 * Send RPMB response to storage service
78 127 *
79 128 * @chan: proxy ipc channel
... ... @@ -95,6 +144,71 @@
95 144 }
96 145  
97 146 /*
  147 + * Send RPMB request to storage service
  148 + *
  149 + * @chan: proxy ipc channel
  150 + * @msg: address of storage message header
  151 + * @req: address of storage message request
  152 + * @req_len: length of request in bytes
  153 + */
  154 +static int proxy_send_request(struct trusty_ipc_chan *chan,
  155 + struct storage_msg *msg, void *req,
  156 + size_t req_len)
  157 +{
  158 + struct trusty_ipc_iovec req_iovs[2] = {
  159 + { .base = msg, .len = sizeof(*msg) },
  160 + { .base = req, .len = req_len }
  161 + };
  162 +
  163 + return trusty_ipc_send(chan, req_iovs, req ? 2 : 1, false);
  164 +}
  165 +
  166 +/*
  167 + * Convenience function to send a request to the storage service and read the
  168 + * response.
  169 + *
  170 + * @cmd: the command
  171 + * @req: the request buffer
  172 + * @req_size: size of the request buffer
  173 + * @resp: the response buffer
  174 + * @resp_size_p: pointer to the size of the response buffer. changed to the
  175 + actual size of the response read from the secure side
  176 + */
  177 +static int storage_do_tipc(uint32_t cmd, void *req, uint32_t req_size, void *resp,
  178 + uint32_t *resp_size_p)
  179 +{
  180 + int rc;
  181 + struct storage_msg msg = { .cmd = cmd };
  182 +
  183 + if (!initialized) {
  184 + trusty_error("%s: Secure storage TIPC client not initialized\n", __func__);
  185 + return TRUSTY_ERR_GENERIC;
  186 + }
  187 + rc = proxy_send_request(&proxy_chan, &msg, req, req_size);
  188 + if (rc < 0) {
  189 + trusty_error("%s: failed (%d) to send storage request\n", __func__, rc);
  190 + return rc;
  191 + }
  192 +
  193 + uint32_t resp_size = resp_size_p ? *resp_size_p : 0;
  194 + rc = proxy_read_response(&proxy_chan, &msg, cmd, resp, resp_size);
  195 + if (rc < 0) {
  196 + trusty_error("%s: failed (%d) to read secure storage response\n", __func__, rc);
  197 + return rc;
  198 + }
  199 + /* change response size to actual response size */
  200 + if (resp_size_p && rc != *resp_size_p) {
  201 + *resp_size_p = rc;
  202 + }
  203 + if (msg.result != STORAGE_NO_ERROR) {
  204 + trusty_error("%s: secure storage service returned error (%d)\n", __func__,
  205 + msg.result);
  206 + return TRUSTY_ERR_GENERIC;
  207 + }
  208 + return TRUSTY_ERR_NONE;
  209 +}
  210 +
  211 +/*
98 212 * Executes the RPMB request at @r, sends response to storage service.
99 213 *
100 214 * @chan: proxy ipc channel
... ... @@ -257,6 +371,18 @@
257 371 return rc;
258 372 }
259 373  
  374 + /**
  375 + * The response of proxy will also be routed to here but we should
  376 + * not handle them, just return and set "proxy_resp_flag" to indicate
  377 + * func trusty_ipc_dev_recv() not try to receive the msg again.
  378 + */
  379 + if (req_msg.cmd & STORAGE_RESP_BIT) {
  380 + chan->complete = 1;
  381 + proxy_resp_flag = 1;
  382 + req_len = rc;
  383 + return TRUSTY_EVENT_HANDLED;
  384 + }
  385 +
260 386 /* handle it and send reply */
261 387 rc = proxy_handle_req(chan, &req_msg, req_buf, rc);
262 388 if (rc < 0) {
... ... @@ -329,5 +455,17 @@
329 455 trusty_ipc_close(&proxy_chan);
330 456  
331 457 initialized = false;
  458 +}
  459 +
  460 +int storage_set_rpmb_key(void)
  461 +{
  462 + uint32_t size = 0;
  463 + return storage_do_tipc(STORAGE_RPMB_KEY_SET, NULL, 0, NULL, &size);
  464 +}
  465 +
  466 +int storage_erase_rpmb(void)
  467 +{
  468 + uint32_t size = 0;
  469 + return storage_do_tipc(STORAGE_RPMB_ERASE_ALL, NULL, 0, NULL, &size);
332 470 }