Commit e73d84f1 authored by Steffen Vogel's avatar Steffen Vogel 🎅🏼
Browse files

emc: add initial code to flash FPGA bitstream via PCIe

parent e54aabff
Pipeline #305523 failed with stages
in 2 seconds
......@@ -27,6 +27,8 @@
#pragma once
#include <xilinx/xilflash.h>
#include <villas/fpga/core.hpp>
namespace villas {
......@@ -40,8 +42,15 @@ public:
bool init();
bool flash(uint32_t offset, const std::string &filename);
bool flash(uint32_t offset, uint32_t length, uint8_t *data);
bool read(uint32_t offset, uint32_t length, uint8_t *data);
private:
XFlash xflash;
static constexpr char registerMemory[] = "Reg";
std::list<MemoryBlockName> getMemoryBlocks() const
......
......@@ -20,21 +20,146 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************************/
#include <villas/plugin.hpp>
#include <iostream>
#include <villas/plugin.hpp>
#include <villas/fpga/ips/emc.hpp>
using namespace villas::fpga::ip;
// instantiate factory to make available to plugin infrastructure
static EMCFactory factory;
bool
EMC::init()
{
//const uintptr_t base = getBaseAddr(registerMemory);
int ret;
const uintptr_t base = getBaseAddr(registerMemory);
return true;
#ifdef XPAR_XFL_DEVICE_FAMILY_INTEL
#if XFL_TO_ASYNCMODE
/* Set Flash to Async mode. */
if (FLASH_MEM_WIDTH == 1) {
WRITE_FLASH_8(FLASH_BASE_ADDRESS + ASYNC_ADDR, 0x60);
WRITE_FLASH_8(FLASH_BASE_ADDRESS + ASYNC_ADDR, 0x03);
}
else if (FLASH_MEM_WIDTH == 2) {
WRITE_FLASH_16(FLASH_BASE_ADDRESS + ASYNC_ADDR,
INTEL_CMD_CONFIG_REG_SETUP);
WRITE_FLASH_16(FLASH_BASE_ADDRESS + ASYNC_ADDR,
INTEL_CMD_CONFIG_REG_CONFIRM);
}
#endif
#endif
ret = XFlash_Initialize(&xflash, base, 2, 0);
if (ret != XST_SUCCESS)
return false;
return XFlash_IsReady(&xflash);
}
bool
EMC::read(uint32_t offset, uint32_t length, uint8_t *data)
{
int ret;
/*
* Reset the Flash Device. This clears the ret registers and puts
* the device in Read mode.
*/
ret = XFlash_Reset(&xflash);
if (ret != XST_SUCCESS)
return false;
/*
* Perform the read operation.
*/
ret = XFlash_Read(&xflash, offset, length, data);
if(ret != XST_SUCCESS)
return false;
return false;
}
// objcopy -I ihex -O binary somefile.mcs somefile.bin
bool
EMC::flash(uint32_t offset, const std::string &filename)
{
bool result;
uint32_t length;
uint8_t *buffer;
std::ifstream is(filename, std::ios::binary);
// get length of file:
is.seekg(0, std::ios::end);
length = is.tellg();
is.seekg (0, std::ios::beg);
// allocate memory:
buffer = new uint8_t[length];
is.read(reinterpret_cast<char *>(buffer), length);
is.close();
result = flash(offset, length, buffer);
delete[] buffer;
return result;
}
/* Based on xilflash_readwrite_example.c */
bool
EMC::flash(uint32_t offset, uint32_t length, uint8_t *data)
{
int ret = XST_FAILURE;
uint32_t start = offset;
uint8_t *verify_data = new uint8_t[length];
/* Reset the Flash Device. This clears the ret registers and puts
* the device in Read mode. */
ret = XFlash_Reset(&xflash);
if (ret != XST_SUCCESS)
return false;
/* Perform an unlock operation before the erase operation for the Intel
* Flash. The erase operation will result in an error if the block is
* locked. */
if ((xflash.CommandSet == XFL_CMDSET_INTEL_STANDARD) ||
(xflash.CommandSet == XFL_CMDSET_INTEL_EXTENDED) ||
(xflash.CommandSet == XFL_CMDSET_INTEL_G18)) {
ret = XFlash_Unlock(&xflash, offset, 0);
if(ret != XST_SUCCESS)
return false;
}
/* Perform the Erase operation. */
ret = XFlash_Erase(&xflash, start, length);
if (ret != XST_SUCCESS)
return false;
/* Perform the Write operation. */
ret = XFlash_Write(&xflash, start, length, data);
if (ret != XST_SUCCESS)
return false;
/* Perform the read operation. */
ret = XFlash_Read(&xflash, start, length, verify_data);
if(ret != XST_SUCCESS) {
return false;
}
/* Compare the data read against the data Written. */
for (unsigned i = 0; i < length; i++) {
if (verify_data[i] != data[i])
return false;
}
delete[] verify_data;
return true;
}
Subproject commit c11cc2fab5eea6bfa8b1412bb8bbd8680d3347d7
Subproject commit b622ddef4315b7e8a56637d07aa2b26ba480d53a
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment