diff --git a/ip/i2c_opencores/HAL/src/i2c_opencores.c b/ip/i2c_opencores/HAL/src/i2c_opencores.c
index 96a39d5..1e98078 100644
--- a/ip/i2c_opencores/HAL/src/i2c_opencores.c
+++ b/ip/i2c_opencores/HAL/src/i2c_opencores.c
@@ -130,7 +130,7 @@ alt_u32 I2C_read(alt_u32 base,alt_u32 last)
int I2C_write
assumes that any addressing and start
has already been done.
- writes one byte of data from the slave.
+ writes one byte of data from the slave.
If last is set the stop bit set.
inputs
base = the base address of the component
@@ -182,7 +182,7 @@ alt_u32 I2C_write(alt_u32 base,alt_u8 data, alt_u32 last)
}
-void SPI_read(alt_u32 base, alt_u8 *rdata, int len)
+void __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_read(alt_u32 base, alt_u8 *rdata, int len)
{
int i;
@@ -197,7 +197,7 @@ void SPI_read(alt_u32 base, alt_u8 *rdata, int len)
}
}
-void SPI_write(alt_u32 base, const alt_u8 *wdata, int len)
+void __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_write(alt_u32 base, const alt_u8 *wdata, int len)
{
int i;
diff --git a/ossc.cof b/ossc.cof
index 939b47d..0348ca8 100644
--- a/ossc.cof
+++ b/ossc.cof
@@ -10,7 +10,7 @@
Page_0
1
- output_files/ossc.sof
+ output_files/ossc.sof1
diff --git a/ossc.qsf b/ossc.qsf
index d3bd9b3..b31ddb0 100644
--- a/ossc.qsf
+++ b/ossc.qsf
@@ -258,4 +258,5 @@ set_global_assignment -name SEARCH_PATH rtl
set_global_assignment -name SEARCH_PATH software/sys_controller/mem_init/
set_global_assignment -name SEARCH_PATH ip/ibex_qsys/rtl_extra
set_global_assignment -name VERILOG_MACRO "SYNTHESIS="
+set_global_assignment -name STRATIXIII_UPDATE_MODE REMOTE
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
\ No newline at end of file
diff --git a/software/sys_controller/av_controller.c b/software/sys_controller/av_controller.c
index de6d7c6..8951161 100644
--- a/software/sys_controller/av_controller.c
+++ b/software/sys_controller/av_controller.c
@@ -82,6 +82,11 @@ avinput_t target_input;
alt_u8 pcm1862_active;
+flash_ctrl_dev flashctrl_dev = {.regs = (volatile gen_flash_if_regs*)INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_CSR_BASE,
+ .flash_size = 0x0200000};
+
+rem_update_dev rem_reconfig_dev = {.regs = (volatile rem_update_regs*)0x0002a000};
+
uint8_t sl_def_iv_x, sl_def_iv_y;
alt_u32 read_it2(alt_u32 regaddr);
@@ -951,6 +956,9 @@ int main()
// Start system timer
alt_timestamp_start();
+ // Write-protect flash
+ flash_write_protect(&flashctrl_dev, 1);
+
init_stat = init_hw();
if (init_stat >= 0) {
diff --git a/software/sys_controller/inc/firmware.h b/software/sys_controller/inc/firmware.h
index 15c8d6c..7eade30 100644
--- a/software/sys_controller/inc/firmware.h
+++ b/software/sys_controller/inc/firmware.h
@@ -20,6 +20,7 @@
#ifndef FIRMWARE_H_
#define FIRMWARE_H_
+#include
#include "alt_types.h"
#include "sysconfig.h"
@@ -40,23 +41,29 @@
#define FW_UPDATE_RETRIES 3
-#define FW_IMAGE_ERROR 100
-#define FW_HDR_ERROR 101
-#define FW_HDR_CRC_ERROR 102
-#define FW_DATA_CRC_ERROR 103
-#define FW_UPD_CANCELLED 104
-
typedef struct {
char fw_key[4];
- alt_u8 version_major;
- alt_u8 version_minor;
+ uint8_t version_major;
+ uint8_t version_minor;
char version_suffix[8];
- alt_u32 hdr_len;
- alt_u32 data_len;
- alt_u32 data_crc;
- alt_u32 hdr_crc;
-} fw_hdr;
+ uint32_t hdr_len;
+ uint32_t data_len;
+ uint32_t data_crc;
+ char padding[482];
+ uint32_t hdr_crc;
+} __attribute__((packed)) fw_hdr;
+
+typedef struct {
+ uint32_t unused[29];
+ uint32_t reconfig_start;
+} rem_update_regs;
+
+typedef struct {
+ volatile rem_update_regs *regs;
+} rem_update_dev;
int fw_update();
+void fw_update_commit(uint32_t* cluster_idx, uint8_t* databuf, uint32_t bytes_to_copy, uint16_t fs_csize, uint16_t fs_startsec);
+
#endif
diff --git a/software/sys_controller/src/firmware.c b/software/sys_controller/src/firmware.c
index d8ae1a5..1d98516 100644
--- a/software/sys_controller/src/firmware.c
+++ b/software/sys_controller/src/firmware.c
@@ -30,190 +30,223 @@
#include "lcd.h"
#include "utils.h"
#include "menu.h"
+#include "ff.h"
+#include "file.h"
#include "altera_avalon_pio_regs.h"
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
extern SD_DEV sdcard_dev;
extern alt_u32 sys_ctrl;
+extern flash_ctrl_dev flashctrl_dev;
+extern rem_update_dev rem_reconfig_dev;
-static int check_fw_header(alt_u8 *databuf, fw_hdr *hdr)
-{
- alt_u32 crcval, tmp;
-
- strncpy(hdr->fw_key, (char*)databuf, 4);
- if (strncmp(hdr->fw_key, "OSSC", 4))
- return FW_IMAGE_ERROR;
-
- hdr->version_major = databuf[4];
- hdr->version_minor = databuf[5];
- strncpy(hdr->version_suffix, (char*)(databuf+6), 8);
- hdr->version_suffix[7] = 0;
-
- memcpy(&tmp, databuf+14, 4);
- hdr->hdr_len = bswap32(tmp);
- memcpy(&tmp, databuf+18, 4);
- hdr->data_len = bswap32(tmp);
- memcpy(&tmp, databuf+22, 4);
- hdr->data_crc = bswap32(tmp);
- // Always at bytes [508-511]
- memcpy(&tmp, databuf+508, 4);
- hdr->hdr_crc = bswap32(tmp);
-
- if (hdr->hdr_len < 26 || hdr->hdr_len > 508)
- return FW_HDR_ERROR;
-
- crcval = crc32(databuf, hdr->hdr_len, 1);
-
- if (crcval != hdr->hdr_crc)
- return FW_HDR_CRC_ERROR;
-
- return 0;
-}
-
-static int check_fw_image(alt_u32 offset, alt_u32 size, alt_u32 golden_crc, alt_u8 *tmpbuf)
-{
- alt_u32 crcval=0, i, bytes_to_read;
+//int fw_update(char *dirname, char *filename) {
+int fw_update() {
+ FIL fw_file;
SDRESULTS res;
+ char dirname_root[10];
+ fw_hdr hdr;
+ int retval;
+ unsigned bytes_read, bytes_to_copy;
+ uint32_t crcval, hdr_len, btn_vec;
+ uint32_t cluster_idx[100]; // enough for >=4kB cluster size
+ uint8_t databuf[SD_BLK_SIZE]; // temp buffer for data
+ uint16_t fs_csize, fs_startsec, cl_iter, cl_soffs;
- for (i=0; i 508)) {
+ printf("Invalid FW header\n");
+ retval = -4;
+ goto close_file;
+ }
+
+ crcval = crc32((unsigned char *)&hdr, hdr_len, 1);
+ hdr.hdr_len = bswap32(hdr.hdr_len);
+ hdr.data_len = bswap32(hdr.data_len);
+ hdr.data_crc = bswap32(hdr.data_crc);
+ hdr.hdr_crc = bswap32(hdr.hdr_crc);
+ if (crcval != hdr.hdr_crc) {
+ printf("Invalid FW header CRC (0x%.8x instead of 0x%.8x)\n", crcval, hdr.hdr_crc);
+ retval = -5;
+ goto close_file;
+ }
+
+ printf("Firmware %u.%u%s%s\n", hdr.version_major, hdr.version_minor, hdr.version_suffix[0] ? "-" : "", hdr.version_suffix);
+ bytes_to_copy = hdr.data_len;
+ printf(" Image: %u bytes, crc 0x%.8x\n", hdr.data_len, hdr.data_crc);
+ if (hdr.data_len >= 16*FLASH_SECTOR_SIZE) {
+ printf("Image exceeds flash allocation\n");
+ retval = -6;
+ goto close_file;
+ }
+
+ sniprintf(menu_row1, LCD_ROW_LEN+1, "v%u.%u%s%s", hdr.version_major, hdr.version_minor, hdr.version_suffix[0] ? "-" : "", hdr.version_suffix);
+ sniprintf(menu_row2, LCD_ROW_LEN+1, "Update? 1=Y, 2=N");
+ ui_disp_menu(1);
+
+ while (1) {
+ btn_vec = IORD_ALTERA_AVALON_PIO_DATA(PIO_1_BASE) & RC_MASK;
+
+ if (btn_vec == rc_keymap[RC_BTN1]) {
+ break;
+ } else if (btn_vec == rc_keymap[RC_BTN2]) {
+ //set_func_ret_msg("Cancelled");
+ retval = 1;
+ goto close_file;
+ }
+
+ usleep(WAITLOOP_SLEEP_US);
+ }
+
+ strlcpy(menu_row2, "Please wait...", LCD_ROW_LEN+1);
+ ui_disp_menu(1);
+
+ // check if 512-byte header is on first or second cluster
+ fs_startsec = fw_file.obj.fs->database;
+ fs_csize = fw_file.obj.fs->csize;
+ if (fs_csize == 1) {
+ cl_iter = 1;
+ cl_soffs = 0;
+ cluster_idx[0] = fw_file.obj.sclust;
+ } else {
+ cl_iter = 0;
+ cl_soffs = 1;
+ }
+ // record cluster IDs to an array
+ if ((f_read_cc(&fw_file, &cluster_idx[cl_iter], bytes_to_copy, &bytes_read, (sizeof(cluster_idx)/sizeof(cluster_idx[0]))-1) != F_OK) || (bytes_read != bytes_to_copy)) {
+ printf("FW cluster error\n");
+ retval = -7;
+ goto close_file;
+ }
+
+ file_close(&fw_file);
+ f_chdir("/");
+
+ printf("Checking copied data...\n");
+ while (bytes_to_copy > 0) {
+ bytes_read = (bytes_to_copy > SD_BLK_SIZE) ? SD_BLK_SIZE : bytes_to_copy;
+ res = SD_Read(&sdcard_dev, databuf, ((cluster_idx[cl_iter]-2)*fs_csize+fs_startsec+cl_soffs), 0, bytes_read);
+ if (res != SD_OK) {
+ printf("FW data read error\n");
+ retval = -8;
+ goto close_file;
+ }
+
+ crcval = crc32((unsigned char *)&databuf, bytes_read, (bytes_to_copy==hdr.data_len));
+ bytes_to_copy -= bytes_read;
+
+ cl_soffs += 1;
+ if (cl_soffs == fs_csize) {
+ cl_iter += 1;
+ cl_soffs = 0;
+ }
+ }
+
+ if (crcval != hdr.data_crc) {
+ printf("Image: Invalid CRC (0x%.8x)\n", crcval);
+ retval = -9;
+ goto close_file;
+ }
+
+ printf("Starting update procedure...\n");
+ strlcpy(menu_row1, "Updating", LCD_ROW_LEN+1);
+ ui_disp_menu(1);
+
+ //disable video output
+ tvp_powerdown();
+ sys_ctrl |= VIDGEN_OFF;
+ IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
+ usleep(10000);
+
+ // No return from here
+ fw_update_commit(cluster_idx, databuf, hdr.data_len, fs_csize, fs_startsec);
+ return 0;
+ } else {
+ printf("FW file not found\n");
+ f_chdir("/");
+ return -2;
}
- //disable video output
- tvp_powerdown();
- sys_ctrl |= VIDGEN_OFF;
- IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
- usleep(10000);
-
- strncpy(menu_row1, "Updating FW", LCD_ROW_LEN+1);
-update_init:
- strncpy(menu_row2, "please wait...", LCD_ROW_LEN+1);
- ui_disp_menu(1);
-
- /*retval = copy_sd_to_flash(512/SD_BLK_SIZE, 0, fw_header.data_len, databuf);
- if (retval != 0)
- goto failure;
-
- strncpy(menu_row1, "Verifying flash", LCD_ROW_LEN+1);
- ui_disp_menu(1);
- retval = verify_flash(0, fw_header.data_len, fw_header.data_crc, databuf);
- if (retval != 0)
- goto failure;*/
-
- SPI_CS_High();
-
- strncpy(menu_row1, "Firmware updated", LCD_ROW_LEN+1);
- strncpy(menu_row2, "please restart", LCD_ROW_LEN+1);
- ui_disp_menu(1);
- while (1) {}
-
- return 0;
-
-failure:
- SPI_CS_High();
-
- switch (retval) {
- case SD_NOINIT:
- errmsg = "No SD card det.";
- break;
- case FW_IMAGE_ERROR:
- errmsg = "Invalid image";
- break;
- case FW_HDR_ERROR:
- errmsg = "Invalid header";
- break;
- case FW_HDR_CRC_ERROR:
- errmsg = "Invalid hdr CRC";
- break;
- case FW_DATA_CRC_ERROR:
- errmsg = "Invalid data CRC";
- break;
- case FW_UPD_CANCELLED:
- errmsg = "Update cancelled";
- break;
- default:
- errmsg = "SD/Flash error";
- break;
- }
- strncpy(menu_row2, errmsg, LCD_ROW_LEN+1);
- ui_disp_menu(1);
- usleep(1000000);
-
- // Critical error, retry update
- if ((retval < 0) && (retries > 0)) {
- sniprintf(menu_row1, LCD_ROW_LEN+1, "Retrying update");
- retries--;
- goto update_init;
- }
-
- render_osd_page();
- return -1;
+close_file:
+ file_close(&fw_file);
+ f_chdir("/");
+ return retval;
+}
+
+// commit FW update. Do not call functions located in flash during update
+void __attribute__((noinline, flatten, noreturn, __section__(".text_bram"))) fw_update_commit(uint32_t* cluster_idx, uint8_t* databuf, uint32_t bytes_to_copy, uint16_t fs_csize, uint16_t fs_startsec) {
+ int i, sectors;
+ SDRESULTS res;
+ uint16_t cl_iter, cl_soffs;
+ uint32_t addr, bytes_read;
+ uint32_t *data_to;
+
+ flash_write_protect(&flashctrl_dev, 0);
+
+ // Erase sectors
+ addr = 0;
+ sectors = (bytes_to_copy/FLASH_SECTOR_SIZE) + ((bytes_to_copy % FLASH_SECTOR_SIZE) != 0);
+ data_to = (uint32_t*)(INTEL_GENERIC_SERIAL_FLASH_INTERFACE_TOP_0_AVL_MEM_BASE);
+
+ for (i=0; i 0) {
+ bytes_read = (bytes_to_copy > SD_BLK_SIZE) ? SD_BLK_SIZE : bytes_to_copy;
+ res = SD_Read(&sdcard_dev, databuf, ((cluster_idx[cl_iter]-2)*fs_csize+fs_startsec+cl_soffs), 0, bytes_read);
+ //TODO: retry if read fails
+
+ bytes_to_copy -= bytes_read;
+ for (i=0; ireconfig_start = 1;
+
+ while (1) {}
}
diff --git a/software/sys_controller/src/menu.c b/software/sys_controller/src/menu.c
index ab1c16e..d31ed3b 100644
--- a/software/sys_controller/src/menu.c
+++ b/software/sys_controller/src/menu.c
@@ -208,9 +208,7 @@ MENU(menu_scanlines, P99_PROTECT({ \
{ "Sl. alternating", OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_altern, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
{ LNG("Sl. alignment","スキャンラインポジション"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_id, OPT_WRAP, SETTING_ITEM(sl_id_desc) } } },
{ LNG("Sl. type","スキャンラインルイ"), OPT_AVCONFIG_SELECTION, { .sel = { &tc.sl_type, OPT_WRAP, SETTING_ITEM(sl_type_desc) } } },
-#ifndef DEBUG
{ "< Custom Sl. >", OPT_SUBMENU, { .sub = { &menu_cust_sl, NULL, NULL } } },
-#endif
}))
MENU(menu_postproc, P99_PROTECT({ \
@@ -251,11 +249,9 @@ MENU(menu_settings, P99_PROTECT({ \
{ LNG("","<プロファイルロード >"), OPT_FUNC_CALL, { .fun = { load_profile, &profile_arg_info } } },
{ LNG("","<プロファイルセーブ >"), OPT_FUNC_CALL, { .fun = { save_profile, &profile_arg_info } } },
{ LNG("","<セッテイヲショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, NULL } } },
-#ifndef DEBUG
{ LNG("","<セッテイヨミコミ >"), OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
{ LNG("","<セッテイカキコミ >"), OPT_FUNC_CALL, { .fun = { export_userdata, NULL } } },
{ LNG("","<ファームウェアアップデート>"), OPT_FUNC_CALL, { .fun = { fw_update, NULL } } },
-#endif
}))
diff --git a/software/sys_controller/src/utils.c b/software/sys_controller/src/utils.c
index 7a59b58..8f8356b 100644
--- a/software/sys_controller/src/utils.c
+++ b/software/sys_controller/src/utils.c
@@ -25,7 +25,7 @@
#include "sysconfig.h"
#include "io.h"
-inline unsigned char bitswap8(unsigned char v)
+inline __attribute__((flatten, __section__(".text_bram"))) unsigned char bitswap8(unsigned char v)
{
return ((v * 0x0802LU & 0x22110LU) |
(v * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
diff --git a/software/sys_controller/ulibSD/sd_io.c b/software/sys_controller/ulibSD/sd_io.c
index 73faf2f..e1a1c8a 100644
--- a/software/sys_controller/ulibSD/sd_io.c
+++ b/software/sys_controller/ulibSD/sd_io.c
@@ -94,11 +94,11 @@ DWORD __SD_Power_Of_Two(BYTE e)
return(partial);
}
-inline void __SD_Assert(void){
+inline void __attribute__((flatten, __section__(".text_bram"))) __SD_Assert(void){
SPI_CS_Low();
}
-inline void __SD_Deassert(void){
+inline void __attribute__((flatten, __section__(".text_bram"))) __SD_Deassert(void){
SPI_CS_High();
}
@@ -107,7 +107,7 @@ void __SD_Speed_Transfer(BYTE throttle) {
else SPI_Freq_Low();
}
-BYTE __SD_Send_Cmd(BYTE cmd, DWORD arg)
+BYTE __attribute__((noinline, flatten, __section__(".text_bram"))) __SD_Send_Cmd(BYTE cmd, DWORD arg)
{
BYTE wiredata[10];
BYTE crc, res;
@@ -361,7 +361,7 @@ SDRESULTS SD_Init(SD_DEV *dev)
#endif
}
-SDRESULTS SD_Read(SD_DEV *dev, void *dat, DWORD sector, WORD ofs, WORD cnt)
+SDRESULTS __attribute__((noinline, flatten, __section__(".text_bram"))) SD_Read(SD_DEV *dev, void *dat, DWORD sector, WORD ofs, WORD cnt)
{
#if defined(_M_IX86) // x86
// Check the sector query
diff --git a/software/sys_controller/ulibSD/spi_io.c b/software/sys_controller/ulibSD/spi_io.c
index 89f193e..05c64c7 100644
--- a/software/sys_controller/ulibSD/spi_io.c
+++ b/software/sys_controller/ulibSD/spi_io.c
@@ -15,11 +15,11 @@ void SPI_Init (void) {
I2C_init(SD_SPI_BASE,ALT_CPU_FREQ,400000);
}
-void SPI_W(const BYTE *wd, int len) {
+void __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_W(const BYTE *wd, int len) {
SPI_write(SD_SPI_BASE, wd, len);
}
-void SPI_R(BYTE *rd, int len) {
+void __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_R(BYTE *rd, int len) {
SPI_read(SD_SPI_BASE, rd, len);
}
@@ -34,16 +34,17 @@ BYTE SPI_RW (BYTE d) {
return w;
}
-void SPI_Release (void) {
+void __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_Release (void) {
+ SPI_CS_High();
return;
}
-inline void SPI_CS_Low (void) {
+inline void __attribute__((flatten, __section__(".text_bram"))) SPI_CS_Low (void) {
sys_ctrl &= ~SD_SPI_SS_N;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
}
-inline void SPI_CS_High (void){
+inline void __attribute__((flatten, __section__(".text_bram"))) SPI_CS_High (void){
sys_ctrl |= SD_SPI_SS_N;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, sys_ctrl);
}
@@ -56,7 +57,7 @@ inline void SPI_Freq_Low (void) {
I2C_init(SD_SPI_BASE,ALT_CPU_FREQ,400000);
}
-int SPI_Timer_On (WORD ms) {
+int __attribute__((noinline, flatten, __section__(".text_bram"))) SPI_Timer_On (WORD ms) {
if (!sd_timer_ts) {
sd_timer_ts = alt_timestamp() + ms*(TIMER_0_FREQ/1000);
return 0;
@@ -64,11 +65,11 @@ int SPI_Timer_On (WORD ms) {
return 1;
}
-inline BOOL SPI_Timer_Status (void) {
+inline BOOL __attribute__((flatten, __section__(".text_bram"))) SPI_Timer_Status (void) {
return alt_timestamp() < sd_timer_ts;
}
-inline void SPI_Timer_Off (void) {
+inline void __attribute__((flatten, __section__(".text_bram"))) SPI_Timer_Off (void) {
sd_timer_ts = 0;
return;
}
diff --git a/sys.qsys b/sys.qsys
index daa6968..c40bc28 100644
--- a/sys.qsys
+++ b/sys.qsys
@@ -293,6 +293,27 @@
type = "int";
}
}
+ element remote_update_0
+ {
+ datum _sortIndex
+ {
+ value = "16";
+ type = "int";
+ }
+ }
+ element remote_update_0.avl_csr
+ {
+ datum _lockedAddress
+ {
+ value = "1";
+ type = "boolean";
+ }
+ datum baseAddress
+ {
+ value = "172032";
+ type = "String";
+ }
+ }
element sc_config_0
{
datum _sortIndex
@@ -578,6 +599,21 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -672,6 +708,15 @@
+
+
+
+
+
+
+
-
+
java.lang.Integer
- 1745002926
+ 1746263054
false
true
false
@@ -402,6 +402,12 @@ parameters are a RESULT of the module parameters. -->
clock
i2c_opencores_1.clock
+
+ false
+ remote_update_0
+ clock
+ remote_update_0.clock
+
false
sc_config_0
@@ -3314,6 +3320,14 @@ parameters are a RESULT of the module parameters. -->
131328
256
+
+ false
+ remote_update_0
+ avl_csr
+ remote_update_0.avl_csr
+ 172032
+ 128
+
false
intel_generic_serial_flash_interface_top_0
@@ -10799,6 +10813,604 @@ parameters are a RESULT of the module parameters. -->
+
+
+
+ java.lang.String
+ CYCLONEIVE
+ false
+ true
+ false
+ true
+ DEVICE_FAMILY
+
+
+ java.lang.String
+ EP4CE15E22C8
+ false
+ true
+ false
+ true
+ DEVICE
+
+
+ java.lang.String
+ ALL
+ false
+ true
+ false
+ true
+
+
+ java.lang.String
+ REMOTE
+ false
+ true
+ true
+ true
+
+
+ java.lang.String
+ EPCS16
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+ boolean
+ true
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+ int
+ 24
+ true
+ true
+ false
+ true
+
+
+ boolean
+ false
+ true
+ true
+ false
+ true
+
+
+ int
+ 24
+ true
+ true
+ false
+ true
+
+
+ int
+ 24
+ true
+ true
+ false
+ true
+
+
+ java.lang.String
+ 8
+ false
+ true
+ false
+ true
+ DEVICE_SPEEDGRADE
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+
+
+ embeddedsw.configuration.isFlash
+ 0
+
+
+ embeddedsw.configuration.isMemoryDevice
+ 0
+
+
+ embeddedsw.configuration.isNonVolatileStorage
+ 0
+
+
+ embeddedsw.configuration.isPrintableDevice
+ 0
+
+
+ com.altera.sopcmodel.avalon.AvalonConnectionPoint$AddressAlignment
+ DYNAMIC
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ true
+ false
+ true
+
+
+ java.math.BigInteger
+ 128
+ true
+ true
+ false
+ true
+
+
+ com.altera.sopcmodel.avalon.EAddrBurstUnits
+ WORDS
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ java.lang.String
+ clock
+ false
+ true
+ true
+ true
+
+
+ java.lang.String
+ reset
+ false
+ true
+ true
+ true
+
+
+ int
+ 8
+ false
+ true
+ true
+ true
+
+
+ java.math.BigInteger
+ 0
+ false
+ true
+ false
+ true
+
+
+ com.altera.entityinterfaces.IConnectionPoint
+
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+ com.altera.sopcmodel.avalon.EAddrBurstUnits
+ WORDS
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ java.math.BigInteger
+ 0
+ false
+ true
+ true
+ true
+
+
+ int
+ 0
+ false
+ false
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+ int
+ 1
+ false
+ true
+ true
+ true
+
+
+ int
+ 0
+ false
+ false
+ true
+ true
+
+
+ int
+ 1
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ false
+ true
+ true
+
+
+ int
+ 1
+ false
+ true
+ false
+ true
+
+
+ int
+ 1
+ false
+ false
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ false
+ true
+ true
+
+
+ com.altera.sopcmodel.avalon.TimingUnits
+ Cycles
+ false
+ false
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ true
+ false
+ true
+
+
+ int
+ 0
+ false
+ false
+ true
+ true
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ avalon
+ false
+
+ avl_csr_write
+ Input
+ 1
+ write
+
+
+ avl_csr_read
+ Input
+ 1
+ read
+
+
+ avl_csr_writedata
+ Input
+ 32
+ writedata
+
+
+ avl_csr_readdata
+ Output
+ 32
+ readdata
+
+
+ avl_csr_readdatavalid
+ Output
+ 1
+ readdatavalid
+
+
+ avl_csr_waitrequest
+ Output
+ 1
+ waitrequest
+
+
+ avl_csr_address
+ Input
+ 5
+ address
+
+
+
+
+
+ boolean
+ false
+ false
+ true
+ false
+ true
+
+
+ java.lang.String
+
+ false
+ true
+ false
+ true
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ clock
+ false
+
+ clock
+ Input
+ 1
+ clk
+
+
+
+
+
+ java.lang.String
+ clock
+ false
+ true
+ true
+ true
+
+
+ com.altera.sopcmodel.reset.Reset$Edges
+ DEASSERT
+ false
+ true
+ true
+ true
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ reset
+ false
+
+ reset
+ Input
+ 1
+ reset
+
+
+
@@ -12666,6 +13278,57 @@ parameters are a RESULT of the module parameters. -->
intel_generic_serial_flash_interface_top_0
avl_csr
+
+
+ int
+ 1
+ false
+ true
+ true
+ true
+
+
+ java.math.BigInteger
+ 0x0002a000
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ ibex_0
+ avalon_master_bus_data
+ remote_update_0
+ avl_csr
+
i2c_opencores_1
clock
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ clk_27
+ clk
+ remote_update_0
+ clock
+
intel_generic_serial_flash_interface_top_0
reset
+
+
+ java.lang.String
+ UNKNOWN
+ false
+ true
+ true
+ true
+
+
+ boolean
+ false
+ false
+ true
+ true
+ true
+
+ clk_27
+ clk_reset
+ remote_update_0
+ reset
+
1.0
- 15
+ 16
clock_sink
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IMutableConnectionPoint
@@ -14285,7 +15002,7 @@ parameters are a RESULT of the module parameters. -->
24.1
- 16
+ 17
reset_sink
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IMutableConnectionPoint
@@ -14293,7 +15010,7 @@ parameters are a RESULT of the module parameters. -->
24.1
- 16
+ 17
avalon_slave
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IMutableConnectionPoint
@@ -14420,6 +15137,14 @@ parameters are a RESULT of the module parameters. -->
Reset Bridge
24.1
+
+ 1
+ altera_remote_update
+ com.altera.entityinterfaces.IElementClass
+ com.altera.entityinterfaces.IModule
+ Remote Update Intel FPGA IP
+ 24.1
+
1
sc_config
@@ -14437,7 +15162,7 @@ parameters are a RESULT of the module parameters. -->
24.1
- 21
+ 22
avalon
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IConnection
@@ -14445,7 +15170,7 @@ parameters are a RESULT of the module parameters. -->
24.1
- 15
+ 16
clock
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IConnection
@@ -14461,7 +15186,7 @@ parameters are a RESULT of the module parameters. -->
24.1
- 15
+ 16
reset
com.altera.entityinterfaces.IElementClass
com.altera.entityinterfaces.IConnection
diff --git a/tools/create_fw_img.c b/tools/create_fw_img.c
index f081647..9caaecd 100644
--- a/tools/create_fw_img.c
+++ b/tools/create_fw_img.c
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -35,6 +36,18 @@
#define FW_HDR_LEN 26
+typedef struct {
+ char fw_key[4];
+ uint8_t version_major;
+ uint8_t version_minor;
+ char version_suffix[8];
+ uint32_t hdr_len;
+ uint32_t data_len;
+ uint32_t data_crc;
+ char padding[482];
+ uint32_t hdr_crc;
+} __attribute__((packed)) fw_header;
+
static uint32_t crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -94,99 +107,170 @@ uint32_t crc32(uint32_t crc, const void *buf, size_t size)
return crc ^ ~0U;
}
+void bitswap8_buf(unsigned char *buf, size_t length)
+{
+ for (size_t i=0; i> 16;
+}
+
int main(int argc, char **argv)
{
unsigned char block;
-
- int fd_i, fd_o;
- struct stat fileinfo;
+
+ int fd_i[2], fd_o;
+ struct stat fileinfo[2];
char fw_bin_name[MAX_FILENAME];
- char hdrbuf[HDR_SIZE];
char rdbuf[BUF_SIZE];
- unsigned fw_version_major;
- unsigned fw_version_minor;
- uint32_t hdr_crc;
- uint32_t crc = 0;
-
- unsigned int i, bytes_read, bytes_written, tot_bytes_read = 0;
-
- if ((argc < 3) || (argc > 4)) {
- printf("Usege: %s rbf version [version_suffix]\n", argv[0]);
- return -1;
- }
-
- if ((fd_i = open(argv[1], O_RDONLY)) == -1 || fstat(fd_i, &fileinfo) == -1) {
- printf("Couldn't open input file\n");
+ fw_header hdr = {0};
+ unsigned fw_version_major, fw_version_minor;
+ int legacy_mode = 0;
+ uint32_t bin_offset, padding;
+
+ unsigned int i, bytes_read, bytes_written, tot_bytes_read[3] = {0, 0, 0};
+
+ if ((argc < 3) || (argc > 6)) {
+ printf("Usage: %s rbf bin bin_offset version [version_suffix]\nLegacy usage: %s rbf version [version_suffix]\n", argv[0], argv[0]);
return -1;
}
-
- snprintf(fw_bin_name, MAX_FILENAME-1, "ossc_%s%s%s.bin", argv[2], (argc == 4) ? "-" : "", (argc == 4) ? argv[3] : "");
-
- if ((fd_o = open(fw_bin_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) == -1) {
+ if (argc < 5)
+ legacy_mode = 1;
+
+ if ((fd_i[0] = open(argv[1], O_RDONLY)) == -1 || fstat(fd_i[0], &fileinfo[0]) == -1) {
+ printf("Couldn't open input RBF file\n");
+ return -1;
+ }
+ if (!legacy_mode) {
+ if ((fd_i[1] = open(argv[2], O_RDONLY)) == -1 || fstat(fd_i[1], &fileinfo[1]) == -1) {
+ printf("Couldn't open input BIN file\n");
+ return -1;
+ }
+ }
+
+ if (legacy_mode)
+ snprintf(fw_bin_name, MAX_FILENAME-1, "ossc_%s%s%s.bin", argv[2], (argc == 4) ? "-" : "", (argc == 4) ? argv[3] : "");
+ else
+ snprintf(fw_bin_name, MAX_FILENAME-1, "ossc_%s%s%s.bin", argv[4], (argc == 6) ? "-" : "", (argc == 6) ? argv[5] : "");
+
+ if ((fd_o = open(fw_bin_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1) {
printf("Couldn't open output file\n");
return -1;
}
- if ((sscanf(argv[2], "%u.%u", &fw_version_major, &fw_version_minor) != 2) || (fw_version_major > 255) || (fw_version_minor > 255)) {
+ if ((sscanf(legacy_mode ? argv[2] : argv[4], "%u.%u", &fw_version_major, &fw_version_minor) != 2) || (fw_version_major > 255) || (fw_version_minor > 255)) {
printf("Invalid version format specified\n");
return -1;
}
- //printf("%s, %u.%u\n", argv[2], fw_version_major, (uint8_t)fw_version_minor);
- memset(hdrbuf, 0x00, HDR_SIZE);
- snprintf(hdrbuf, FW_KEY_SIZE+1, "OSSC");
- hdrbuf[4] = (uint8_t)fw_version_major;
- hdrbuf[5] = (uint8_t)fw_version_minor;
- snprintf(hdrbuf+6, FW_SUFFIX_MAX_SIZE+1, (argc == 4) ? argv[3] : "");
- *((uint32_t*)(hdrbuf+6+FW_SUFFIX_MAX_SIZE)) = htonl(FW_HDR_LEN);
- *((uint32_t*)(hdrbuf+6+FW_SUFFIX_MAX_SIZE+4)) = htonl((uint32_t)fileinfo.st_size);
+ snprintf(hdr.fw_key, FW_KEY_SIZE+1, "OSSC");
+ hdr.version_major = (uint8_t)fw_version_major;
+ hdr.version_minor = (uint8_t)fw_version_minor;
+ snprintf(hdr.version_suffix, FW_SUFFIX_MAX_SIZE, legacy_mode ? ((argc == 4) ? argv[3] : "") : ((argc == 6) ? argv[5] : ""));
+ hdr.hdr_len = htobe32(FW_HDR_LEN);
- // data CRC
- while ((bytes_read = read(fd_i, rdbuf, BUF_SIZE)) > 0) {
- crc = crc32(crc, rdbuf, bytes_read);
- tot_bytes_read += bytes_read;
+ if (legacy_mode) {
+ hdr.data_len = htobe32((uint32_t)fileinfo[0].st_size);
+
+ // data CRC (rbf)
+ while ((bytes_read = read(fd_i[0], rdbuf, BUF_SIZE)) > 0) {
+ hdr.data_crc = crc32(hdr.data_crc, rdbuf, bytes_read);
+ tot_bytes_read[0] += bytes_read;
+ }
+ } else {
+ bin_offset = (uint32_t)strtol(argv[3], NULL, 16);
+
+ // data CRC (rbf)
+ while ((bytes_read = read(fd_i[0], rdbuf, BUF_SIZE)) > 0) {
+ hdr.data_crc = crc32(hdr.data_crc, rdbuf, bytes_read);
+ tot_bytes_read[0] += bytes_read;
+ }
+ // data CRC (padding)
+ memset(rdbuf, 0xff, sizeof(rdbuf));
+ padding = bin_offset - tot_bytes_read[0];
+ while (tot_bytes_read[1] < padding) {
+ bytes_read = ((padding-tot_bytes_read[1]) > sizeof(rdbuf)) ? sizeof(rdbuf) : (padding-tot_bytes_read[1]);
+ hdr.data_crc = crc32(hdr.data_crc, rdbuf, bytes_read);
+ tot_bytes_read[1] += bytes_read;
+ }
+ // data CRC (bin)
+ while ((bytes_read = read(fd_i[1], rdbuf, BUF_SIZE)) > 0) {
+ bitswap8_buf(rdbuf, bytes_read);
+ hdr.data_crc = crc32(hdr.data_crc, rdbuf, bytes_read);
+ tot_bytes_read[2] += bytes_read;
+ }
+ hdr.data_len = htobe32((uint32_t)fileinfo[0].st_size+padding+(uint32_t)fileinfo[1].st_size);
}
- *((uint32_t*)(hdrbuf+6+FW_SUFFIX_MAX_SIZE+8)) = htonl(crc);
// header CRC
- hdr_crc = crc32(0, hdrbuf, FW_HDR_LEN);
- *((uint32_t*)(hdrbuf+HDR_SIZE-4)) = htonl(hdr_crc);
+ hdr.data_crc = htobe32(hdr.data_crc);
+ hdr.hdr_crc = crc32(0, &hdr, FW_HDR_LEN);
+ hdr.hdr_crc = htobe32(hdr.hdr_crc);
- if (tot_bytes_read != fileinfo.st_size) {
- printf("Incorrect size output file\n");
- return -1;
+ if ((tot_bytes_read[0] != fileinfo[0].st_size) || (!legacy_mode && (tot_bytes_read[2] != fileinfo[1].st_size))) {
+ printf("Incorrect size input data read\n");
+ return -1;
}
- printf("version %u.%u%s%s: %u bytes\n", fw_version_major, fw_version_minor, (argc == 4) ? "-" : "", hdrbuf+6, fileinfo.st_size);
- printf("Header CRC32: %.8x\n", hdr_crc);
- printf("Data CRC32: %.8x\n", crc);
+ printf("version %u.%u%s%s: %u bytes\n", fw_version_major, fw_version_minor, (argc == 4+2*!legacy_mode) ? "-" : "", hdr.version_suffix, tot_bytes_read[0]+tot_bytes_read[1]+tot_bytes_read[2]);
+ printf("Header CRC32: %.8x\n", htobe32(hdr.hdr_crc));
+ printf("Data CRC32: %.8x\n", htobe32(hdr.data_crc));
- bytes_written = write(fd_o, hdrbuf, HDR_SIZE);
+ bytes_written = write(fd_o, &hdr, HDR_SIZE);
if (bytes_written != HDR_SIZE) {
printf("Couldn't write output file\n");
return -1;
}
- tot_bytes_read = 0;
- lseek(fd_i, 0, SEEK_SET);
- while ((bytes_read = read(fd_i, rdbuf, BUF_SIZE)) > 0) {
+ tot_bytes_read[0] = 0;
+ lseek(fd_i[0], 0, SEEK_SET);
+ while ((bytes_read = read(fd_i[0], rdbuf, BUF_SIZE)) > 0) {
bytes_written = write(fd_o, rdbuf, bytes_read);
if (bytes_written != bytes_read) {
printf("Couldn't write output file\n");
return -1;
}
- tot_bytes_read += bytes_read;
+ tot_bytes_read[0] += bytes_read;
}
- if (tot_bytes_read != fileinfo.st_size) {
+ if (tot_bytes_read[0] != fileinfo[0].st_size) {
printf("Incorrect size output file\n");
- return -1;
+ return -1;
+ }
+
+ if (!legacy_mode) {
+ memset(rdbuf, 0xff, sizeof(rdbuf));
+ while (tot_bytes_read[1] > 0) {
+ bytes_read = (tot_bytes_read[1] > sizeof(rdbuf)) ? sizeof(rdbuf) : tot_bytes_read[1];
+ bytes_written = write(fd_o, rdbuf, bytes_read);
+ if (bytes_written != bytes_read) {
+ printf("Couldn't write output file\n");
+ return -1;
+ }
+ tot_bytes_read[1] -= bytes_read;
+ }
+
+ tot_bytes_read[2] = 0;
+ lseek(fd_i[1], 0, SEEK_SET);
+ while ((bytes_read = read(fd_i[1], rdbuf, BUF_SIZE)) > 0) {
+ bitswap8_buf(rdbuf, bytes_read);
+ bytes_written = write(fd_o, rdbuf, bytes_read);
+ if (bytes_written != bytes_read) {
+ printf("Couldn't write output file\n");
+ return -1;
+ }
+ tot_bytes_read[2] += bytes_read;
+ }
+ if (tot_bytes_read[2] != fileinfo[1].st_size) {
+ printf("Incorrect size output bin file\n");
+ return -1;
+ }
}
printf("Firmware image written to %s\n", fw_bin_name);
-
+
close(fd_o);
- close(fd_i);
-
+ close(fd_i[0]);
+ if (!legacy_mode)
+ close(fd_i[1]);
+
return 0;
}