On Sel, 2017-08-08 at 11:32 +0200, Marek Vasut wrote: > On 08/08/2017 11:12 AM, tien.fong.c...@intel.com wrote: > > > > From: Tien Fong Chee <tien.fong.c...@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.c...@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> > > > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot