- Add ATF flow for SoC64 devices
- Update socfpgaimage to support print header and update padding flow
This commit is contained in:
Tom Rini 2021-01-15 07:23:50 -05:00
commit 83e13c3469
32 changed files with 1449 additions and 37 deletions

View File

@ -1583,7 +1583,10 @@ u-boot.spr: spl/u-boot-spl.img u-boot.img FORCE
ifneq ($(CONFIG_ARCH_SOCFPGA),)
quiet_cmd_gensplx4 = GENSPLX4 $@
cmd_gensplx4 = cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \
cmd_gensplx4 = $(OBJCOPY) -I binary -O binary --gap-fill=0x0 \
--pad-to=$(CONFIG_SPL_PAD_TO) \
spl/u-boot-spl.sfp spl/u-boot-spl.sfp && \
cat spl/u-boot-spl.sfp spl/u-boot-spl.sfp \
spl/u-boot-spl.sfp spl/u-boot-spl.sfp > $@ || { rm -f $@; false; }
spl/u-boot-splx4.sfp: spl/u-boot-spl.sfp FORCE
$(call if_changed,gensplx4)

View File

@ -2,9 +2,11 @@
/*
* U-Boot additions
*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
* Copyright (C) 2019-2020 Intel Corporation <www.intel.com>
*/
#include "socfpga_soc64_fit-u-boot.dtsi"
/{
memory {
#address-cells = <2>;

View File

@ -0,0 +1,120 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* U-Boot additions
*
* Copyright (C) 2020 Intel Corporation <www.intel.com>
*/
#if defined(CONFIG_FIT)
/ {
binman: binman {
multiple-images;
};
};
&binman {
u-boot {
filename = "u-boot.itb";
fit {
fit,external-offset = <CONFIG_FIT_EXTERNAL_OFFSET>;
description = "FIT with firmware and bootloader";
#address-cells = <1>;
images {
uboot {
description = "U-Boot SoC64";
type = "standalone";
os = "U-Boot";
arch = "arm64";
compression = "none";
load = <0x00200000>;
uboot_blob: blob-ext {
filename = "u-boot-nodtb.bin";
};
};
atf {
description = "ARM Trusted Firmware";
type = "firmware";
os = "arm-trusted-firmware";
arch = "arm64";
compression = "none";
load = <0x00001000>;
entry = <0x00001000>;
atf_blob: blob-ext {
filename = "bl31.bin";
};
};
fdt {
description = "U-Boot SoC64 flat device-tree";
type = "flat_dt";
compression = "none";
uboot_fdt_blob: blob-ext {
filename = "u-boot.dtb";
};
};
};
configurations {
default = "conf";
conf {
description = "Intel SoC64 FPGA";
firmware = "atf";
loadables = "uboot";
fdt = "fdt";
};
};
};
};
kernel {
filename = "kernel.itb";
fit {
description = "FIT with Linux kernel image and FDT blob";
#address-cells = <1>;
images {
kernel {
description = "Linux Kernel";
type = "kernel";
arch = "arm64";
os = "linux";
compression = "none";
load = <0x4080000>;
entry = <0x4080000>;
kernel_blob: blob-ext {
filename = "Image";
};
};
fdt {
description = "Linux DTB";
type = "flat_dt";
arch = "arm64";
compression = "none";
kernel_fdt_blob: blob-ext {
filename = "linux.dtb";
};
};
};
configurations {
default = "conf";
conf {
description = "Intel SoC64 FPGA";
kernel = "kernel";
fdt = "fdt";
};
};
};
};
};
#endif

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* U-Boot additions
*
* Copyright (C) 2020 Intel Corporation <www.intel.com>
*/
#include "socfpga_soc64_fit-u-boot.dtsi"

View File

@ -2,9 +2,11 @@
/*
* U-Boot additions
*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
* Copyright (C) 2019-2020 Intel Corporation <www.intel.com>
*/
#include "socfpga_stratix10-u-boot.dtsi"
/{
aliases {
spi0 = &qspi;

View File

@ -33,7 +33,7 @@ config TARGET_SOCFPGA_AGILEX
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
select ARMV8_SPIN_TABLE
select BINMAN if SPL_ATF
select CLK
select FPGA_INTEL_SDM_MAILBOX
select NCORE_CACHE
@ -79,7 +79,7 @@ config TARGET_SOCFPGA_STRATIX10
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
select ARMV8_SPIN_TABLE
select BINMAN if SPL_ATF
select FPGA_INTEL_SDM_MAILBOX
choice

View File

@ -29,6 +29,7 @@ endif
ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
obj-y += clock_manager_s10.o
obj-y += lowlevel_init_soc64.o
obj-y += mailbox_s10.o
obj-y += misc_s10.o
obj-y += mmu-arm64_s10.o
@ -41,6 +42,7 @@ endif
ifdef CONFIG_TARGET_SOCFPGA_AGILEX
obj-y += clock_manager_agilex.o
obj-y += lowlevel_init_soc64.o
obj-y += mailbox_s10.o
obj-y += misc_s10.o
obj-y += mmu-arm64_s10.o
@ -70,6 +72,9 @@ ifdef CONFIG_TARGET_SOCFPGA_AGILEX
obj-y += firewall.o
obj-y += spl_agilex.o
endif
else
obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
obj-$(CONFIG_SPL_ATF) += smc_api.o
endif
ifdef CONFIG_TARGET_SOCFPGA_GEN5

View File

@ -13,7 +13,7 @@
#include <asm/arch/clock_manager.h>
#include <asm/arch/misc.h>
#include <asm/io.h>
#include <log.h>
#include <usb.h>
#include <usb/dwc2_udc.h>
@ -87,3 +87,13 @@ int g_dnl_board_usb_cable_connected(void)
return 1;
}
#endif
#ifdef CONFIG_SPL_BUILD
__weak int board_fit_config_name_match(const char *name)
{
/* Just empty function now - can't decide what to choose */
debug("%s: %s\n", __func__, name);
return 0;
}
#endif

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2020 Intel Corporation <www.intel.com>
*
*/
#ifndef _SECURE_REG_HELPER_H_
#define _SECURE_REG_HELPER_H_
#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1
#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2
#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3
#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4
int socfpga_secure_reg_read32(u32 id, u32 *val);
int socfpga_secure_reg_write32(u32 id, u32 val);
int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val);
#endif /* _SECURE_REG_HELPER_H_ */

View File

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Intel Corporation
*/
#ifndef _SMC_API_H_
#define _SMC_API_H_
int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len);
int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len,
u32 *resp_buf);
#endif /* _SMC_API_H_ */

View File

@ -0,0 +1,76 @@
/*
* Copyright (C) 2020 Intel Corporation. All rights reserved
*
* SPDX-License-Identifier: GPL-2.0
*/
#include <asm-offsets.h>
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
wait_for_atf:
ldr x4, =CPU_RELEASE_ADDR
ldr x5, [x4]
cbz x5, slave_wait_atf
br x5
slave_wait_atf:
branch_if_slave x0, wait_for_atf
#else
branch_if_slave x0, 1f
#endif
ldr x0, =GICD_BASE
bl gic_init_secure
1:
#if defined(CONFIG_GICV3)
ldr x0, =GICR_BASE
bl gic_init_secure_percpu
#elif defined(CONFIG_GICV2)
ldr x0, =GICD_BASE
ldr x1, =GICC_BASE
bl gic_init_secure_percpu
#endif
#endif
#ifdef CONFIG_ARMV8_MULTIENTRY
branch_if_master x0, x1, 2f
/*
* Slave should wait for master clearing spin table.
* This sync prevent slaves observing incorrect
* value of spin table and jumping to wrong place.
*/
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#ifdef CONFIG_GICV2
ldr x0, =GICC_BASE
#endif
bl gic_wait_for_interrupt
#endif
/*
* All slaves will enter EL2 and optionally EL1.
*/
adr x4, lowlevel_in_el2
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el2
lowlevel_in_el2:
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
adr x4, lowlevel_in_el1
ldr x5, =ES_TO_AARCH64
bl armv8_switch_to_el1
lowlevel_in_el1:
#endif
#endif /* CONFIG_ARMV8_MULTIENTRY */
2:
mov lr, x29 /* Restore LR */
ret
ENDPROC(lowlevel_init)

View File

@ -11,6 +11,7 @@
#include <asm/arch/mailbox_s10.h>
#include <asm/arch/system_manager.h>
#include <asm/secure.h>
#include <asm/system.h>
DECLARE_GLOBAL_DATA_PTR;
@ -398,6 +399,9 @@ error:
int mbox_reset_cold(void)
{
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
psci_system_reset();
#else
int ret;
ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_REBOOT_HPS, MBOX_CMD_DIRECT,
@ -406,6 +410,7 @@ int mbox_reset_cold(void)
/* mailbox sent failure, wait for watchdog to kick in */
hang();
}
#endif
return 0;
}

View File

@ -5,11 +5,14 @@
*/
#include <common.h>
#include <hang.h>
#include <asm/io.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/smc_api.h>
#include <asm/arch/system_manager.h>
#include <dt-bindings/reset/altr,rst-mgr-s10.h>
#include <linux/iopoll.h>
#include <linux/intel-smc.h>
DECLARE_GLOBAL_DATA_PTR;
@ -55,6 +58,15 @@ void socfpga_per_reset_all(void)
void socfpga_bridges_reset(int enable)
{
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
u64 arg = enable;
int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0);
if (ret) {
printf("SMC call failed with error %d in %s.\n", ret, __func__);
return;
}
#else
u32 reg;
if (enable) {
@ -101,6 +113,7 @@ void socfpga_bridges_reset(int enable)
/* Disable NOC timeout */
writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT);
}
#endif
}
/*

View File

@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2020 Intel Corporation <www.intel.com>
*
*/
#include <common.h>
#include <hang.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/arch/misc.h>
#include <asm/arch/secure_reg_helper.h>
#include <asm/arch/smc_api.h>
#include <asm/arch/system_manager.h>
#include <linux/errno.h>
#include <linux/intel-smc.h>
int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr)
{
switch (id) {
case SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC:
*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_SDMMC;
break;
case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC0;
break;
case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1:
*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC1;
break;
case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2:
*reg_addr = socfpga_get_sysmgr_addr() + SYSMGR_SOC64_EMAC2;
break;
default:
return -EADDRNOTAVAIL;
}
return 0;
}
int socfpga_secure_reg_read32(u32 id, u32 *val)
{
int ret;
u64 ret_arg;
u64 args[1];
phys_addr_t reg_addr;
ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
if (ret)
return ret;
args[0] = (u64)reg_addr;
ret = invoke_smc(INTEL_SIP_SMC_REG_READ, args, 1, &ret_arg, 1);
if (ret)
return ret;
*val = (u32)ret_arg;
return 0;
}
int socfpga_secure_reg_write32(u32 id, u32 val)
{
int ret;
u64 args[2];
phys_addr_t reg_addr;
ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
if (ret)
return ret;
args[0] = (u64)reg_addr;
args[1] = val;
return invoke_smc(INTEL_SIP_SMC_REG_WRITE, args, 2, NULL, 0);
}
int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val)
{
int ret;
u64 args[3];
phys_addr_t reg_addr;
ret = socfpga_secure_convert_reg_id_to_addr(id, &reg_addr);
if (ret)
return ret;
args[0] = (u64)reg_addr;
args[1] = mask;
args[2] = val;
return invoke_smc(INTEL_SIP_SMC_REG_UPDATE, args, 3, NULL, 0);
}

