
On Sel, 2017-08-08 at 11:32 +0200, Marek Vasut wrote:
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.
this is core driver for handling fpga program operation from flash to fpga manager. I can improve the message. Let me know if you have other comment need to add.
Coding style issues are present (camel case, wrong comment style, use checkpatch).
Okay, i will run checkpatch.
If this is for some FPGA loading, can this functionality be scripted instead?
Sorry, i'm not getting you. How functionality be scripted? Could you provide some example or details explanation?
Thanks.
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>