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; }