View File

@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Intel Corporation <www.intel.com>
*
*/
#include <common.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <linux/intel-smc.h>
int invoke_smc(u32 func_id, u64 *args, int arg_len, u64 *ret_arg, int ret_len)
{
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
regs.regs[0] = func_id;
if (args)
memcpy(&regs.regs[1], args, arg_len * sizeof(*args));
smc_call(&regs);
if (ret_arg)
memcpy(ret_arg, &regs.regs[1], ret_len * sizeof(*ret_arg));
return regs.regs[0];
}
int smc_send_mailbox(u32 cmd, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len,
u32 *resp_buf)
{
int ret;
u64 args[6];
u64 resp[3];
args[0] = cmd;
args[1] = (u64)arg;
args[2] = len;
args[3] = urgent;
args[4] = (u64)resp_buf;
if (resp_buf_len)
args[5] = *resp_buf_len;
else
args[5] = 0;
ret = invoke_smc(INTEL_SIP_SMC_MBOX_SEND_CMD, args, ARRAY_SIZE(args),
resp, ARRAY_SIZE(resp));
if (ret == INTEL_SIP_SMC_STATUS_OK && resp_buf && resp_buf_len) {
if (!resp[0])
*resp_buf_len = resp[1];
}
return (int)resp[0];
}

View File

@ -12,6 +12,7 @@
const struct cm_config * const cm_get_default_config(void)
{
#ifdef CONFIG_SPL_BUILD
struct cm_config *cm_handoff_cfg = (struct cm_config *)
(S10_HANDOFF_CLOCK + S10_HANDOFF_OFFSET_DATA);
u32 *conversion = (u32 *)cm_handoff_cfg;
@ -26,7 +27,7 @@ const struct cm_config * const cm_get_default_config(void)
} else if (handoff_clk == S10_HANDOFF_MAGIC_CLOCK) {
return cm_handoff_cfg;
}
#endif
return NULL;
}

View File

@ -4,4 +4,5 @@ M: Dinh Nguyen <dinh.nguyen@intel.com>
S: Maintained
F: board/altera/stratix10-socdk/
F: include/configs/socfpga_stratix10_socdk.h
F: configs/socfpga_stratix10_atf_defconfig
F: configs/socfpga_stratix10_defconfig

View File

@ -4,4 +4,5 @@ M: Chee Hong Ang <chee.hong.ang@intel.com>
S: Maintained
F: board/intel/agilex-socdk/
F: include/configs/socfpga_agilex_socdk.h
F: configs/socfpga_agilex_atf_defconfig
F: configs/socfpga_agilex_defconfig

View File

@ -0,0 +1,72 @@
CONFIG_ARM=y
CONFIG_ARM_SMCCC=y
CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
CONFIG_ARCH_SOCFPGA=y
CONFIG_SYS_TEXT_BASE=0x200000
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x200
CONFIG_DM_GPIO=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
CONFIG_IDENT_STRING="socfpga_agilex"
CONFIG_SPL_FS_FAT=y
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="earlycon"
CONFIG_SPL_CACHE=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000
CONFIG_SPL_ATF=y
CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # "
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_ALTERA_SDRAM=y
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MTD=y
CONFIG_SF_DEFAULT_MODE=0x2003
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_DM_RESET=y
CONFIG_SPI=y
CONFIG_CADENCE_QSPI=y
CONFIG_DESIGNWARE_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_DESIGNWARE_WATCHDOG=y
CONFIG_WDT=y
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_PANIC_HANG=y

View File

@ -0,0 +1,74 @@
CONFIG_ARM=y
CONFIG_ARM_SMCCC=y
CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
CONFIG_ARCH_SOCFPGA=y
CONFIG_SYS_TEXT_BASE=0x200000
CONFIG_SYS_MALLOC_F_LEN=0x2000
CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x200
CONFIG_DM_GPIO=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y
CONFIG_IDENT_STRING="socfpga_stratix10"
CONFIG_SPL_FS_FAT=y
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
# CONFIG_USE_SPL_FIT_GENERATOR is not set
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="earlycon"
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000
CONFIG_SPL_ATF=y
CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SOCFPGA_STRATIX10 # "
CONFIG_CMD_MEMTEST=y
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_stratix10_socdk"
CONFIG_ENV_IS_IN_MMC=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_ALTERA_SDRAM=y
CONFIG_FPGA_INTEL_PR=y
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MTD=y
CONFIG_SF_DEFAULT_MODE=0x2003
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_DM_RESET=y
CONFIG_SPI=y
CONFIG_CADENCE_QSPI=y
CONFIG_DESIGNWARE_SPI=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_DESIGNWARE_WATCHDOG=y
CONFIG_WDT=y
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_PANIC_HANG=y

View File

@ -8,11 +8,149 @@
#include <log.h>
#include <watchdog.h>
#include <asm/arch/mailbox_s10.h>
#include <asm/arch/smc_api.h>
#include <linux/delay.h>
#include <linux/intel-smc.h>
#define RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS 60000
#define RECONFIG_STATUS_INTERVAL_DELAY_US 1000000
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
#define BITSTREAM_CHUNK_SIZE 0xFFFF0
#define RECONFIG_STATUS_POLL_RETRY_MAX 100
/*
* Polling the FPGA configuration status.
* Return 0 for success, non-zero for error.
*/
static int reconfig_status_polling_resp(void)
{
int ret;
unsigned long start = get_timer(0);
while (1) {
ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_ISDONE, NULL, 0,
NULL, 0);
if (!ret)
return 0; /* configuration success */
if (ret != INTEL_SIP_SMC_STATUS_BUSY)
return ret;
if (get_timer(start) > RECONFIG_STATUS_POLL_RESP_TIMEOUT_MS)
return -ETIMEDOUT; /* time out */
puts(".");
udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
WATCHDOG_RESET();
}
return -ETIMEDOUT;
}
static int send_bitstream(const void *rbf_data, size_t rbf_size)
{
int i;
u64 res_buf[3];
u64 args[2];
u32 xfer_count = 0;
int ret, wr_ret = 0, retry = 0;
size_t buf_size = (rbf_size > BITSTREAM_CHUNK_SIZE) ?
BITSTREAM_CHUNK_SIZE : rbf_size;
while (rbf_size || xfer_count) {
if (!wr_ret && rbf_size) {
args[0] = (u64)rbf_data;
args[1] = buf_size;
wr_ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_WRITE,
args, 2, NULL, 0);
debug("wr_ret = %d, rbf_data = %p, buf_size = %08lx\n",
wr_ret, rbf_data, buf_size);
if (wr_ret)
continue;
rbf_size -= buf_size;
rbf_data += buf_size;
if (buf_size >= rbf_size)
buf_size = rbf_size;
xfer_count++;
puts(".");
} else {
ret = invoke_smc(
INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE,
NULL, 0, res_buf, ARRAY_SIZE(res_buf));
if (!ret) {
for (i = 0; i < ARRAY_SIZE(res_buf); i++) {
if (!res_buf[i])
break;
xfer_count--;
wr_ret = 0;
retry = 0;
}
} else if (ret !=
INTEL_SIP_SMC_STATUS_BUSY)
return ret;
else if (!xfer_count)
return INTEL_SIP_SMC_STATUS_ERROR;
if (++retry >= RECONFIG_STATUS_POLL_RETRY_MAX)
return -ETIMEDOUT;
udelay(20000);
}
WATCHDOG_RESET();
}
return 0;
}
/*
* This is the interface used by FPGA driver.
* Return 0 for success, non-zero for error.
*/
int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
{
int ret;
u64 arg = 1;
debug("Invoking FPGA_CONFIG_START...\n");
ret = invoke_smc(INTEL_SIP_SMC_FPGA_CONFIG_START, &arg, 1, NULL, 0);
if (ret) {
puts("Failure in RECONFIG mailbox command!\n");
return ret;
}
ret = send_bitstream(rbf_data, rbf_size);
if (ret) {
puts("Error sending bitstream!\n");
return ret;
}
/* Make sure we don't send MBOX_RECONFIG_STATUS too fast */
udelay(RECONFIG_STATUS_INTERVAL_DELAY_US);
debug("Polling with MBOX_RECONFIG_STATUS...\n");
ret = reconfig_status_polling_resp();
if (ret) {
puts("FPGA reconfiguration failed!");
return ret;
}
puts("FPGA reconfiguration OK!\n");
return ret;
}
#else
static const struct mbox_cfgstat_state {
int err_no;
const char *error_name;
@ -286,3 +424,4 @@ int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size)
return ret;
}
#endif

View File

@ -40,7 +40,7 @@ struct ca_dwmmc_priv_data {
u8 ds;
};
static void ca_dwmci_clksel(struct dwmci_host *host)
static int ca_dwmci_clksel(struct dwmci_host *host)
{
struct ca_dwmmc_priv_data *priv = host->priv;
u32 val = readl(priv->sd_dll_reg);
@ -52,6 +52,8 @@ static void ca_dwmci_clksel(struct dwmci_host *host)
val |= SD_CLK_SEL_100MHZ;
writel(val, priv->sd_dll_reg);
return 0;
}
static void ca_dwmci_board_init(struct dwmci_host *host)

View File

