From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 1FAA8A04C2; Fri, 15 Nov 2019 00:05:44 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2C7A92BAF; Fri, 15 Nov 2019 00:05:43 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id E59E4374 for ; Fri, 15 Nov 2019 00:05:40 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Nov 2019 15:05:39 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.68,306,1569308400"; d="scan'208";a="203213116" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga008.fm.intel.com with ESMTP; 14 Nov 2019 15:05:39 -0800 Received: from fmsmsx154.amr.corp.intel.com (10.18.116.70) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 14 Nov 2019 15:05:39 -0800 Received: from cdsmsx152.ccr.corp.intel.com (172.17.4.41) by FMSMSX154.amr.corp.intel.com (10.18.116.70) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 14 Nov 2019 15:05:38 -0800 Received: from cdsmsx104.ccr.corp.intel.com ([169.254.4.66]) by CDSMSX152.ccr.corp.intel.com ([169.254.6.195]) with mapi id 14.03.0439.000; Fri, 15 Nov 2019 07:05:36 +0800 From: "Zhang, Tianfei" To: "Xu, Rosen" , "dev@dpdk.org" CC: "Pei, Andy" , "Ye, Xiaolong" , "Yigit, Ferruh" Thread-Topic: [PATCH v18 13/19] raw/ifpga/base: add secure support Thread-Index: AQHVmsqd14umbK+FHkimUudKJqftJaeLRoZQ Date: Thu, 14 Nov 2019 23:05:35 +0000 Message-ID: References: <1571917119-149534-2-git-send-email-andy.pei@intel.com> <1573722187-148846-1-git-send-email-rosen.xu@intel.com> <1573722187-148846-14-git-send-email-rosen.xu@intel.com> In-Reply-To: <1573722187-148846-14-git-send-email-rosen.xu@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.2.0.6 x-originating-ip: [172.17.6.105] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Subject: Re: [dpdk-dev] [PATCH v18 13/19] raw/ifpga/base: add secure support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Xu, Rosen > Sent: Thursday, November 14, 2019 5:03 PM > To: dev@dpdk.org > Cc: Xu, Rosen ; Zhang, Tianfei ; > Pei, Andy ; Ye, Xiaolong ; Yig= it, > Ferruh > Subject: [PATCH v18 13/19] raw/ifpga/base: add secure support >=20 > From: Tianfei zhang >=20 > Add secure max10 device support. In PAC N3000 Card, it implements the secure functionality on the MAX10 Boar= d Management Controller (BMC) as Root of Trust (RoT). It changes to MAX10 (= RTL and Nios FW) to enable secure RSU (Remote System Update) authentication= and integrity checks for FPGA Flat image, and FW updates to the card. The = card's BMC continues to support features such as power sequence management,= board monitoring via sensors, JTAG management and in-band SPI interface ac= cess. The external Flash on the card shall be programmed with the Intel roo= t public key hash (for BMC images and FW) and Customer/User key (for FPGA F= lat image) during manufacturing, so the image updates (RSU) shall be verifi= ed using ECDSA-256 P-256 and SHA2-256 before being written to the MAX10 Ima= ge Flash or FPGA Image Flash. This patch add RoT support for MAX10 because some registers and the content= of Device Tree have changed between RoT solution and Non-RoT solution. >=20 > Signed-off-by: Tianfei zhang > Signed-off-by: Andy Pei > --- > drivers/raw/ifpga/base/ifpga_defines.h | 2 + > drivers/raw/ifpga/base/ifpga_fme.c | 26 ++++-- > drivers/raw/ifpga/base/opae_intel_max10.c | 137 > +++++++++++++++++++++++++----- > drivers/raw/ifpga/base/opae_intel_max10.h | 80 ++++++++++++----- > 4 files changed, 198 insertions(+), 47 deletions(-) >=20 > diff --git a/drivers/raw/ifpga/base/ifpga_defines.h > b/drivers/raw/ifpga/base/ifpga_defines.h > index 8993cc6..1e84b15 100644 > --- a/drivers/raw/ifpga/base/ifpga_defines.h > +++ b/drivers/raw/ifpga/base/ifpga_defines.h > @@ -1698,6 +1698,8 @@ struct ifpga_fme_board_info { > u32 patch_version; > u32 minor_version; > u32 major_version; > + u32 max10_version; > + u32 nios_fw_version; > u32 nums_of_retimer; > u32 ports_per_retimer; > u32 nums_of_fvl; > diff --git a/drivers/raw/ifpga/base/ifpga_fme.c > b/drivers/raw/ifpga/base/ifpga_fme.c > index 794ca09..87fa596 100644 > --- a/drivers/raw/ifpga/base/ifpga_fme.c > +++ b/drivers/raw/ifpga/base/ifpga_fme.c > @@ -825,6 +825,7 @@ static int board_type_to_info(u32 type, static int > fme_get_board_interface(struct ifpga_fme_hw *fme) { > struct fme_bitstream_id id; > + u32 val; >=20 > if (fme_hdr_get_bitstream_id(fme, &id.id)) > return -EINVAL; > @@ -850,6 +851,18 @@ static int fme_get_board_interface(struct > ifpga_fme_hw *fme) > fme->board_info.nums_of_fvl, > fme->board_info.ports_per_fvl); >=20 > + if (max10_sys_read(MAX10_BUILD_VER, &val)) > + return -EINVAL; > + fme->board_info.max10_version =3D val & 0xffffff; > + > + if (max10_sys_read(NIOS2_FW_VERSION, &val)) > + return -EINVAL; > + fme->board_info.nios_fw_version =3D val & 0xffffff; > + > + dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n", > + fme->board_info.max10_version, > + fme->board_info.nios_fw_version); > + > return 0; > } >=20 > @@ -858,16 +871,11 @@ static int spi_self_checking(void) > u32 val; > int ret; >=20 > - ret =3D max10_reg_read(0x30043c, &val); > + ret =3D max10_sys_read(MAX10_TEST_REG, &val); > if (ret) > return -EIO; >=20 > - if (val !=3D 0x87654321) { > - dev_err(NULL, "Read MAX10 test register fail: 0x%x\n", val); > - return -EIO; > - } > - > - dev_info(NULL, "Read MAX10 test register success, SPI self-test done\n"= ); > + dev_info(NULL, "Read MAX10 test register 0x%x\n", val); >=20 > return 0; > } > @@ -1283,7 +1291,7 @@ int fme_mgr_get_retimer_status(struct > ifpga_fme_hw *fme, > if (!dev) > return -ENODEV; >=20 > - if (max10_reg_read(PKVL_LINK_STATUS, &val)) { > + if (max10_sys_read(PKVL_LINK_STATUS, &val)) { > dev_err(dev, "%s: read pkvl status fail\n", __func__); > return -EINVAL; > } > @@ -1311,7 +1319,7 @@ int fme_mgr_get_sensor_value(struct ifpga_fme_hw > *fme, > if (!dev) > return -ENODEV; >=20 > - if (max10_reg_read(sensor->value_reg, value)) { > + if (max10_sys_read(sensor->value_reg, value)) { > dev_err(dev, "%s: read sensor value register 0x%x fail\n", > __func__, sensor->value_reg); > return -EINVAL; > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c > b/drivers/raw/ifpga/base/opae_intel_max10.c > index ae7a8df..748ab56 100644 > --- a/drivers/raw/ifpga/base/opae_intel_max10.c > +++ b/drivers/raw/ifpga/base/opae_intel_max10.c > @@ -30,6 +30,22 @@ int max10_reg_write(unsigned int reg, unsigned int val= ) > reg, 4, (unsigned char *)&tmp); > } >=20 > +int max10_sys_read(unsigned int offset, unsigned int *val) { > + if (!g_max10) > + return -ENODEV; > + > + return max10_reg_read(g_max10->base + offset, val); } > + > +int max10_sys_write(unsigned int offset, unsigned int val) { > + if (!g_max10) > + return -ENODEV; > + > + return max10_reg_write(g_max10->base + offset, val); } > + > static struct max10_compatible_id max10_id_table[] =3D { > {.compatible =3D MAX10_PAC,}, > {.compatible =3D MAX10_PAC_N3000,}, > @@ -66,7 +82,8 @@ static void max10_check_capability(struct > intel_max10_device *max10) > max10->flags |=3D MAX10_FLAGS_NO_I2C2 | > MAX10_FLAGS_NO_BMCIMG_FLASH; > dev_info(max10, "found %s card\n", max10->id->compatible); > - } > + } else > + max10->flags |=3D MAX10_FLAGS_MAC_CACHE; > } >=20 > static int altera_nor_flash_read(u32 offset, @@ -100,7 +117,7 @@ static = int > enable_nor_flash(bool on) > unsigned int val =3D 0; > int ret; >=20 > - ret =3D max10_reg_read(RSU_REG_OFF, &val); > + ret =3D max10_sys_read(RSU_REG, &val); > if (ret) { > dev_err(NULL "enabling flash error\n"); > return ret; > @@ -111,7 +128,7 @@ static int enable_nor_flash(bool on) > else > val &=3D ~RSU_ENABLE; >=20 > - return max10_reg_write(RSU_REG_OFF, val); > + return max10_sys_write(RSU_REG, val); > } >=20 > static int init_max10_device_table(struct intel_max10_device *max10) @@ > -123,7 +140,7 @@ static int init_max10_device_table(struct > intel_max10_device *max10) > u32 dt_size, dt_addr, val; > int ret; >=20 > - ret =3D max10_reg_read(DT_AVAIL_REG_OFF, &val); > + ret =3D max10_sys_read(DT_AVAIL_REG, &val); > if (ret) { > dev_err(max10 "cannot read DT_AVAIL_REG\n"); > return ret; > @@ -134,7 +151,7 @@ static int init_max10_device_table(struct > intel_max10_device *max10) > return -EINVAL; > } >=20 > - ret =3D max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr); > + ret =3D max10_sys_read(DT_BASE_ADDR_REG, &dt_addr); > if (ret) { > dev_info(max10 "cannot get base addr of device table\n"); > return ret; > @@ -315,7 +332,7 @@ static int max10_add_sensor(struct raw_sensor_info > *info, > if (!sensor_reg_valid(&info->regs[i])) > continue; >=20 > - ret =3D max10_reg_read(info->regs[i].regoff, &val); > + ret =3D max10_sys_read(info->regs[i].regoff, &val); > if (ret) > break; >=20 > @@ -355,7 +372,8 @@ static int max10_add_sensor(struct raw_sensor_info > *info, > return ret; > } >=20 > -static int max10_sensor_init(struct intel_max10_device *dev) > +static int > +max10_sensor_init(struct intel_max10_device *dev, int parent) > { > int i, ret =3D 0, offset =3D 0; > const fdt32_t *num; > @@ -370,7 +388,7 @@ static int max10_sensor_init(struct intel_max10_devic= e > *dev) > return 0; > } >=20 > - fdt_for_each_subnode(offset, fdt_root, 0) { > + fdt_for_each_subnode(offset, fdt_root, parent) { > ptr =3D fdt_get_name(fdt_root, offset, NULL); > if (!ptr) { > dev_err(dev, "failed to fdt get name\n"); @@ -417,7 +435,16 > @@ static int max10_sensor_init(struct intel_max10_device *dev) > continue; > } >=20 > - raw->regs[i].regoff =3D start; > + /* This is a hack to compatible with non-secure > + * solution. If sensors are included in root node, > + * then it's non-secure dtb, which use absolute addr > + * of non-secure solution. > + */ > + if (parent) > + raw->regs[i].regoff =3D start; > + else > + raw->regs[i].regoff =3D start - > + MAX10_BASE_ADDR; > raw->regs[i].size =3D size; > } >=20 > @@ -469,6 +496,63 @@ static int max10_sensor_init(struct > intel_max10_device *dev) > return ret; > } >=20 > +static int check_max10_version(struct intel_max10_device *dev) { > + unsigned int v; > + > + if (!max10_reg_read(MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER, > + &v)) { > + if (v !=3D 0xffffffff) { > + dev_info(dev, "secure MAX10 detected\n"); > + dev->base =3D MAX10_SEC_BASE_ADDR; > + dev->flags |=3D MAX10_FLAGS_SECURE; > + } else { > + dev_info(dev, "non-secure MAX10 detected\n"); > + dev->base =3D MAX10_BASE_ADDR; > + } > + return 0; > + } > + > + return -ENODEV; > +} > + > +static int > +max10_secure_hw_init(struct intel_max10_device *dev) { > + int offset, sysmgr_offset =3D 0; > + char *fdt_root; > + > + fdt_root =3D dev->fdt_root; > + if (!fdt_root) { > + dev_debug(dev, "skip init as not find Device Tree\n"); > + return 0; > + } > + > + fdt_for_each_subnode(offset, fdt_root, 0) { > + if (!fdt_node_check_compatible(fdt_root, offset, > + "intel-max10,system-manager")) { > + sysmgr_offset =3D offset; > + break; > + } > + } > + > + max10_check_capability(dev); > + > + max10_sensor_init(dev, sysmgr_offset); > + > + return 0; > +} > + > +static int > +max10_non_secure_hw_init(struct intel_max10_device *dev) { > + max10_check_capability(dev); > + > + max10_sensor_init(dev, 0); > + > + return 0; > +} > + > struct intel_max10_device * > intel_max10_device_probe(struct altera_spi_device *spi, > int chipselect) > @@ -492,32 +576,47 @@ struct intel_max10_device * > /* set the max10 device firstly */ > g_max10 =3D dev; >=20 > - /* init the MAX10 device table */ > + /* check the max10 version */ > + ret =3D check_max10_version(dev); > + if (ret) { > + dev_err(dev, "Failed to find max10 hardware!\n"); > + goto free_dev; > + } > + > + /* load the MAX10 device table */ > ret =3D init_max10_device_table(dev); > if (ret) { > - dev_err(dev, "init max10 device table fail\n"); > + dev_err(dev, "Init max10 device table fail\n"); > goto free_dev; > } >=20 > - max10_check_capability(dev); > + /* init max10 devices, like sensor*/ > + if (dev->flags & MAX10_FLAGS_SECURE) > + ret =3D max10_secure_hw_init(dev); > + else > + ret =3D max10_non_secure_hw_init(dev); > + if (ret) { > + dev_err(dev, "Failed to init max10 hardware!\n"); > + goto free_dtb; > + } >=20 > /* read FPGA loading information */ > - ret =3D max10_reg_read(FPGA_PAGE_INFO_OFF, &val); > + ret =3D max10_sys_read(FPGA_PAGE_INFO, &val); > if (ret) { > dev_err(dev, "fail to get FPGA loading info\n"); > - goto spi_tran_fail; > + goto release_max10_hw; > } > dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory"); >=20 > - > - max10_sensor_init(dev); > - > return dev; >=20 > -spi_tran_fail: > +release_max10_hw: > + max10_sensor_uinit(); > +free_dtb: > if (dev->fdt_root) > opae_free(dev->fdt_root); > - spi_transaction_remove(dev->spi_tran_dev); > + if (dev->spi_tran_dev) > + spi_transaction_remove(dev->spi_tran_dev); > free_dev: > g_max10 =3D NULL; > opae_free(dev); > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h > b/drivers/raw/ifpga/base/opae_intel_max10.h > index 90bf098..e632941 100644 > --- a/drivers/raw/ifpga/base/opae_intel_max10.h > +++ b/drivers/raw/ifpga/base/opae_intel_max10.h > @@ -23,6 +23,8 @@ struct max10_compatible_id { > #define MAX10_FLAGS_SPI BIT(3) > #define MAX10_FLGAS_NIOS_SPI BIT(4) > #define MAX10_FLAGS_PKVL BIT(5) > +#define MAX10_FLAGS_SECURE BIT(6) > +#define MAX10_FLAGS_MAC_CACHE BIT(7) >=20 > struct intel_max10_device { > unsigned int flags; /*max10 hardware capability*/ @@ -30,6 +32,7 @@ > struct intel_max10_device { > struct spi_transaction_dev *spi_tran_dev; > struct max10_compatible_id *id; /*max10 compatible*/ > char *fdt_root; > + unsigned int base; /* max10 base address */ > }; >=20 > /* retimer speed */ > @@ -74,30 +77,69 @@ struct opae_retimer_status { #define FLASH_BASE > 0x10000000 #define FLASH_OPTION_BITS 0x10000 >=20 > -#define NIOS2_FW_VERSION_OFF 0x300400 > -#define RSU_REG_OFF 0x30042c > -#define FPGA_RP_LOAD BIT(3) > -#define NIOS2_PRERESET BIT(4) > -#define NIOS2_HANG BIT(5) > -#define RSU_ENABLE BIT(6) > -#define NIOS2_RESET BIT(7) > -#define NIOS2_I2C2_POLL_STOP BIT(13) > -#define FPGA_RECONF_REG_OFF 0x300430 > -#define COUNTDOWN_START BIT(18) > -#define MAX10_BUILD_VER_OFF 0x300468 > -#define PCB_INFO GENMASK(31, 24) > -#define MAX10_BUILD_VERION GENMASK(23, 0) > -#define FPGA_PAGE_INFO_OFF 0x30046c > -#define DT_AVAIL_REG_OFF 0x300490 > -#define DT_AVAIL BIT(0) > -#define DT_BASE_ADDR_REG_OFF 0x300494 > -#define PKVL_POLLING_CTRL 0x300480 > -#define PKVL_LINK_STATUS 0x300564 > +/* System Registers */ > +#define MAX10_BASE_ADDR 0x300400 > +#define MAX10_SEC_BASE_ADDR 0x300800 > +/* Register offset of system registers */ > +#define NIOS2_FW_VERSION 0x0 > +#define MAX10_MACADDR1 0x10 > +#define MAX10_MAC_BYTE4 GENMASK(7, 0) > +#define MAX10_MAC_BYTE3 GENMASK(15, 8) > +#define MAX10_MAC_BYTE2 GENMASK(23, 16) > +#define MAX10_MAC_BYTE1 GENMASK(31, 24) > +#define MAX10_MACADDR2 0x14 > +#define MAX10_MAC_BYTE6 GENMASK(7, 0) > +#define MAX10_MAC_BYTE5 GENMASK(15, 8) > +#define MAX10_MAC_COUNT GENMASK(23, 16) > +#define RSU_REG 0x2c > +#define FPGA_RECONF_PAGE GENMASK(2, 0) > +#define FPGA_RP_LOAD BIT(3) > +#define NIOS2_PRERESET BIT(4) > +#define NIOS2_HANG BIT(5) > +#define RSU_ENABLE BIT(6) > +#define NIOS2_RESET BIT(7) > +#define NIOS2_I2C2_POLL_STOP BIT(13) > +#define PKVL_EEPROM_LOAD BIT(31) > +#define FPGA_RECONF_REG 0x30 > +#define MAX10_TEST_REG 0x3c > +#define COUNTDOWN_START BIT(18) > +#define MAX10_BUILD_VER 0x68 > +#define MAX10_VERSION_MAJOR GENMASK(23, 16) > +#define PCB_INFO GENMASK(31, 24) > +#define FPGA_PAGE_INFO 0x6c > +#define DT_AVAIL_REG 0x90 > +#define DT_AVAIL BIT(0) > +#define DT_BASE_ADDR_REG 0x94 > +#define MAX10_DOORBELL 0x400 > +#define RSU_REQUEST BIT(0) > +#define SEC_PROGRESS GENMASK(7, 4) > +#define HOST_STATUS GENMASK(11, 8) > +#define SEC_STATUS GENMASK(23, 16) > + > +/* PKVL related registers, in system register region */ > +#define PKVL_POLLING_CTRL 0x80 > +#define POLLING_MODE GENMASK(15, 0) > +#define PKVL_A_PRELOAD BIT(16) > +#define PKVL_A_PRELOAD_TIMEOUT BIT(17) > +#define PKVL_A_DATA_TOO_BIG BIT(18) > +#define PKVL_A_HDR_CHECKSUM BIT(20) > +#define PKVL_B_PRELOAD BIT(24) > +#define PKVL_B_PRELOAD_TIMEOUT BIT(25) > +#define PKVL_B_DATA_TOO_BIG BIT(26) > +#define PKVL_B_HDR_CHECKSUM BIT(28) > +#define PKVL_EEPROM_UPG_STATUS GENMASK(31, 16) > +#define PKVL_LINK_STATUS 0x164 > +#define PKVL_A_VERSION 0x254 > +#define PKVL_B_VERSION 0x258 > +#define SERDES_VERSION GENMASK(15, 0) > +#define SBUS_VERSION GENMASK(31, 16) >=20 > #define DFT_MAX_SIZE 0x7e0000 >=20 > int max10_reg_read(unsigned int reg, unsigned int *val); int > max10_reg_write(unsigned int reg, unsigned int val); > +int max10_sys_read(unsigned int offset, unsigned int *val); int > +max10_sys_write(unsigned int offset, unsigned int val); > struct intel_max10_device * > intel_max10_device_probe(struct altera_spi_device *spi, > int chipselect); > -- > 1.8.3.1