mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
emc: add initial code to flash FPGA bitstream via PCIe
This commit is contained in:
parent
eabae63714
commit
e5545aa17e
3 changed files with 139 additions and 5 deletions
|
@ -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);
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
2
fpga/thirdparty/libxil
vendored
2
fpga/thirdparty/libxil
vendored
|
@ -1 +1 @@
|
|||
Subproject commit c11cc2fab5eea6bfa8b1412bb8bbd8680d3347d7
|
||||
Subproject commit b622ddef4315b7e8a56637d07aa2b26ba480d53a
|
Loading…
Add table
Reference in a new issue