@ -496,8 +496,13 @@ static int dwmci_set_ios(struct mmc *mmc)
dwmci_writel(host, DWMCI_UHS_REG, regs);
if (host->clksel)
host->clksel(host);
if (host->clksel) {
int ret;
ret = host->clksel(host);
if (ret)
return ret;
}
#if CONFIG_IS_ENABLED(DM_REGULATOR)
if (mmc->vqmmc_supply) {

View File

@ -44,7 +44,7 @@ struct dwmci_exynos_priv_data {
* Function used as callback function to initialise the
* CLKSEL register for every mmc channel.
*/
static void exynos_dwmci_clksel(struct dwmci_host *host)
static int exynos_dwmci_clksel(struct dwmci_host *host)
{
#ifdef CONFIG_DM_MMC
struct dwmci_exynos_priv_data *priv =
@ -53,6 +53,8 @@ static void exynos_dwmci_clksel(struct dwmci_host *host)
struct dwmci_exynos_priv_data *priv = host->priv;
#endif
dwmci_writel(host, DWMCI_CLKSEL, priv->sdr_timing);
return 0;
}
unsigned int exynos_dwmci_get_clk(struct dwmci_host *host, uint freq)

View File

@ -51,7 +51,7 @@ struct nexell_dwmmc_priv {
struct clk *clk_get(const char *id);
static void nx_dw_mmc_clksel(struct dwmci_host *host)
static int nx_dw_mmc_clksel(struct dwmci_host *host)
{
/* host->priv is pointer to "struct udevice" */
struct nexell_dwmmc_priv *priv = dev_get_priv(host->priv);
@ -65,6 +65,8 @@ static void nx_dw_mmc_clksel(struct dwmci_host *host)
DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(3);
dwmci_writel(host, DWMCI_CLKSEL, val);
return 0;
}
static void nx_dw_mmc_reset(int ch)

View File

@ -6,6 +6,7 @@
#include <common.h>
#include <log.h>
#include <asm/arch/clock_manager.h>
#include <asm/arch/secure_reg_helper.h>
#include <asm/arch/system_manager.h>
#include <clk.h>
#include <dm.h>
@ -13,6 +14,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <dm/device_compat.h>
#include <linux/intel-smc.h>
#include <linux/libfdt.h>
#include <linux/err.h>
#include <malloc.h>
@ -46,7 +48,7 @@ static void socfpga_dwmci_reset(struct udevice *dev)
reset_deassert_bulk(&reset_bulk);
}
static void socfpga_dwmci_clksel(struct dwmci_host *host)
static int socfpga_dwmci_clksel(struct dwmci_host *host)
{
struct dwmci_socfpga_priv_data *priv = host->priv;
u32 sdmmc_mask = ((priv->smplsel & 0x7) << SYSMGR_SDMMC_SMPLSEL_SHIFT) |
@ -58,14 +60,28 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
debug("%s: drvsel %d smplsel %d\n", __func__,
priv->drvsel, priv->smplsel);
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
int ret;
ret = socfpga_secure_reg_write32(SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC,
sdmmc_mask);
if (ret) {
printf("DWMMC: Failed to set clksel via SMC call");
return ret;
}
#else
writel(sdmmc_mask, socfpga_get_sysmgr_addr() + SYSMGR_SDMMC);
debug("%s: SYSMGR_SDMMCGRP_CTRL_REG = 0x%x\n", __func__,
readl(socfpga_get_sysmgr_addr() + SYSMGR_SDMMC));
#endif
/* Enable SDMMC clock */
setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_PERPLL_EN,
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK);
return 0;
}
static int socfpga_dwmmc_get_clk_rate(struct udevice *dev)

View File

@ -6,6 +6,8 @@
*/
#include <common.h>
#include <asm/arch/secure_reg_helper.h>
#include <asm/arch/system_manager.h>
#include <asm/io.h>
#include <dm.h>
#include <clk.h>
@ -17,8 +19,6 @@
#include <dm/device_compat.h>
#include <linux/err.h>
#include <asm/arch/system_manager.h>
struct dwmac_socfpga_plat {
struct dw_eth_pdata dw_eth_pdata;
void *phy_intf;
@ -64,6 +64,32 @@ static int dwmac_socfpga_of_to_plat(struct udevice *dev)
return designware_eth_of_to_plat(dev);
}
static int dwmac_socfpga_do_setphy(struct udevice *dev, u32 modereg)
{
struct dwmac_socfpga_plat *pdata = dev_get_plat(dev);
u32 modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF)
u32 index = ((u64)pdata->phy_intf - socfpga_get_sysmgr_addr() -
SYSMGR_SOC64_EMAC0) >> 2;
u32 id = SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 + index;
int ret = socfpga_secure_reg_update32(id,
modemask,
modereg << pdata->reg_shift);
if (ret) {
dev_err(dev, "Failed to set PHY register via SMC call\n");
return ret;
}
#else
clrsetbits_le32(pdata->phy_intf, modemask,
modereg << pdata->reg_shift);
#endif
return 0;
}
static int dwmac_socfpga_probe(struct udevice *dev)
{
struct dwmac_socfpga_plat *pdata = dev_get_plat(dev);
@ -71,7 +97,6 @@ static int dwmac_socfpga_probe(struct udevice *dev)
struct reset_ctl_bulk reset_bulk;
int ret;
u32 modereg;
u32 modemask;
switch (edata->phy_interface) {
case PHY_INTERFACE_MODE_MII:
@ -97,9 +122,9 @@ static int dwmac_socfpga_probe(struct udevice *dev)
reset_assert_bulk(&reset_bulk);
modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
clrsetbits_le32(pdata->phy_intf, modemask,
modereg << pdata->reg_shift);
ret = dwmac_socfpga_do_setphy(dev, modereg);
if (ret)
return ret;
reset_release_bulk(&reset_bulk);

View File

@ -22,8 +22,10 @@
#if defined(CONFIG_TARGET_SOCFPGA_GEN5)
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000
#define CONFIG_SYS_INIT_RAM_SIZE SOCFPGA_PHYS_OCRAM_SIZE
#define CONFIG_SPL_PAD_TO 0x10000
#elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10)
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000
#define CONFIG_SPL_PAD_TO 0x40000
/* SPL memory allocation configuration, this is for FAT implementation */
#ifndef CONFIG_SYS_SPL_MALLOC_SIZE
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000

View File

@ -40,9 +40,14 @@
*/
#define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000
#define CONFIG_SYS_INIT_RAM_SIZE 0x40000
#ifdef CONFIG_SPL_BUILD
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR \
+ CONFIG_SYS_INIT_RAM_SIZE \
- S10_HANDOFF_SIZE)
#else
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE \
+ 0x100000)
#endif
#define CONFIG_SYS_INIT_SP_OFFSET (CONFIG_SYS_INIT_SP_ADDR)
#define CONFIG_SYS_MALLOC_LEN (5 * 1024 * 1024)
@ -78,12 +83,20 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
* CONFIG_BOOTARGS goes into the environment value "bootargs".
* Do note the value will override also the chosen node in FDT blob.
*/
#ifdef CONFIG_FIT
#define CONFIG_BOOTFILE "kernel.itb"
#define CONFIG_BOOTCOMMAND "run fatscript; run mmcfitload;run linux_qspi_enable;" \
"run mmcfitboot"
#else
#define CONFIG_BOOTFILE "Image"
#define CONFIG_BOOTCOMMAND "run fatscript; run mmcload;run linux_qspi_enable;" \
"run mmcboot"
#endif
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=" __stringify(CONFIG_SYS_LOAD_ADDR) "\0" \
"bootfile=Image\0" \
"bootfile=" CONFIG_BOOTFILE "\0" \
"fdt_addr=8000000\0" \
"fdtimage=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
"mmcroot=/dev/mmcblk0p2\0" \
@ -93,6 +106,11 @@ unsigned int cm_get_qspi_controller_clk_hz(void);
"mmcload=mmc rescan;" \
"load mmc 0:1 ${loadaddr} ${bootfile};" \
"load mmc 0:1 ${fdt_addr} ${fdtimage}\0" \
"mmcfitboot=setenv bootargs " CONFIG_BOOTARGS \
" root=${mmcroot} rw rootwait;" \
"bootm ${loadaddr}\0" \
"mmcfitload=mmc rescan;" \
"load mmc 0:1 ${loadaddr} ${bootfile}\0" \
"linux_qspi_enable=if sf probe; then " \
"echo Enabling QSPI at Linux DTB...;" \
"fdt addr ${fdt_addr}; fdt resize;" \
@ -193,6 +211,10 @@ unsigned int cm_get_l4_sys_free_clk_hz(void);
- CONFIG_SYS_SPL_MALLOC_SIZE)
/* SPL SDMMC boot support */
#ifdef CONFIG_SPL_LOAD_FIT
#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.itb"
#else
#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.img"
#endif
#endif /* __CONFIG_SOCFPGA_SOC64_COMMON_H__ */

