
On 08/08/2017 11:12 AM, tien.fong.chee@intel.com wrote:
From: Tien Fong Chee tien.fong.chee@intel.com
Configuration flip-flop driver is mainly used for handling the FPGA program operation where the FPGA image loading from the flash into FPGA manager.
I don't understand what this driver is for , sorry.
Coding style issues are present (camel case, wrong comment style, use checkpatch).
If this is for some FPGA loading, can this functionality be scripted instead?
Signed-off-by: Tien Fong Chee tien.fong.chee@intel.com
arch/arm/mach-socfpga/cff.c | 582 +++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/include/mach/cff.h | 40 +++ include/configs/socfpga_arria10_socdk.h | 6 + 3 files changed, 628 insertions(+) create mode 100644 arch/arm/mach-socfpga/cff.c create mode 100644 arch/arm/mach-socfpga/include/mach/cff.h
diff --git a/arch/arm/mach-socfpga/cff.c b/arch/arm/mach-socfpga/cff.c new file mode 100644 index 0000000..ccee5e9 --- /dev/null +++ b/arch/arm/mach-socfpga/cff.c @@ -0,0 +1,582 @@ +/*
- COPYRIGHT (C) 2017 Intel Corporation <www.intel.com>
- SPDX-License-Identifier: GPL-2.0
- */
+#include <altera.h> +#include <common.h> +#include <asm/io.h> +#include <asm/arch/cff.h> +#include <asm/arch/fpga_manager.h> +#include <asm/arch/misc.h> +#include <asm/arch/system_manager.h> +#include <asm/arch/reset_manager.h> +#include <errno.h> +#include <fat.h> +#include <fs.h> +#include <fdtdec.h> +#include <malloc.h> +#include <mmc.h> +#include <spi_flash.h> +#include <spl.h> +#include <watchdog.h>
+#define RBF_UNENCRYPTED 0xa65c +#define RBF_ENCRYPTED 0xa65d +#define ARRIA10RBF_PERIPH 0x0001 +#define ARRIA10RBF_CORE 0x8001
+DECLARE_GLOBAL_DATA_PTR;
+static int flash_type = -1;
+struct mmc *mmc;
+/* Local functions */ +static int cff_flash_read(struct cff_flash_info *cff_flashinfo, u32 *buffer,
- u32 *buffer_sizebytes);
+static int cff_flash_preinit(struct cff_flash_info *cff_flashinfo,
- fpga_fs_info *fpga_fsinfo, u32 *buffer, u32 *buffer_sizebytes);
+#ifdef CONFIG_CMD_FPGA_LOADFS +static const char *get_cff_filename(const void *fdt, int *len, u32 core); +#else +static int get_cff_offset(const void *fdt, u32 core); +#endif
+static struct mmc *init_mmc_device(int dev, bool force_init) +{
- struct mmc *mmc;
- mmc = find_mmc_device(dev);
- if (!mmc) {
printf("no mmc device at slot %x\n", dev);
return NULL;
- }
- if (force_init)
mmc->has_init = 0;
- if (mmc_init(mmc))
return NULL;
- return mmc;
+}
+static int cff_flash_probe(struct cff_flash_info *cff_flashinfo) +{
- int dev = 0;
- if(BOOT_DEVICE_MMC1 == flash_type)
- {
mmc = init_mmc_device(dev, true);
if (!mmc)
return -ENOTBLK;
+#ifdef CONFIG_CMD_FPGA_LOADFS
/* we are looking at the FAT partition */
if (fat_register_device(mmc_get_blk_desc(mmc),
cff_flashinfo->sdmmc_flashinfo.dev_part)) {
printf("Failed to set filesystem to FAT.\n");
return -EPERM;
}
+#endif
- }
- return flash_type;
+}
+static int flash_read(struct cff_flash_info *cff_flashinfo,
- u32 size_read,
- u32 *buffer_ptr)
+{
- size_t ret = EEXIST;
+#ifdef CONFIG_CMD_FPGA_LOADFS
- loff_t actread;
+#endif
- if(BOOT_DEVICE_MMC1 == flash_type) {
+#ifdef CONFIG_CMD_FPGA_LOADFS
ret = fat_read_file(cff_flashinfo->sdmmc_flashinfo.filename,
buffer_ptr, cff_flashinfo->flash_offset,
size_read, &actread);
if (ret || actread != size_read) {
printf("Failed to read %s from FAT %d ",
cff_flashinfo->sdmmc_flashinfo.filename,
ret);
printf("!= %d.\n", size_read);
return -EPERM;
} else
ret = actread;
+#else
u32 blk = cff_flashinfo->flash_offset/mmc->read_bl_len;
u32 cnt = size_read / mmc->read_bl_len;
if (!cnt)
cnt = 1;
if((size_read % mmc->read_bl_len) &&
(size_read >= mmc->read_bl_len))
cnt++;
ret = blk_dread(mmc_get_blk_desc(mmc), blk, cnt,
buffer_ptr);
if (cnt != ret)
return -EPERM;
+#endif
- }
return ret;
+}
+#ifdef CONFIG_CMD_FPGA_LOADFS +const char *get_cff_filename(const void *fdt, int *len, u32 core) +{
- const char *cff_filename = NULL;
- const char *cell;
- int nodeoffset;
- nodeoffset = fdt_subnode_offset(fdt, 0, "chosen");
- if (nodeoffset >= 0) {
if (core)
cell = fdt_getprop(fdt,
nodeoffset,
"cffcore-file",
len);
else
cell = fdt_getprop(fdt, nodeoffset, "cff-file", len);
if (cell)
cff_filename = cell;
- }
- return cff_filename;
+} +#else +static int get_cff_offset(const void *fdt, u32 core) +{
- int nodeoffset = 0;
- nodeoffset = fdt_subnode_offset(fdt, 0, "chosen");
- if (nodeoffset >= 0) {
if (core)
return fdtdec_get_int(fdt,
nodeoffset,
"cffcore-offset",
-ESPIPE);
else
return fdtdec_get_int(fdt,
nodeoffset,
"cff-offset",
-ESPIPE);
- }
- return -ESPIPE;
+} +#endif
+int cff_from_sdmmc_env(u32 core) +{
- int rval = -ENOENT;
- fpga_fs_info fpga_fsinfo;
+#ifdef CONFIG_CMD_FPGA_LOADFS
- int len = 0;
- const char *cff = NULL;
+#else
- char addrToString[32] = {0};
- int sdmmc_rbf_rawaddr = -ENOENT;
+#endif
- flash_type = spl_boot_device();
- fpga_fsinfo.interface = "sdmmc";
+#ifdef CONFIG_CMD_FPGA_LOADFS
- cff = get_cff_filename(gd->fdt_blob, &len, core);
- /* FAT periph RBF file reading */
- if (cff && (len > 0)) {
mmc_initialize(gd->bd);
fpga_fsinfo.filename = (char *)cff;
fpga_fsinfo.dev_part = getenv("cff_devsel_partition");
if (NULL == fpga_fsinfo.dev_part) {
/* FAT partition */
fpga_fsinfo.dev_part = "1";
printf("No SD/MMC partition found in environment. ");
printf("Assuming partition 1.\n");
}
rval = cff_from_flash(&fpga_fsinfo);
- }
+#else
- sdmmc_rbf_rawaddr = get_cff_offset(gd->fdt_blob, core);
/* RAW periph RBF reading */
- if (sdmmc_rbf_rawaddr >= 0) {
sprintf(addrToString, "%x", sdmmc_rbf_rawaddr);
fpga_fsinfo.filename = addrToString;
rval = cff_from_flash(&fpga_fsinfo);
- }
+#endif
- return rval;
+}
+void get_rbf_image_info(struct rbf_info *rbf, u16 *buffer) +{
- /*
Magic ID starting at:
-> 1st dword in periph.rbf
-> 2nd dword in core.rbf
- */
- u32 word_reading_max = 2;
- u32 i;
- for(i = 0; i < word_reading_max; i++)
- {
if(RBF_UNENCRYPTED == *(buffer + i)) /* PERIPH RBF */
rbf->security = unencrypted;
else if (RBF_ENCRYPTED == *(buffer + i))
rbf->security = encrypted;
else if (RBF_UNENCRYPTED == *(buffer + i + 1)) /* CORE RBF */
rbf->security = unencrypted;
else if (RBF_ENCRYPTED == *(buffer + i + 1))
rbf->security = encrypted;
else {
rbf->security = invalid;
continue;
}
/* PERIPH RBF */
if (ARRIA10RBF_PERIPH == *(buffer + i + 1)) {
rbf->section = periph_section;
break;
}
else if (ARRIA10RBF_CORE == *(buffer + i + 1)) {
rbf->section = core_section;
break;
} /* CORE RBF */
else if (ARRIA10RBF_PERIPH == *(buffer + i + 2)) {
rbf->section = periph_section;
break;
}
else if (ARRIA10RBF_CORE == *(buffer + i + 2)) {
rbf->section = core_section;
break;
}
else {
rbf->section = unknown;
break;
}
- }
- return;
+}
+static int cff_flash_preinit(struct cff_flash_info *cff_flashinfo,
- fpga_fs_info *fpga_fsinfo, u32 *buffer, u32 *buffer_sizebytes)
+{
- u32 *bufferptr_after_header = NULL;
- u32 buffersize_after_header = 0;
- u32 rbf_header_data_size = 0;
- int ret = 0;
- /* To avoid from keeping re-read the contents */
- struct image_header *header = &(cff_flashinfo->header);
- size_t buffer_size = *buffer_sizebytes;
- u32 *buffer_ptr = (u32 *)*buffer;
+#ifdef CONFIG_CMD_FPGA_LOADFS
- cff_flashinfo->sdmmc_flashinfo.filename = fpga_fsinfo->filename;
- cff_flashinfo->flash_offset = 0;
+#else
- cff_flashinfo->flash_offset =
simple_strtoul(fpga_fsinfo->filename, NULL, 16);
+#endif
/* Load mkimage header into buffer */
- ret = flash_read(cff_flashinfo,
sizeof(struct image_header), buffer_ptr);
- if (0 >= ret) {
printf(" Failed to read mkimage header from flash.\n");
return -ENOENT;
- }
- WATCHDOG_RESET();
- memcpy(header, (u_char *)buffer_ptr, sizeof(*header));
- if (!image_check_magic(header)) {
printf("FPGA: Bad Magic Number.\n");
return -EBADF;
- }
- if (!image_check_hcrc(header)) {
printf("FPGA: Bad Header Checksum.\n");
return -EPERM;
- }
- /* Getting rbf data size */
- cff_flashinfo->remaining =
image_get_data_size(header);
- /* Calculate total size of both rbf data with mkimage header */
- rbf_header_data_size = cff_flashinfo->remaining +
sizeof(struct image_header);
- /* Loading to buffer chunk by chunk, normally for OCRAM buffer */
- if (rbf_header_data_size > buffer_size) {
/* Calculate size of rbf data in the buffer */
buffersize_after_header =
buffer_size - sizeof(struct image_header);
cff_flashinfo->remaining -= buffersize_after_header;
- } else {
- /* Loading whole rbf image into buffer, normally for DDR buffer */
buffer_size = rbf_header_data_size;
/* Calculate size of rbf data in the buffer */
buffersize_after_header =
buffer_size - sizeof(struct image_header);
cff_flashinfo->remaining = 0;
- }
- /* Loading mkimage header and rbf data into buffer */
- ret = flash_read(cff_flashinfo, buffer_size, buffer_ptr);
- if (0 >= ret) {
printf(" Failed to read mkimage header and rbf data ");
printf("from flash.\n");
return -ENOENT;
- }
- /* Getting pointer of rbf data starting address where is it
right after mkimage header */
- bufferptr_after_header =
(u32 *)((u_char *)buffer_ptr + sizeof(struct image_header));
- /* Update next reading rbf data flash offset */
- cff_flashinfo->flash_offset += buffer_size;
- /* Update the starting addr of rbf data to init FPGA & programming
into FPGA */
- *buffer = (u32)bufferptr_after_header;
- get_rbf_image_info(&cff_flashinfo->rbfinfo, (u16 *)bufferptr_after_header);
- /* Update the size of rbf data to be programmed into FPGA */
- *buffer_sizebytes = buffersize_after_header;
+#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- cff_flashinfo->datacrc =
crc32(cff_flashinfo->datacrc,
(u_char *)bufferptr_after_header,
buffersize_after_header);
+#endif +if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- if (cff_flashinfo->datacrc !=
image_get_dcrc(&(cff_flashinfo->header))) {
printf("FPGA: Bad Data Checksum.\n");
return -EPERM;
- }
+#endif +}
- return 0;
+}
+static int cff_flash_read(struct cff_flash_info *cff_flashinfo, u32 *buffer,
- u32 *buffer_sizebytes)
+{
- int ret = 0;
- /* To avoid from keeping re-read the contents */
- size_t buffer_size = *buffer_sizebytes;
- u32 *buffer_ptr = (u32 *)*buffer;
- u32 flash_addr = cff_flashinfo->flash_offset;
- /* Buffer allocated in OCRAM */
- /* Read the data by small chunk by chunk. */
- if (cff_flashinfo->remaining > buffer_size)
cff_flashinfo->remaining -= buffer_size;
- else {
/* Buffer allocated in DDR, larger than rbf data most
of the time */
buffer_size = cff_flashinfo->remaining;
cff_flashinfo->remaining = 0;
- }
- ret = flash_read(cff_flashinfo, buffer_size, buffer_ptr);
- if (0 >= ret) {
printf(" Failed to read rbf data from flash.\n");
return -ENOENT;
- }
+#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- cff_flashinfo->datacrc =
crc32(cff_flashinfo->datacrc,
(unsigned char *)buffer_ptr, buffer_size);
+#endif
+if (0 == cff_flashinfo->remaining) { +#ifdef CONFIG_CHECK_FPGA_DATA_CRC
- if (cff_flashinfo->datacrc !=
image_get_dcrc(&(cff_flashinfo->header))) {
printf("FPGA: Bad Data Checksum.\n");
return -EPERM;
- }
+#endif +}
- /* Update next reading rbf data flash offset */
- flash_addr += buffer_size;
- cff_flashinfo->flash_offset = flash_addr;
- /* Update the size of rbf data to be programmed into FPGA */
- *buffer_sizebytes = buffer_size;
- return 0;
+}
+int cff_from_flash(fpga_fs_info *fpga_fsinfo) +{
- u32 buffer = 0;
- u32 buffer_ori = 0;
- u32 buffer_sizebytes = 0;
- u32 buffer_sizebytes_ori = 0;
- struct cff_flash_info cff_flashinfo;
- u32 status;
- int ret = 0;
- memset(&cff_flashinfo, 0, sizeof(cff_flashinfo));
- if (fpga_fsinfo->filename == NULL) {
printf("no [periph/core] rbf [filename/offset] specified.\n");
return -EINVAL;
- }
- WATCHDOG_RESET();
+#ifdef CONFIG_CMD_FPGA_LOADFS
- cff_flashinfo.sdmmc_flashinfo.dev_part =
simple_strtol(fpga_fsinfo->dev_part, NULL, 10);
+#endif
- ret = cff_flash_probe(&cff_flashinfo);
- if (0 >= ret) {
puts("Flash probe failed.\n");
return ret;
- }
+#ifdef CONFIG_CMD_FPGA_LOADFS
- /* Loading rbf data with DDR, faster than OCRAM,
only for core rbf */
- if (gd->ram_size != 0) {
ret = fat_size(fpga_fsinfo->filename, (loff_t *)&buffer_sizebytes);
if(ret){
puts("Failed to read file size.\n");
return ret;
}
buffer_ori = (u32)memalign(ARCH_DMA_MINALIGN, buffer_sizebytes);
if (!buffer_ori) {
error("RBF calloc failed!\n");
return -ENOMEM;
}
/* Loading mkimage header and rbf data into
DDR instead of OCRAM */
buffer = buffer_ori;
buffer_sizebytes_ori = buffer_sizebytes;
- } else {
buffer = buffer_ori = (u32)cff_flashinfo.buffer;
buffer_sizebytes =
buffer_sizebytes_ori =
sizeof(cff_flashinfo.buffer);
- }
+#else
- /* Adjust to adjacent block */
- buffer_sizebytes = buffer_sizebytes_ori =
(sizeof(cff_flashinfo.buffer)/ mmc->read_bl_len) *
mmc->read_bl_len;
+#endif
- /* Note: Both buffer and buffer_sizebytes values can be altered by
function below. */
- ret = cff_flash_preinit(&cff_flashinfo, fpga_fsinfo, &buffer,
&buffer_sizebytes);
- if (ret)
return ret;
- if (periph_section == cff_flashinfo.rbfinfo.section) {
/* initialize the FPGA Manager */
status = fpgamgr_program_init((u32 *)buffer, buffer_sizebytes);
if (status) {
printf("FPGA: Init with periph rbf failed with error. ");
printf("code %d\n", status);
return -EPERM;
}
- }
- WATCHDOG_RESET();
- /* transfer data to FPGA Manager */
- fpgamgr_program_write((void *)buffer,
buffer_sizebytes);
- WATCHDOG_RESET();
- while (cff_flashinfo.remaining) {
ret = cff_flash_read(&cff_flashinfo, &buffer_ori,
&buffer_sizebytes_ori);
if (ret)
return ret;
/* transfer data to FPGA Manager */
fpgamgr_program_write((void *)buffer_ori,
buffer_sizebytes_ori);
WATCHDOG_RESET();
- }
- if ((periph_section == cff_flashinfo.rbfinfo.section) &&
is_early_release_fpga_config(gd->fdt_blob)) {
if (-ETIMEDOUT != fpgamgr_wait_early_user_mode())
printf("FPGA: Early Release Succeeded.\n");
else {
printf("FPGA: Failed to see Early Release.\n");
return -EIO;
}
- } else if ((core_section == cff_flashinfo.rbfinfo.section) ||
((periph_section == cff_flashinfo.rbfinfo.section) &&
!is_early_release_fpga_config(gd->fdt_blob))) {
/* Ensure the FPGA entering config done */
status = fpgamgr_program_finish();
if (status)
return status;
else
printf("FPGA: Enter user mode.\n");
- } else {
printf("Config Error: Unsupported FGPA raw binary type.\n");
return -ENOEXEC;
- }
- WATCHDOG_RESET();
- return 1;
+} diff --git a/arch/arm/mach-socfpga/include/mach/cff.h b/arch/arm/mach-socfpga/include/mach/cff.h new file mode 100644 index 0000000..7f3f66b --- /dev/null +++ b/arch/arm/mach-socfpga/include/mach/cff.h @@ -0,0 +1,40 @@ +/*
- Copyright (C) 2017 Intel Corporation <www.intel.com>
- SPDX-License-Identifier: GPL-2.0
- */
+#ifndef _SOCFPGA_CFF_H_ +#define _SOCFPGA_CFF_H_
+#include <fpga.h>
+#ifndef __ASSEMBLY_
+struct flash_info {
- char *filename;
- int dev_part;
+};
+enum rbf_type {unknown, periph_section, core_section}; +enum rbf_security {invalid, unencrypted, encrypted};
+struct rbf_info {
- enum rbf_type section ;
- enum rbf_security security;
+};
+struct cff_flash_info {
- struct flash_info sdmmc_flashinfo;
- u32 buffer[4096] __aligned(ARCH_DMA_MINALIGN);
- u32 remaining;
- u32 flash_offset;
- struct rbf_info rbfinfo;
- struct image_header header;
+};
+int cff_from_sdmmc_env(unsigned int core); +int cff_from_flash(fpga_fs_info *fpga_fsinfo); +#endif /* __ASSEMBLY__ */
+#endif /* _SOCFPGA_CFF_H_ */ diff --git a/include/configs/socfpga_arria10_socdk.h b/include/configs/socfpga_arria10_socdk.h index 3b59b6a..aa4c54a 100644 --- a/include/configs/socfpga_arria10_socdk.h +++ b/include/configs/socfpga_arria10_socdk.h @@ -58,6 +58,12 @@
- Flash configurations
*/ #define CONFIG_SYS_MAX_FLASH_BANKS 1 +/* Default SDMMC physical address for periph.rbf (sector alignment) */ +#define CONFIG_FS_FAT_MAX_CLUSTSIZE (32 * 1024)
+#if !defined(CONFIG_SPL_BUILD) && !defined(CONFIG_CMD_FPGA_LOADFS) +#define CONFIG_CMD_FPGA_LOADFS +#endif
/* The rest of the configuration is shared */ #include <configs/socfpga_common.h>