diff options
Diffstat (limited to 'bsp/meta-altera/recipes-bsp/u-boot/files/v2019.07/0006-ARM-socfpga-stratix10-Add-Stratix10-FPGA-configurati.patch')
-rw-r--r-- | bsp/meta-altera/recipes-bsp/u-boot/files/v2019.07/0006-ARM-socfpga-stratix10-Add-Stratix10-FPGA-configurati.patch | 833 |
1 files changed, 0 insertions, 833 deletions
diff --git a/bsp/meta-altera/recipes-bsp/u-boot/files/v2019.07/0006-ARM-socfpga-stratix10-Add-Stratix10-FPGA-configurati.patch b/bsp/meta-altera/recipes-bsp/u-boot/files/v2019.07/0006-ARM-socfpga-stratix10-Add-Stratix10-FPGA-configurati.patch deleted file mode 100644 index cc0be27b..00000000 --- a/bsp/meta-altera/recipes-bsp/u-boot/files/v2019.07/0006-ARM-socfpga-stratix10-Add-Stratix10-FPGA-configurati.patch +++ /dev/null @@ -1,833 +0,0 @@ -From 04187fba93e6d359ebb4dd8e397dff282f53ec5a Mon Sep 17 00:00:00 2001 -From: "Ang, Chee Hong" <chee.hong.ang@intel.com> -Date: Mon, 29 Apr 2019 23:42:39 -0700 -Subject: [PATCH 06/12] ARM: socfpga: stratix10: Add Stratix10 FPGA - configuration PSCI services - -Allow PSCI layer to handle the S10 FPGA configuration (SiP) service -calls. All these services are also known as FPGA configuration service -layer for S10. This service layer support FPGA configuration service -requests from OS (EL1). It acts as the middle layer between SDM -(Secure Device Manager) and the OS. It enables OS (EL1) to invoke SMC -call to this service layer (EL3) and pass the FPGA bit stream to SDM -for FPGA configuration. - -Signed-off-by: Ang, Chee Hong <chee.hong.ang@intel.com> ---- - arch/arm/mach-socfpga/Makefile | 1 + - arch/arm/mach-socfpga/include/mach/smc_s10.h | 42 ++ - arch/arm/mach-socfpga/smc_fpga_reconfig_s10.c | 422 ++++++++++++++++++ - include/linux/intel-smc.h | 311 +++++++++++++ - 4 files changed, 776 insertions(+) - create mode 100644 arch/arm/mach-socfpga/include/mach/smc_s10.h - create mode 100644 arch/arm/mach-socfpga/smc_fpga_reconfig_s10.c - create mode 100644 include/linux/intel-smc.h - -diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile -index d34198d159..88970e7555 100644 ---- a/arch/arm/mach-socfpga/Makefile -+++ b/arch/arm/mach-socfpga/Makefile -@@ -41,6 +41,7 @@ obj-y += wrap_pinmux_config_s10.o - obj-y += wrap_pll_config_s10.o - ifndef CONFIG_SPL_BUILD - obj-$(CONFIG_ARMV8_PSCI) += psci.o -+obj-$(CONFIG_FPGA_STRATIX10) += smc_fpga_reconfig_s10.o - endif - endif - -diff --git a/arch/arm/mach-socfpga/include/mach/smc_s10.h b/arch/arm/mach-socfpga/include/mach/smc_s10.h -new file mode 100644 -index 0000000000..9c82d863e5 ---- /dev/null -+++ b/arch/arm/mach-socfpga/include/mach/smc_s10.h -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2018 Intel Corporation. All rights reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#include <common.h> -+ -+#define SMC_ARG0 0 -+#define SMC_ARG1 (SMC_ARG0 + 1) -+#define SMC_ARG2 (SMC_ARG1 + 1) -+#define SMC_ARG3 (SMC_ARG2 + 1) -+#define SMC_RETURN_ARGS_MAX (SMC_ARG3 + 1) -+ -+/* Macro functions for allocation and read/write of -+ variables to be assigned to registers */ -+/* Allocate memory for variable */ -+#define SMC_ALLOC_REG_MEM(var) unsigned long var[SMC_RETURN_ARGS_MAX] -+/* Clear variable */ -+#define SMC_INIT_REG_MEM(var) \ -+ do { \ -+ int i; \ -+ for (i = 0; i < SMC_RETURN_ARGS_MAX; i++) \ -+ var[i] = 0; \ -+ } while (0) -+/* Read variable */ -+#define SMC_GET_REG_MEM(var, i) var[i] -+/* Write Variable */ -+#define SMC_ASSIGN_REG_MEM(var, i, val) \ -+ do { \ -+ var[i] = (val); \ -+ } while (0) -+/* Assign variables back to registers */ -+#define SMC_RET_REG_MEM(var) \ -+ do { \ -+ asm volatile("ldr x0, %0\n" \ -+ "ldr x1, %1\n" \ -+ "ldr x2, %2\n" \ -+ "ldr x3, %3\n" \ -+ : : "m" (var[0]), "m" (var[1]), \ -+ "m" (var[2]), "m" (var[3]) : ); \ -+ } while (0) -diff --git a/arch/arm/mach-socfpga/smc_fpga_reconfig_s10.c b/arch/arm/mach-socfpga/smc_fpga_reconfig_s10.c -new file mode 100644 -index 0000000000..0ed12e16b4 ---- /dev/null -+++ b/arch/arm/mach-socfpga/smc_fpga_reconfig_s10.c -@@ -0,0 +1,422 @@ -+/* -+ * Copyright (C) 2018 Intel Corporation. All rights reserved -+ * -+ * SPDX-License-Identifier: GPL-2.0 -+ */ -+ -+#include <common.h> -+#include <errno.h> -+#include <asm/io.h> -+#include <asm/psci.h> -+#include <asm/secure.h> -+#include <asm/arch/mailbox_s10.h> -+#include <asm/arch/smc_s10.h> -+#include <linux/intel-smc.h> -+#include <asm/arch/reset_manager.h> -+ -+/* Start of reserved memory */ -+#define FPGA_CONFIG_RESEVED_MEM_START (CONFIG_SYS_SDRAM_BASE + \ -+ 0x400000) -+/* End of reserved memory */ -+#define FPGA_CONFIG_RESERVED_MEM_END (CONFIG_SYS_SDRAM_BASE + \ -+ 0xFFFFFF) -+ -+#define FPGA_CONFIG_BUF_MAX 16 -+ -+#define FPGA_BUF_STAT_IDLE 0 -+#define FPGA_BUF_STAT_PENDING 1 -+#define FPGA_BUF_STAT_COMPLETED 2 -+#define FPGA_BUF_STAT_SUCCESS 3 -+#define FPGA_BUF_STAT_ERROR 4 -+ -+#define IS_BUF_FREE(x) (x.state == FPGA_BUF_STAT_IDLE) -+#define IS_BUF_PENDING(x) (x.state == FPGA_BUF_STAT_PENDING) -+#define IS_BUF_SUBMITTED(x) (x.state >= FPGA_BUF_STAT_PENDING && \ -+ x.submit_count > 0) -+#define IS_BUF_COMPLETED(x) (x.state == FPGA_BUF_STAT_COMPLETED && \ -+ x.submit_count > 0) -+#define IS_BUF_FULLY_COMPLETED(x) (x.state == FPGA_BUF_STAT_COMPLETED && \ -+ x.submit_count == 0) -+#define IS_BUF_SUCCESS(x) (x.state == FPGA_BUF_STAT_SUCCESS) -+#define IS_BUF_ERROR(x) (x.state == FPGA_BUF_STAT_ERROR) -+ -+static __secure_data struct fpga_buf_list { -+ u32 state; -+ u32 buf_id; -+ u64 buf_addr; -+ u64 buf_size; -+ u32 buf_off; -+ u32 submit_count; -+} fpga_buf_list[FPGA_CONFIG_BUF_MAX]; -+ -+static u8 __secure_data fpga_error = 1; -+static u8 __secure_data is_partial_reconfig; -+static u8 __secure_data fpga_buf_id = 1; -+static u32 __secure_data fpga_xfer_max = 4; -+static u32 __secure_data fpga_buf_read_index; -+static u32 __secure_data fpga_buf_write_index; -+static u32 __secure_data fpga_buf_count; -+/* 20bits DMA size with 8 bytes alignment */ -+static u32 __secure_data fpga_buf_size_max = 0xFFFF8; -+/* Number of data blocks received from OS(EL1) */ -+static u32 __secure_data fpga_buf_rcv_count; -+/* Number of data blocks submitted to SDM */ -+static u32 __secure_data fpga_xfer_submitted_count; -+ -+/* Check for any responses from SDM and update the status in buffer list */ -+static void __secure reclaim_completed_buf(void) -+{ -+ u32 i, j; -+ u32 resp_len; -+ u32 buf[MBOX_RESP_BUFFER_SIZE]; -+ -+ /* If no buffer has been submitted to SDM */ -+ if (!fpga_xfer_submitted_count) -+ return; -+ -+ /* Read the SDM responses asynchronously */ -+ resp_len = mbox_rcv_resp_psci(buf, MBOX_RESP_BUFFER_SIZE); -+ -+ for (i = 0; i < resp_len; i++) { -+ /* Skip mailbox response headers which are not belong to us */ -+ if (MBOX_RESP_LEN_GET(buf[i]) || -+ MBOX_RESP_CLIENT_GET(buf[i]) != MBOX_CLIENT_ID_UBOOT) -+ continue; -+ -+ for (j = 0; j < FPGA_CONFIG_BUF_MAX; j++) { -+ /* Check buffer id */ -+ if (fpga_buf_list[j].buf_id != -+ MBOX_RESP_ID_GET(buf[i])) -+ continue; -+ -+ if (IS_BUF_SUBMITTED(fpga_buf_list[j])) { -+ if (fpga_buf_list[j].submit_count) -+ fpga_buf_list[j].submit_count--; -+ fpga_xfer_submitted_count--; -+ /* Error occur in transaction */ -+ if (MBOX_RESP_ERR_GET(buf[i])) { -+ fpga_error = 1; -+ fpga_buf_list[j].state = -+ FPGA_BUF_STAT_ERROR; -+ fpga_buf_list[j].submit_count = 0; -+ } else if (IS_BUF_FULLY_COMPLETED( -+ fpga_buf_list[j])) { -+ /* Last chunk in buffer and no error */ -+ fpga_buf_list[j].state = -+ FPGA_BUF_STAT_SUCCESS; -+ } -+ break; -+ } else if (IS_BUF_ERROR(fpga_buf_list[j])) { -+ fpga_xfer_submitted_count--; -+ break; -+ } -+ } -+ } -+} -+ -+static void __secure do_xfer_buf(void) -+{ -+ u32 i = fpga_buf_read_index; -+ u32 args[3]; -+ int ret; -+ -+ /* No buffer found in buffer list or SDM can't handle xfer anymore */ -+ if (!fpga_buf_rcv_count || -+ fpga_xfer_submitted_count == fpga_xfer_max) -+ return; -+ -+ while (fpga_xfer_submitted_count < fpga_xfer_max) { -+ if (IS_BUF_FREE(fpga_buf_list[i]) || -+ IS_BUF_ERROR(fpga_buf_list[i])) -+ break; -+ if (IS_BUF_PENDING(fpga_buf_list[i])) { -+ /* -+ * Argument descriptor for RECONFIG_DATA -+ * must always be 1. -+ */ -+ args[0] = MBOX_ARG_DESC_COUNT(1); -+ args[1] = (u32)(fpga_buf_list[i].buf_addr + -+ fpga_buf_list[i].buf_off); -+ if ((fpga_buf_list[i].buf_size - -+ fpga_buf_list[i].buf_off) > fpga_buf_size_max) { -+ args[2] = fpga_buf_size_max; -+ fpga_buf_list[i].buf_off += fpga_buf_size_max; -+ } else { -+ args[2] = (u32)(fpga_buf_list[i].buf_size - -+ fpga_buf_list[i].buf_off); -+ fpga_buf_list[i].state = -+ FPGA_BUF_STAT_COMPLETED; -+ } -+ -+ ret = mbox_send_cmd_only_psci(fpga_buf_list[i].buf_id, -+ MBOX_RECONFIG_DATA, MBOX_CMD_INDIRECT, 3, -+ args); -+ if (ret) { -+ fpga_error = 1; -+ fpga_buf_list[i].state = -+ FPGA_BUF_STAT_ERROR; -+ fpga_buf_list[i].submit_count = 0; -+ break; -+ } else { -+ fpga_buf_list[i].submit_count++; -+ fpga_xfer_submitted_count++; -+ } -+ -+ if (fpga_xfer_submitted_count >= fpga_xfer_max) -+ break; -+ } -+ -+ if (IS_BUF_COMPLETED(fpga_buf_list[i]) || -+ IS_BUF_SUCCESS(fpga_buf_list[i])) { -+ i++; -+ i %= FPGA_CONFIG_BUF_MAX; -+ if (i == fpga_buf_write_index) -+ break; -+ } -+ } -+} -+ -+static void __secure smc_config_get_mem(unsigned long function_id) -+{ -+ SMC_ALLOC_REG_MEM(r); -+ -+ SMC_INIT_REG_MEM(r); -+ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, INTEL_SIP_SMC_STATUS_OK); -+ /* Start physical address of reserved memory */ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG1, FPGA_CONFIG_RESEVED_MEM_START); -+ /* Size of reserved memory */ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG2, FPGA_CONFIG_RESERVED_MEM_END - -+ FPGA_CONFIG_RESEVED_MEM_START + 1); -+ -+ SMC_RET_REG_MEM(r); -+} -+ -+static void __secure smc_config_start(unsigned long function_id, -+ unsigned long config_type) -+{ -+ SMC_ALLOC_REG_MEM(r); -+ int ret, i; -+ u32 resp_len = 2; -+ u32 resp_buf[2]; -+ -+ /* Clear any previous pending SDM reponses */ -+ mbox_rcv_resp_psci(NULL, MBOX_RESP_BUFFER_SIZE); -+ -+ SMC_INIT_REG_MEM(r); -+ -+ fpga_error = 0; -+ -+ ret = mbox_send_cmd_psci(MBOX_ID_UBOOT, MBOX_RECONFIG, MBOX_CMD_DIRECT, -+ 0, NULL, 0, &resp_len, resp_buf); -+ if (ret) { -+ fpga_error = 1; -+ goto ret; -+ } -+ -+ /* Initialize the state of the buffer list */ -+ for (i = 0; i < FPGA_CONFIG_BUF_MAX; i++) { -+ fpga_buf_list[i].state = FPGA_BUF_STAT_IDLE; -+ fpga_buf_list[i].buf_id = 0; -+ } -+ -+ /* Read maximum transaction allowed by SDM */ -+ fpga_xfer_max = resp_buf[0]; -+ /* Read maximum buffer size allowed by SDM */ -+ fpga_buf_size_max = resp_buf[1]; -+ fpga_buf_count = 0; -+ fpga_buf_rcv_count = 0; -+ fpga_xfer_submitted_count = 0; -+ fpga_buf_read_index = 0; -+ fpga_buf_write_index = 0; -+ fpga_buf_id = 1; -+ -+ is_partial_reconfig = (u8)config_type; -+ -+ /* Check whether config type is full reconfiguration */ -+ if (!is_partial_reconfig) { -+ /* Disable bridge */ -+ socfpga_bridges_reset_psci(0); -+ } -+ -+ret: -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, INTEL_SIP_SMC_STATUS_OK); -+ -+ SMC_RET_REG_MEM(r); -+} -+ -+static void __secure smc_config_write(unsigned long function_id, -+ unsigned long phys_addr, -+ unsigned long phys_size) -+{ -+ SMC_ALLOC_REG_MEM(r); -+ -+ SMC_INIT_REG_MEM(r); -+ -+ reclaim_completed_buf(); -+ -+ if (fpga_error) { -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG1, -+ fpga_buf_list[fpga_buf_read_index]. -+ buf_addr); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG2, -+ fpga_buf_list[fpga_buf_read_index]. -+ buf_size); -+ goto ret; -+ } -+ -+ do_xfer_buf(); -+ -+ if (fpga_buf_rcv_count == fpga_xfer_max || -+ (fpga_buf_count == FPGA_CONFIG_BUF_MAX && -+ fpga_buf_write_index == fpga_buf_read_index)) { -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED); -+ goto ret; -+ } -+ -+ if (!phys_addr || !phys_size) { -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG1, phys_addr); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG2, phys_size); -+ goto ret; -+ } -+ -+ /* Look for free buffer in buffer list */ -+ if (IS_BUF_FREE(fpga_buf_list[fpga_buf_write_index])) { -+ fpga_buf_list[fpga_buf_write_index].state = -+ FPGA_BUF_STAT_PENDING; -+ fpga_buf_list[fpga_buf_write_index].buf_addr = phys_addr; -+ fpga_buf_list[fpga_buf_write_index].buf_size = phys_size; -+ fpga_buf_list[fpga_buf_write_index].buf_off = 0; -+ fpga_buf_list[fpga_buf_write_index].buf_id = fpga_buf_id++; -+ /* Rollover buffer id */ -+ if (fpga_buf_id > 15) -+ fpga_buf_id = 1; -+ fpga_buf_count++; -+ fpga_buf_write_index++; -+ fpga_buf_write_index %= FPGA_CONFIG_BUF_MAX; -+ fpga_buf_rcv_count++; -+ if (fpga_buf_rcv_count == fpga_xfer_max) -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY); -+ else -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_STATUS_OK); -+ /* Attempt to submit new buffer to SDM */ -+ do_xfer_buf(); -+ } else { -+ /* No free buffer available in buffer list */ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED); -+ } -+ -+ret: -+ SMC_RET_REG_MEM(r); -+} -+ -+static void __secure smc_config_completed_write(unsigned long function_id) -+{ -+ SMC_ALLOC_REG_MEM(r); -+ int i; -+ int count = 3, r_index = 1; -+ -+ SMC_INIT_REG_MEM(r); -+ -+ reclaim_completed_buf(); -+ do_xfer_buf(); -+ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_STATUS_OK); -+ -+ for (i = 0; i < FPGA_CONFIG_BUF_MAX; i++) { -+ if (IS_BUF_SUCCESS(fpga_buf_list[fpga_buf_read_index])) { -+ SMC_ASSIGN_REG_MEM(r, r_index++, -+ fpga_buf_list[fpga_buf_read_index].buf_addr); -+ fpga_buf_list[fpga_buf_read_index].state = -+ FPGA_BUF_STAT_IDLE; -+ fpga_buf_list[fpga_buf_read_index].buf_id = 0; -+ fpga_buf_count--; -+ fpga_buf_read_index++; -+ fpga_buf_read_index %= FPGA_CONFIG_BUF_MAX; -+ fpga_buf_rcv_count--; -+ count--; -+ if (!count) -+ break; -+ } else if (IS_BUF_ERROR(fpga_buf_list[fpga_buf_read_index]) && -+ !fpga_buf_list[fpga_buf_read_index].submit_count) { -+ SMC_INIT_REG_MEM(r); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG1, -+ fpga_buf_list[fpga_buf_read_index].buf_addr); -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG2, -+ fpga_buf_list[fpga_buf_read_index].buf_size); -+ goto ret; -+ } -+ } -+ -+ /* No completed buffers found */ -+ if (r_index == 1 && fpga_xfer_submitted_count) -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY); -+ -+ret: -+ SMC_RET_REG_MEM(r); -+} -+ -+static void __secure smc_config_isdone(unsigned long function_id) -+{ -+ SMC_ALLOC_REG_MEM(r); -+ int ret; -+ -+ SMC_INIT_REG_MEM(r); -+ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY); -+ -+ reclaim_completed_buf(); -+ do_xfer_buf(); -+ -+ if (fpga_error) { -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR); -+ goto ret; -+ } -+ -+ if (fpga_xfer_submitted_count) -+ goto ret; -+ -+ ret = mbox_get_fpga_config_status_psci(MBOX_RECONFIG_STATUS); -+ if (ret) { -+ if (ret != MBOX_CFGSTAT_STATE_CONFIG) { -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, -+ INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR); -+ fpga_error = 1; -+ } -+ goto ret; -+ } -+ -+ /* FPGA configuration completed successfully */ -+ SMC_ASSIGN_REG_MEM(r, SMC_ARG0, INTEL_SIP_SMC_STATUS_OK); -+ -+ /* Check whether config type is full reconfiguration */ -+ if (!is_partial_reconfig) -+ socfpga_bridges_reset_psci(1); /* Enable bridge */ -+ret: -+ SMC_RET_REG_MEM(r); -+} -+ -+DECLARE_SECURE_SVC(config_get_mem, INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM, -+ smc_config_get_mem); -+DECLARE_SECURE_SVC(config_start, INTEL_SIP_SMC_FPGA_CONFIG_START, -+ smc_config_start); -+DECLARE_SECURE_SVC(config_write, INTEL_SIP_SMC_FPGA_CONFIG_WRITE, -+ smc_config_write); -+DECLARE_SECURE_SVC(config_completed_write, -+ INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE, -+ smc_config_completed_write); -+DECLARE_SECURE_SVC(config_isdone, INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, -+ smc_config_isdone); -diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h -new file mode 100644 -index 0000000000..5e4c156e42 ---- /dev/null -+++ b/include/linux/intel-smc.h -@@ -0,0 +1,311 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Copyright (C) 2017-2018, Intel Corporation -+ */ -+ -+#ifndef __INTEL_SMC_H -+#define __INTEL_SMC_H -+ -+#include <linux/arm-smccc.h> -+#include <linux/bitops.h> -+ -+/* -+ * This file defines the Secure Monitor Call (SMC) message protocol used for -+ * service layer driver in normal world (EL1) to communicate with secure -+ * monitor software in Secure Monitor Exception Level 3 (EL3). -+ * -+ * This file is shared with secure firmware (FW) which is out of kernel tree. -+ * -+ * An ARM SMC instruction takes a function identifier and up to 6 64-bit -+ * register values as arguments, and can return up to 4 64-bit register -+ * value. The operation of the secure monitor is determined by the parameter -+ * values passed in through registers. -+ -+ * EL1 and EL3 communicates pointer as physical address rather than the -+ * virtual address. -+ */ -+ -+/* -+ * Functions specified by ARM SMC Calling convention: -+ * -+ * FAST call executes atomic operations, returns when the requested operation -+ * has completed. -+ * STD call starts a operation which can be preempted by a non-secure -+ * interrupt. The call can return before the requested operation has -+ * completed. -+ * -+ * a0..a7 is used as register names in the descriptions below, on arm32 -+ * that translates to r0..r7 and on arm64 to w0..w7. -+ */ -+ -+#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \ -+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \ -+ ARM_SMCCC_OWNER_SIP, (func_num)) -+ -+#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \ -+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \ -+ ARM_SMCCC_OWNER_SIP, (func_num)) -+ -+/* -+ * Return values in INTEL_SIP_SMC_* call -+ * -+ * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION: -+ * Secure monitor software doesn't recognize the request. -+ * -+ * INTEL_SIP_SMC_STATUS_OK: -+ * FPGA configuration completed successfully, -+ * In case of FPGA configuration write operation, it means secure monitor -+ * software can accept the next chunk of FPGA configuration data. -+ * -+ * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY: -+ * In case of FPGA configuration write operation, it means secure monitor -+ * software is still processing previous data & can't accept the next chunk -+ * of data. Service driver needs to issue -+ * INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE call to query the -+ * completed block(s). -+ * -+ * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR: -+ * There is error during the FPGA configuration process. -+ * -+ * INTEL_SIP_SMC_REG_ERROR: -+ * There is error during a read or write operation of the protected -+ * registers. -+ */ -+#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF -+#define INTEL_SIP_SMC_STATUS_OK 0x0 -+#define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY 0x1 -+#define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_REJECTED 0x2 -+#define INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR 0x4 -+#define INTEL_SIP_SMC_REG_ERROR 0x5 -+#define INTEL_SIP_SMC_RSU_ERROR 0x7 -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_START -+ * -+ * Sync call used by service driver at EL1 to request the FPGA in EL3 to -+ * be prepare to receive a new configuration. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_START. -+ * a1: flag for full or partial configuration -+ * 0 full reconfiguration. -+ * 1 partial reconfiguration. -+ * a2-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK, or INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1-3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START 1 -+#define INTEL_SIP_SMC_FPGA_CONFIG_START \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START) -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_WRITE -+ * -+ * Async call used by service driver at EL1 to provide FPGA configuration data -+ * to secure world. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_WRITE. -+ * a1: 64bit physical address of the configuration data memory block -+ * a2: Size of configuration data block. -+ * a3-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY or -+ * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1: 64bit physical address of 1st completed memory block if any completed -+ * block, otherwise zero value. -+ * a2: 64bit physical address of 2nd completed memory block if any completed -+ * block, otherwise zero value. -+ * a3: 64bit physical address of 3rd completed memory block if any completed -+ * block, otherwise zero value. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE 2 -+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE \ -+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE) -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE -+ * -+ * Sync call used by service driver at EL1 to track the completed write -+ * transactions. This request is called after INTEL_SIP_SMC_FPGA_CONFIG_WRITE -+ * call returns INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE. -+ * a1-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY or -+ * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1: 64bit physical address of 1st completed memory block. -+ * a2: 64bit physical address of 2nd completed memory block if -+ * any completed block, otherwise zero value. -+ * a3: 64bit physical address of 3rd completed memory block if -+ * any completed block, otherwise zero value. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE 3 -+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE \ -+INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_ISDONE -+ * -+ * Sync call used by service driver at EL1 to inform secure world that all -+ * data are sent, to check whether or not the secure world had completed -+ * the FPGA configuration process. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_ISDONE. -+ * a1-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_FPGA_CONFIG_STATUS_BUSY or -+ * INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1-3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE 4 -+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE) -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM -+ * -+ * Sync call used by service driver at EL1 to query the physical address of -+ * memory block reserved by secure monitor software. -+ * -+ * Call register usage: -+ * a0:INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM. -+ * a1-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1: start of physical address of reserved memory block. -+ * a2: size of reserved memory block. -+ * a3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM 5 -+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM) -+ -+/* -+ * Request INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK -+ * -+ * For SMC loop-back mode only, used for internal integration, debugging -+ * or troubleshooting. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK. -+ * a1-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_FPGA_CONFIG_STATUS_ERROR. -+ * a1-3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK 6 -+#define INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK) -+ -+/* -+ * Request INTEL_SIP_SMC_REG_READ -+ * -+ * Read a protected register using SMCCC -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_REG_READ. -+ * a1: register address. -+ * a2-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. -+ * a1: Value in the register -+ * a2-3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_REG_READ 7 -+#define INTEL_SIP_SMC_REG_READ \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ) -+ -+/* -+ * Request INTEL_SIP_SMC_REG_WRITE -+ * -+ * Write a protected register using SMCCC -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_REG_WRITE. -+ * a1: register address -+ * a2: value to program into register. -+ * a3-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. -+ * a1-3: not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8 -+#define INTEL_SIP_SMC_REG_WRITE \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE) -+ -+/* -+ * Request INTEL_SIP_SMC_FUNCID_REG_UPDATE -+ * -+ * Update one or more bits in a protected register using a -+ * read-modify-write operation. -+ * -+ * Call register usage: -+ * a0: INTEL_SIP_SMC_REG_UPDATE. -+ * a1: register address -+ * a2: Write Mask. -+ * a3: Value to write. -+ * a4-7: not used. -+ * -+ * Return status: -+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR. -+ * a1-3: Not used. -+ */ -+#define INTEL_SIP_SMC_FUNCID_REG_UPDATE 9 -+#define INTEL_SIP_SMC_REG_UPDATE \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE) -+ -+/* -+ * Request INTEL_SIP_SMC_RSU_STATUS -+ * -+ * Sync call used by service driver at EL1 to query the RSU status -+ * -+ * Call register usage: -+ * a0 INTEL_SIP_SMC_RSU_STATUS -+ * a1-7 not used -+ * -+ * Return status -+ * a0: Current Image -+ * a1: Last Failing Image -+ * a2: Version [width 32 bit] | State [width 32 bit] -+ * a3: Error details [width 32 bit] | Error location [width 32 bit] -+ * -+ * Or -+ * -+ * a0: INTEL_SIP_SMC_RSU_ERROR -+ */ -+#define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11 -+#define INTEL_SIP_SMC_RSU_STATUS \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS) -+ -+/* -+ * Request INTEL_SIP_SMC_RSU_UPDATE -+ * -+ * Sync call used by service driver at EL1 to tell you next reboot is RSU_UPDATE -+ * -+ * Call register usage: -+ * a0 INTEL_SIP_SMC_RSU_UPDATE -+ * a1 64bit physical address of the configuration data memory in flash -+ * a2-7 not used -+ * -+ * Return status -+ * a0 INTEL_SIP_SMC_STATUS_OK -+ */ -+#define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12 -+#define INTEL_SIP_SMC_RSU_UPDATE \ -+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE) -+ -+ -+#endif --- -2.21.0 - |