View File

@ -174,7 +174,7 @@ struct dwmci_host {
struct mmc *mmc;
void *priv;
void (*clksel)(struct dwmci_host *host);
int (*clksel)(struct dwmci_host *host);
void (*board_init)(struct dwmci_host *host);
/**

573
include/linux/intel-smc.h Normal file
View File

@ -0,0 +1,573 @@
/* 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 u-boot 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
* values. 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:
* SMC call 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_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_STATUS_ERROR:
* There is error during the SMC call 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_STATUS_BUSY 0x1
#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
#define INTEL_SIP_SMC_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_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_STATUS_BUSY,
* INTEL_SIP_SMC_STATUS_REJECTED or INTEL_SIP_SMC_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_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_STATUS_BUSY or
* INTEL_SIP_SMC_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_STATUS_BUSY or
* INTEL_SIP_SMC_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_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_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)
/*
* Request INTEL_SIP_SMC_ECC_DBE
*
* Sync call used by service driver at EL1 alert EL3 that a Double Bit
* ECC error has occurred.
*
* Call register usage:
* a0 INTEL_SIP_SMC_ECC_DBE
* a1 SysManager Double Bit Error value
* a2-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_ECC_DBE 13
#define INTEL_SIP_SMC_ECC_DBE \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_ECC_DBE)
/*
* Request INTEL_SIP_SMC_RSU_NOTIFY
*
* Sync call used by service driver at EL1 to report HPS software execution stage
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_NOTIFY
* a1 32bit HPS software execution stage
* a2-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
*/
#define INTEL_SIP_SMC_FUNCID_RSU_NOTIFY 14
#define INTEL_SIP_SMC_RSU_NOTIFY \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_NOTIFY)
/*
* Request INTEL_SIP_SMC_RSU_RETRY_COUNTER
*
* Sync call used by service driver at EL1 to query the RSU retry counter
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_RETRY_COUNTER
* a1-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_RSU_ERROR.
* a1 retry counter
*/
#define INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER 15
#define INTEL_SIP_SMC_RSU_RETRY_COUNTER \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER)
/*
* Request INTEL_SIP_SMC_RSU_DCMF_VERSION
*
* Sync call used by service driver at EL1 to query DCMF version
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_DCMF_VERSION
* a1-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
* a1 dcmf1 version | dcmf0 version
* a2 dcmf3 version | dcmf2 version
*
* Or
*
* a0 INTEL_SIP_SMC_RSU_ERROR
*/
#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION 16
#define INTEL_SIP_SMC_RSU_DCMF_VERSION \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION)
/*
* Request INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
*
* Sync call used by SSBL (EL2) to copy DCMF version to ATF memory
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
* a1 dcmf1 version | dcmf0 version
* a2 dcmf3 version | dcmf2 version
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION 17
#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION)
/*
* Request INTEL_SIP_SMC_RSU_MAX_RETRY
*
* Sync call used by service driver at EL1 to query max_retry parameter
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_MAX_RETRY
* a1-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
* a1 max_retry
*
* Or
*
* a0 INTEL_SIP_SMC_RSU_ERROR
*/
#define INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY 18
#define INTEL_SIP_SMC_RSU_MAX_RETRY \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY)
/*
* Request INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
*
* Sync call used by SSBL (EL2) to copy RSU 'max retry' to ATF memory
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
* a1 max retry
* a2-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY 19
#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY)
/*
* Request INTEL_SIP_SMC_RSU_DCMF_STATUS
*
* Sync call used by service driver at EL1 to query DCMF status
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_DCMF_STATUS
* a1-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
* a1 dcmf3 status | dcmf2 status | dcmf1 status | dcmf0 status
*
* Or
*
* a0 INTEL_SIP_SMC_RSU_ERROR
*/
#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS 20
#define INTEL_SIP_SMC_RSU_DCMF_STATUS \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS)
/*
* Request INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
*
* Sync call used by SSBL (EL2) to copy RSU 'dcmf status' to ATF memory
*
* Call register usage:
* a0 INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
* a1 dcmf status
* a2-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS 21
#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS)
/*
* Request INTEL_SIP_SMC_HPS_SET_BRIDGES
*
* Enable/disable the SoC FPGA bridges
*
* Call register usage:
* a0 INTEL_SIP_SMC_HPS_SET_BRIDGES
* a1 Set bridges status:
* 0 - Disable
* 1 - Enable
* a2-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES 50
#define INTEL_SIP_SMC_HPS_SET_BRIDGES \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES)
/*
* Request INTEL_SIP_SMC_MBOX_SEND_CMD
*
* Send mailbox command to SDM
*
* Call register usage:
* a0 INTEL_SIP_SMC_MBOX_SEND_CMD
* a1 Mailbox command
* a2 64bit physical address pointer to command's arguments
* a3 Length of the argument
* a4 Urgent command:
* 0 - Disable
* 1 - Enable
* a5 64bit physical address pointer to a buffer for receiving responses
* a6 Length of the buffer
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
* a1 Status of mailbox response
* a2 Received length in the buffer
*/
#define INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD 60
#define INTEL_SIP_SMC_MBOX_SEND_CMD \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD)
/*
* Request INTEL_SIP_SMC_HPS_SET_PHYINTF
*
* Select EMACx PHY interface
*
* Call register usage:
* a0 INTEL_SIP_SMC_HPS_SET_PHYINTF
* a1 EMAC number:
* 0 - EMAC0
* 1 - EMAC1
* 2 - EMAC2
* a2 Type of PHY interface:
* 0 - GMII_MII
* 1 - RGMII
* 2 - RMII
* 3 - RESET
* a3-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
*/
#define INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF 61
#define INTEL_SIP_SMC_HPS_SET_PHYINTF \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_PHYINTF)
/*
* Request INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK
*
* Select which phase shift of the clocks (drvsel & smplsel) for SDMMC
*
* Call register usage:
* a0 INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK
* a1 Select which phase shift of the clock for cclk_in_drv (drvsel):
* 0 - 0 degree
* 1 - 45 degrees
* 2 - 90 degrees
* 3 - 135 degrees
* 4 - 180 degrees
* 5 - 225 degrees
* 6 - 270 degrees
* 7 - 315 degrees
* a2 Select which phase shift of the clock for cclk_in_sample (smplsel):
* (Same as above)
* a3-7 not used
*
* Return status
* a0 INTEL_SIP_SMC_STATUS_OK
*/
#define INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK 62
#define INTEL_SIP_SMC_HPS_SET_SDMMC_CCLK \
INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_SDMMC_CCLK)
#endif

