diff --git a/firmware/boot.c b/firmware/boot.c new file mode 100644 index 0000000..0aac05f --- /dev/null +++ b/firmware/boot.c @@ -0,0 +1,684 @@ +// This file is Copyright (c) 2014-2020 Florent Kermarrec +// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq +// This file is Copyright (c) 2018 Ewen McNeill +// This file is Copyright (c) 2018 Felix Held +// This file is Copyright (c) 2019 Gabriel L. Somlo +// This file is Copyright (c) 2017 Tim 'mithro' Ansell +// This file is Copyright (c) 2018 William D. Jones +// License: BSD + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sfl.h" +#include "boot.h" +#include "jsmn.h" + +#include +#include + +#include +#include + +#include +#include +#include + +/*-----------------------------------------------------------------------*/ +/* Helpers */ +/*-----------------------------------------------------------------------*/ + +#define max(x, y) (((x) > (y)) ? (x) : (y)) +#define min(x, y) (((x) < (y)) ? (x) : (y)) + +/*-----------------------------------------------------------------------*/ +/* Boot */ +/*-----------------------------------------------------------------------*/ + +extern void boot_helper(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr); + +static void __attribute__((noreturn)) boot(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr) +{ + printf("Executing booted program at 0x%08x\n\n", addr); + printf("--============= \e[1mLiftoff!\e[0m ===============--\n"); + uart_sync(); +#ifdef CONFIG_CPU_HAS_INTERRUPT + irq_setmask(0); + irq_setie(0); +#endif + flush_cpu_icache(); + flush_cpu_dcache(); +#ifdef CONFIG_L2_SIZE + flush_l2_cache(); +#endif + +#if defined(CONFIG_CPU_TYPE_MOR1KX) && defined(CONFIG_CPU_VARIANT_LINUX) + /* Mainline Linux expects to have exception vector base address set to the + * base address of Linux kernel; it also expects to be run with an offset + * of 0x100. */ + mtspr(SPR_EVBAR, addr); + addr += 0x100; +#endif + + boot_helper(r1, r2, r3, addr); + while(1); +} + +enum { + ACK_TIMEOUT, + ACK_CANCELLED, + ACK_OK +}; + +/*-----------------------------------------------------------------------*/ +/* ROM Boot */ +/*-----------------------------------------------------------------------*/ + +#ifdef ROM_BOOT_ADDRESS +/* Running the application code from ROM is the fastest way to execute code + and could be interesting when the code is small enough, on large devices + where many blockrams are available or simply when the execution speed is + critical. Defining ROM_BOOT_ADDRESS in the SoC will make the BIOS jump to + it at boot. */ +void romboot(void) +{ + boot(0, 0, 0, ROM_BOOT_ADDRESS); +} +#endif + +/*-----------------------------------------------------------------------*/ +/* Serial Boot */ +/*-----------------------------------------------------------------------*/ + +static int check_ack(void) +{ + int recognized; + static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK; + + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(CONFIG_CLOCK_FREQUENCY/4); + timer0_en_write(1); + timer0_update_value_write(1); + recognized = 0; + while(timer0_value_read()) { + if(uart_read_nonblock()) { + char c; + c = uart_read(); + if((c == 'Q') || (c == '\e')) + return ACK_CANCELLED; + if(c == str[recognized]) { + recognized++; + if(recognized == SFL_MAGIC_LEN) + return ACK_OK; + } else { + if(c == str[0]) + recognized = 1; + else + recognized = 0; + } + } + timer0_update_value_write(1); + } + return ACK_TIMEOUT; +} + +static uint32_t get_uint32(unsigned char* data) +{ + return ((uint32_t) data[0] << 24) | + ((uint32_t) data[1] << 16) | + ((uint32_t) data[2] << 8) | + (uint32_t) data[3]; +} + +#define MAX_FAILED 5 + +/* Returns 1 if other boot methods should be tried */ +int serialboot(void) +{ + struct sfl_frame frame; + int failed; + static const char str[SFL_MAGIC_LEN+1] = SFL_MAGIC_REQ; + const char *c; + int ack_status; + + printf("Booting from serial...\n"); + printf("Press Q or ESC to abort boot completely.\n"); + + /* Send the serialboot "magic" request to Host */ + c = str; + while(*c) { + uart_write(*c); + c++; + } + ack_status = check_ack(); + if(ack_status == ACK_TIMEOUT) { + printf("Timeout\n"); + return 1; + } + if(ack_status == ACK_CANCELLED) { + printf("Cancelled\n"); + return 0; + } + /* Assume ACK_OK */ + + failed = 0; + while(1) { + int i; + int actualcrc; + int goodcrc; + + /* Get one Frame */ + frame.payload_length = uart_read(); + frame.crc[0] = uart_read(); + frame.crc[1] = uart_read(); + frame.cmd = uart_read(); + for(i=0;i 0) + printf("(%d bytes)", size); + printf("\n"); + return size; +} + +static void netboot_from_json(const char * filename, unsigned int ip, unsigned short tftp_port) +{ + int size; + uint8_t i; + uint8_t count; + + /* FIXME: modify/increase if too limiting */ + char json_buffer[1024]; + char json_name[32]; + char json_value[32]; + + unsigned long boot_r1 = 0; + unsigned long boot_r2 = 0; + unsigned long boot_r3 = 0; + unsigned long boot_addr = 0; + + uint8_t image_found = 0; + uint8_t boot_addr_found = 0; + + /* Read JSON file */ + size = tftp_get(ip, tftp_port, filename, json_buffer); + if (size <= 0) + return; + + /* Parse JSON file */ + jsmntok_t t[32]; + jsmn_parser p; + jsmn_init(&p); + count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); + for (i=0; i 16*1024*1024)) { + printf("Error: Invalid image length 0x%08x\n", length); + return 0; + } + + crc = MMPTR(base_address + 4); + got_crc = crc32((unsigned char *)(base_address + 8), length); + if(crc != got_crc) { + printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc); + return 0; + } + + return length; +} + +#if defined(MAIN_RAM_BASE) && defined(FLASH_BOOT_ADDRESS) +static int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned long ram_address) +{ + uint32_t length; + uint32_t offset; + + length = check_image_in_flash(flash_address); + if(length > 0) { + printf("Copying 0x%08x to 0x%08x (%d bytes)...\n", flash_address, ram_address, length); + offset = 0; + init_progression_bar(length); + while (length > 0) { + uint32_t chunk_length; + chunk_length = min(length, 0x8000); /* 32KB chunks */ + memcpy((void *) ram_address + offset, (void*) flash_address + offset + 8, chunk_length); + offset += chunk_length; + length -= chunk_length; + show_progress(offset); + } + show_progress(offset); + printf("\n"); + return 1; + } + + return 0; +} +#endif + +void flashboot(void) +{ + uint32_t length; + uint32_t result; + + printf("Booting from flash...\n"); + length = check_image_in_flash(FLASH_BOOT_ADDRESS); + if(!length) + return; + +#ifdef MAIN_RAM_BASE + /* When Main RAM is available, copy the code from the Flash and execute it + from Main RAM since faster */ + result = copy_image_from_flash_to_ram(FLASH_BOOT_ADDRESS, MAIN_RAM_BASE); + if(!result) + return; + boot(0, 0, 0, MAIN_RAM_BASE); +#else + /* When Main RAM is not available, execute the code directly from Flash (XIP). + The code starts after (a) length and (b) CRC -- both uint32_t */ + boot(0, 0, 0, (FLASH_BOOT_ADDRESS + 2 * sizeof(uint32_t))); +#endif +} + +#endif + +/*-----------------------------------------------------------------------*/ +/* SDCard Boot */ +/*-----------------------------------------------------------------------*/ + +#if defined(CSR_SPISDCARD_BASE) || defined(CSR_SDCORE_BASE) + +static int copy_file_from_sdcard_to_ram(const char * filename, unsigned long ram_address) +{ + FRESULT fr; + FATFS fs; + FIL file; + uint32_t br; + uint32_t offset; + uint32_t length; + + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return 0; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return 0; + } + + length = f_size(&file); + printf("Copying %s to 0x%08x (%d bytes)...\n", filename, ram_address, length); + init_progression_bar(length); + offset = 0; + for (;;) { + fr = f_read(&file, (void*) ram_address + offset, 0x8000, &br); + if (fr != FR_OK) { + printf("file read error.\n"); + f_close(&file); + f_mount(0, "", 0); + return 0; + } + if (br == 0) + break; + offset += br; + show_progress(offset); + } + show_progress(offset); + printf("\n"); + + f_close(&file); + f_mount(0, "", 0); + + return 1; +} + +static void sdcardboot_from_json(const char * filename) +{ + FRESULT fr; + FATFS fs; + FIL file; + + uint8_t i; + uint8_t count; + uint32_t length; + uint32_t result; + + /* FIXME: modify/increase if too limiting */ + char json_buffer[1024]; + char json_name[32]; + char json_value[32]; + + unsigned long boot_r1 = 0; + unsigned long boot_r2 = 0; + unsigned long boot_r3 = 0; + unsigned long boot_addr = 0; + + uint8_t image_found = 0; + uint8_t boot_addr_found = 0; + + /* Read JSON file */ + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return; + } + + fr = f_read(&file, json_buffer, sizeof(json_buffer), &length); + + /* Close JSON file */ + f_close(&file); + f_mount(0, "", 0); + + /* Parse JSON file */ + jsmntok_t t[32]; + jsmn_parser p; + jsmn_init(&p); + count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); + for (i=0; i +// This file is Copyright (c) 2013-2014 Sebastien Bourdeauducq +// This file is Copyright (c) 2018 Ewen McNeill +// This file is Copyright (c) 2018 Felix Held +// This file is Copyright (c) 2019 Gabriel L. Somlo +// This file is Copyright (c) 2017 Tim 'mithro' Ansell +// This file is Copyright (c) 2018 William D. Jones +// License: BSD + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sfl.h" +#include "boot.h" +#include "jsmn.h" + +#include +#include + +#include +#include + +#include +#include +#include + +/*-----------------------------------------------------------------------*/ +/* Helpers */ +/*-----------------------------------------------------------------------*/ + +#define max(x, y) (((x) > (y)) ? (x) : (y)) +#define min(x, y) (((x) < (y)) ? (x) : (y)) + +/*-----------------------------------------------------------------------*/ +/* Boot */ +/*-----------------------------------------------------------------------*/ + +extern void boot_helper(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr); + +static void __attribute__((noreturn)) boot(unsigned long r1, unsigned long r2, unsigned long r3, unsigned long addr) +{ + printf("Executing booted program at 0x%08x\n\n", addr); + printf("--============= \e[1mLiftoff!\e[0m ===============--\n"); + uart_sync(); +#ifdef CONFIG_CPU_HAS_INTERRUPT + irq_setmask(0); + irq_setie(0); +#endif + flush_cpu_icache(); + flush_cpu_dcache(); +#ifdef CONFIG_L2_SIZE + flush_l2_cache(); +#endif + +#if defined(CONFIG_CPU_TYPE_MOR1KX) && defined(CONFIG_CPU_VARIANT_LINUX) + /* Mainline Linux expects to have exception vector base address set to the + * base address of Linux kernel; it also expects to be run with an offset + * of 0x100. */ + mtspr(SPR_EVBAR, addr); + addr += 0x100; +#endif + + boot_helper(r1, r2, r3, addr); + while(1); +} + +enum { + ACK_TIMEOUT, + ACK_CANCELLED, + ACK_OK +}; + +/*-----------------------------------------------------------------------*/ +/* ROM Boot */ +/*-----------------------------------------------------------------------*/ + +#ifdef ROM_BOOT_ADDRESS +/* Running the application code from ROM is the fastest way to execute code + and could be interesting when the code is small enough, on large devices + where many blockrams are available or simply when the execution speed is + critical. Defining ROM_BOOT_ADDRESS in the SoC will make the BIOS jump to + it at boot. */ +void romboot(void) +{ + boot(0, 0, 0, ROM_BOOT_ADDRESS); +} +#endif + +/*-----------------------------------------------------------------------*/ +/* Serial Boot */ +/*-----------------------------------------------------------------------*/ + +static int check_ack(void) +{ + int recognized; + static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK; + + timer0_en_write(0); + timer0_reload_write(0); + timer0_load_write(CONFIG_CLOCK_FREQUENCY/4); + timer0_en_write(1); + timer0_update_value_write(1); + recognized = 0; + while(timer0_value_read()) { + if(uart_read_nonblock()) { + char c; + c = uart_read(); + if((c == 'Q') || (c == '\e')) + return ACK_CANCELLED; + if(c == str[recognized]) { + recognized++; + if(recognized == SFL_MAGIC_LEN) + return ACK_OK; + } else { + if(c == str[0]) + recognized = 1; + else + recognized = 0; + } + } + timer0_update_value_write(1); + } + return ACK_TIMEOUT; +} + +static uint32_t get_uint32(unsigned char* data) +{ + return ((uint32_t) data[0] << 24) | + ((uint32_t) data[1] << 16) | + ((uint32_t) data[2] << 8) | + (uint32_t) data[3]; +} + +#define MAX_FAILED 5 + +/* Returns 1 if other boot methods should be tried */ +int serialboot(void) +{ + struct sfl_frame frame; + int failed; + static const char str[SFL_MAGIC_LEN+1] = SFL_MAGIC_REQ; + const char *c; + int ack_status; + + printf("Booting from serial...\n"); + printf("Press Q or ESC to abort boot completely.\n"); + + /* Send the serialboot "magic" request to Host */ + c = str; + while(*c) { + uart_write(*c); + c++; + } + ack_status = check_ack(); + if(ack_status == ACK_TIMEOUT) { + printf("Timeout\n"); + return 1; + } + if(ack_status == ACK_CANCELLED) { + printf("Cancelled\n"); + return 0; + } + /* Assume ACK_OK */ + + failed = 0; + while(1) { + int i; + int actualcrc; + int goodcrc; + + /* Get one Frame */ + frame.payload_length = uart_read(); + frame.crc[0] = uart_read(); + frame.crc[1] = uart_read(); + frame.cmd = uart_read(); + for(i=0;i 0) + printf("(%d bytes)", size); + printf("\n"); + return size; +} + +static void netboot_from_json(const char * filename, unsigned int ip, unsigned short tftp_port) +{ + int size; + uint8_t i; + uint8_t count; + + /* FIXME: modify/increase if too limiting */ + char json_buffer[1024]; + char json_name[32]; + char json_value[32]; + + unsigned long boot_r1 = 0; + unsigned long boot_r2 = 0; + unsigned long boot_r3 = 0; + unsigned long boot_addr = 0; + + uint8_t image_found = 0; + uint8_t boot_addr_found = 0; + + /* Read JSON file */ + size = tftp_get(ip, tftp_port, filename, json_buffer); + if (size <= 0) + return; + + /* Parse JSON file */ + jsmntok_t t[32]; + jsmn_parser p; + jsmn_init(&p); + count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); + for (i=0; i 16*1024*1024)) { + printf("Error: Invalid image length 0x%08x\n", length); + return 0; + } + + crc = MMPTR(base_address + 4); + got_crc = crc32((unsigned char *)(base_address + 8), length); + if(crc != got_crc) { + printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc); + return 0; + } + + return length; +} + +#if defined(MAIN_RAM_BASE) && defined(FLASH_BOOT_ADDRESS) +static int copy_image_from_flash_to_ram(unsigned int flash_address, unsigned long ram_address) +{ + uint32_t length; + uint32_t offset; + + length = check_image_in_flash(flash_address); + if(length > 0) { + printf("Copying 0x%08x to 0x%08x (%d bytes)...\n", flash_address, ram_address, length); + offset = 0; + init_progression_bar(length); + while (length > 0) { + uint32_t chunk_length; + chunk_length = min(length, 0x8000); /* 32KB chunks */ + memcpy((void *) ram_address + offset, (void*) flash_address + offset + 8, chunk_length); + offset += chunk_length; + length -= chunk_length; + show_progress(offset); + } + show_progress(offset); + printf("\n"); + return 1; + } + + return 0; +} +#endif + +void flashboot(void) +{ + uint32_t length; + uint32_t result; + + printf("Booting from flash...\n"); + length = check_image_in_flash(FLASH_BOOT_ADDRESS); + if(!length) + return; + +#ifdef MAIN_RAM_BASE + /* When Main RAM is available, copy the code from the Flash and execute it + from Main RAM since faster */ + result = copy_image_from_flash_to_ram(FLASH_BOOT_ADDRESS, MAIN_RAM_BASE); + if(!result) + return; + boot(0, 0, 0, MAIN_RAM_BASE); +#else + /* When Main RAM is not available, execute the code directly from Flash (XIP). + The code starts after (a) length and (b) CRC -- both uint32_t */ + boot(0, 0, 0, (FLASH_BOOT_ADDRESS + 2 * sizeof(uint32_t))); +#endif +} + +#endif + +/*-----------------------------------------------------------------------*/ +/* SDCard Boot */ +/*-----------------------------------------------------------------------*/ + +#if defined(CSR_SPISDCARD_BASE) || defined(CSR_SDCORE_BASE) + +static int copy_file_from_sdcard_to_ram(const char * filename, unsigned long ram_address) +{ + FRESULT fr; + FATFS fs; + FIL file; + uint32_t br; + uint32_t offset; + uint32_t length; + + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return 0; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return 0; + } + + length = f_size(&file); + printf("Copying %s to 0x%08x (%d bytes)...\n", filename, ram_address, length); + init_progression_bar(length); + offset = 0; + for (;;) { + fr = f_read(&file, (void*) ram_address + offset, 0x8000, &br); + if (fr != FR_OK) { + printf("file read error.\n"); + f_close(&file); + f_mount(0, "", 0); + return 0; + } + if (br == 0) + break; + offset += br; + show_progress(offset); + } + show_progress(offset); + printf("\n"); + + f_close(&file); + f_mount(0, "", 0); + + return 1; +} + +static void sdcardboot_from_json(const char * filename) +{ + FRESULT fr; + FATFS fs; + FIL file; + + uint8_t i; + uint8_t count; + uint32_t length; + uint32_t result; + + /* FIXME: modify/increase if too limiting */ + char json_buffer[1024]; + char json_name[32]; + char json_value[32]; + + unsigned long boot_r1 = 0; + unsigned long boot_r2 = 0; + unsigned long boot_r3 = 0; + unsigned long boot_addr = 0; + + uint8_t image_found = 0; + uint8_t boot_addr_found = 0; + + /* Read JSON file */ + fr = f_mount(&fs, "", 1); + if (fr != FR_OK) + return; + fr = f_open(&file, filename, FA_READ); + if (fr != FR_OK) { + printf("%s file not found.\n", filename); + f_mount(0, "", 0); + return; + } + + fr = f_read(&file, json_buffer, sizeof(json_buffer), &length); + + /* Close JSON file */ + f_close(&file); + f_mount(0, "", 0); + + /* Parse JSON file */ + jsmntok_t t[32]; + jsmn_parser p; + jsmn_init(&p); + count = jsmn_parse(&p, json_buffer, strlen(json_buffer), t, sizeof(t)/sizeof(*t)); + for (i=0; i #include +#include #include "../command.h" #include "../helpers.h" @@ -423,6 +424,7 @@ define_command(mhsig, mhsig, "RAM signature hunt", MEM_CMDS); * * Dump registers */ +#define CMD_MEM_DUMPREGS 1 #ifdef CMD_MEM_DUMPREGS // Register x // versus ABI @@ -573,14 +575,15 @@ define_command(dumpregs, dumpregs, "Dump processor registers", MEM_CMDS); * * Try to boot from RAM */ - +#define CMD_MEM_RAMBOOT 1 +#ifdef CMD_MEM_RAMBOOT static void ramboot(int nb_params, char **params) { - extern void netboot(void); + extern void doRAMboot(void); char *c; - c = (char *)0x40000000; // MAIN_RAM_BASE + c = (char *)MAIN_RAM_BASE; //0x40000000 if( (*(c + 0) == 0xff) && (*(c + 1) == 0xff) && (*(c + 2) == 0xff) @@ -594,7 +597,8 @@ static void ramboot(int nb_params, char **params) printf("No program loaded to RAM?!\n"); return; } - netboot(); // Try to boot ... + doRAMboot(); // Try to boot ... } define_command(ramboot, ramboot, "Boot from RAM", MEM_CMDS); +#endif \ No newline at end of file diff --git a/helpers/__pycache__/prepare_firmware.cpython-38.pyc b/helpers/__pycache__/prepare_firmware.cpython-38.pyc index b76d492..fce41d5 100644 Binary files a/helpers/__pycache__/prepare_firmware.cpython-38.pyc and b/helpers/__pycache__/prepare_firmware.cpython-38.pyc differ diff --git a/helpers/prepare_firmware.py b/helpers/prepare_firmware.py index a9c5087..2133022 100644 --- a/helpers/prepare_firmware.py +++ b/helpers/prepare_firmware.py @@ -39,6 +39,19 @@ def copyjob(): print("Copying project firmware to target path ...") shutil.copy2(localpath + originalfilename, path2firmware + originalfilename) + originalfilename = "boot.c" + backupfilename = "boot.c.bak" + backupfilename2 = "boot.c.original" + if os.path.isfile(path2firmware + backupfilename): # Check for existing backup + print("Backup already exists") + else: # Ok, no backup. Let's create one in-place & one to our local project directory ... + print("Preparing backup first ...") + shutil.copy2(path2firmware + originalfilename, path2firmware + backupfilename) + shutil.copy2(path2firmware + originalfilename, localpath + backupfilename2) + print("Backups in-place & to local project path finished.") + print("Copying project firmware to target path ...") + shutil.copy2(localpath + originalfilename, path2firmware + originalfilename) + path2firmware = os.path.dirname(litex.soc.__file__) + "/software/bios/cmds/" originalfilename = "cmd_mem.c" backupfilename = "cmd_mem.c.bak" diff --git a/neopixelar.py b/neopixelar.py index 13fbcf2..b752f4a 100755 --- a/neopixelar.py +++ b/neopixelar.py @@ -338,15 +338,17 @@ class BaseSoC(SoCCore): # USERLED blink (on-board LED) # only w/ uart-name=crossover option: - # self.comb += platform.request("user_led_n").eq(counter[23]) # ~2Hz (?) + if kwargs["uart_name"] not in ["serial", "bridge"]: + self.comb += platform.request("user_led_n").eq(counter[23]) # ~2Hz (?) platform.add_extension(_gpios) # General LED outputs + # Adjust no. for your actual project ... max_TABLES = 3 # 1..16 max_LEDS_per_chain = 27 # 1..256 self.submodules.npe = NeoPixelEngine(n_TABLES=max_TABLES, n_LEDs=max_LEDS_per_chain) self.add_csr("npe") - for i in range(42,56+2): # Do output on J4 (14) & J5 (2) + for i in range(42,56+2): # Example: Do output on J4 (14) & J5 (2) self.comb += platform.request("gpio", i).eq(self.npe.bDataPin[i-42]) # Output data pin # Build -------------------------------------------------------------------------------------------- @@ -385,11 +387,11 @@ def main(): sdram_rate = args.sdram_rate, **soc_core_argdict(args)) - # 32MBit SPIFlash --------------------------------------------------------------------------------- - soc.mem_map["spiflash"] = 0xc0000000 + # 32MBit SPIFlash (not used currently) --------------------------------------------------------------- + # soc.mem_map["spiflash"] = 0xc0000000 # Boot at +1MB - soc.add_constant("FLASH_BOOT_ADDRESS", soc.mem_map["spiflash"] + 1024*1024) - soc.add_spi_flash(name="spiflash", mode="1x", dummy_cycles=8, clk_freq=5e6) + # soc.add_constant("FLASH_BOOT_ADDRESS", soc.mem_map["spiflash"] + 1024*1024) + # soc.add_spi_flash(name="spiflash", mode="1x", dummy_cycles=8, clk_freq=5e6) builder = Builder(soc, **builder_argdict(args)) builder.build(**trellis_argdict(args), run=args.build) # Written here to (local) build tree