View File

@ -61,6 +61,7 @@
#define HEADER_OFFSET 0x40
#define VALIDATION_WORD 0x31305341
#define IMAGE_ALIGN 16
/* Minimum and default entry point offset */
#define ENTRY_POINT_OFFSET 0x14
@ -97,7 +98,7 @@ static unsigned int sfp_hdr_size(uint8_t ver)
return 0;
}
static unsigned int sfp_pad_size(uint8_t ver)
static unsigned int sfp_max_size(uint8_t ver)
{
if (ver == 0)
return sizeof(buffer_v0);
@ -106,6 +107,12 @@ static unsigned int sfp_pad_size(uint8_t ver)
return 0;
}
static unsigned int sfp_aligned_len(uint32_t size)
{
/* Add 4 bytes for CRC and align to 16 bytes */
return ALIGN(size + sizeof(uint32_t), IMAGE_ALIGN);
}
/*
* The header checksum is just a very simple checksum over
* the header area.
@ -208,22 +215,24 @@ static int sfp_sign_buffer(uint8_t *buf, uint8_t ver, uint8_t flags,
struct image_tool_params *params)
{
uint32_t calc_crc;
uint32_t crc_off;
/* Align the length up */
len = ALIGN(len, 4);
len = sfp_aligned_len(len);
/* Build header, adding 4 bytes to length to hold the CRC32. */
sfp_build_header(buf + HEADER_OFFSET, ver, flags, len + 4, params);
/* Build header */
sfp_build_header(buf + HEADER_OFFSET, ver, flags, len, params);
/* Calculate and apply the CRC */
calc_crc = ~pbl_crc32(0, (char *)buf, len);
crc_off = len - sizeof(uint32_t); /* at last 4 bytes of image */
calc_crc = ~pbl_crc32(0, (char *)buf, crc_off);
*((uint32_t *)(buf + len)) = cpu_to_le32(calc_crc);
*((uint32_t *)(buf + crc_off)) = cpu_to_le32(calc_crc);
if (!pad_64k)
return len + 4;
return sfp_pad_size(ver);
return sfp_max_size(ver);
}
/* Verify that the buffer looks sane */
@ -240,7 +249,7 @@ static int sfp_verify_buffer(const uint8_t *buf)
return -1;
}
if (len < HEADER_OFFSET || len > sfp_pad_size(ver)) {
if (len < HEADER_OFFSET || len > sfp_max_size(ver)) {
debug("Invalid header length (%i)\n", len);
return -1;
}
@ -274,12 +283,51 @@ static int socfpgaimage_verify_header(unsigned char *ptr, int image_size,
return sfp_verify_buffer(ptr);
}
static void socfpgaimage_print_header_v0(struct socfpga_header_v0 *header)
{
printf("Image Type\t: Cyclone V / Arria V SoC Image\n");
printf("Validation word\t: 0x%08x\n",
le32_to_cpu(header->validation));
printf("Version\t\t: 0x%08x\n", header->version);
printf("Flags\t\t: 0x%08x\n", header->flags);
printf("Program length\t: 0x%08x\n",
le16_to_cpu(header->length_u32));
printf("Header checksum\t: 0x%08x\n",
le16_to_cpu(header->checksum));
}
static void socfpgaimage_print_header_v1(struct socfpga_header_v1 *header)
{
printf("Image Type\t: Arria 10 SoC Image\n");
printf("Validation word\t: 0x%08x\n",
le32_to_cpu(header->validation));
printf("Version\t\t: 0x%08x\n", header->version);
printf("Flags\t\t: 0x%08x\n", header->flags);
printf("Header length\t: 0x%08x\n",
le16_to_cpu(header->header_u8));
printf("Program length\t: 0x%08x\n",
le32_to_cpu(header->length_u8));
printf("Program entry\t: 0x%08x\n",
le32_to_cpu(header->entry_offset));
printf("Header checksum\t: 0x%08x\n",
le16_to_cpu(header->checksum));
}
static void socfpgaimage_print_header(const void *ptr)
{
if (sfp_verify_buffer(ptr) == 0)
printf("Looks like a sane SOCFPGA preloader\n");
else
const void *header = ptr + HEADER_OFFSET;
struct socfpga_header_v0 *header_v0;
if (sfp_verify_buffer(ptr) == 0) {
header_v0 = (struct socfpga_header_v0 *)header;
if (header_v0->version == 0)
socfpgaimage_print_header_v0(header_v0);
else
socfpgaimage_print_header_v1((struct socfpga_header_v1 *)header);
} else {
printf("Not a sane SOCFPGA preloader\n");
}
}
static int socfpgaimage_check_params_v0(struct image_tool_params *params)
@ -328,19 +376,25 @@ static int socfpgaimage_check_image_types_v1(uint8_t type)
* To work in with the mkimage framework, we do some ugly stuff...
*
* First, socfpgaimage_vrec_header() is called.
* We prepend a fake header big enough to make the file sfp_pad_size().
* We prepend a fake header big enough to include crc32 and align image to 16
* bytes.
* This gives us enough space to do what we want later.
*
* Next, socfpgaimage_set_header() is called.
* We fix up the buffer by moving the image to the start of the buffer.
* We now have some room to do what we need (add CRC and padding).
* We now have some room to do what we need (add CRC).
*/
static int data_size;
static int sfp_fake_header_size(unsigned int size, uint8_t ver)
{
return sfp_pad_size(ver) - size;
unsigned int align_size;
align_size = sfp_aligned_len(size);
/* extra bytes needed */
return align_size - size;
}
static int sfp_vrec_header(struct image_tool_params *params,
@ -350,7 +404,7 @@ static int sfp_vrec_header(struct image_tool_params *params,
if (params->datafile &&
stat(params->datafile, &sbuf) == 0 &&
sbuf.st_size <= (sfp_pad_size(ver) - sizeof(uint32_t))) {
sbuf.st_size <= (sfp_max_size(ver) - sizeof(uint32_t))) {
data_size = sbuf.st_size;
tparams->header_size = sfp_fake_header_size(data_size, ver);
}
@ -378,7 +432,7 @@ static void sfp_set_header(void *ptr, unsigned char ver,
/*
* This function is called after vrec_header() has been called.
* At this stage we have the sfp_fake_header_size() dummy bytes
* followed by data_size image bytes. Total = sfp_pad_size().
* followed by data_size image bytes.
* We need to fix the buffer by moving the image bytes back to
* the beginning of the buffer, then actually do the signing stuff...
*/