summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Foster <nick@nerdnetworks.org>2011-04-22 11:28:27 -0700
committerNick Foster <nick@nerdnetworks.org>2011-04-22 11:28:27 -0700
commit361300327fceb20a5256cc9c5e5c6096cdbcd014 (patch)
treed740ba064a1e42b2057484bcc325e9c045cc1fa3
parent3dd74062fc6cfad68a62faac6669bada96f3aecf (diff)
downloaduhd-361300327fceb20a5256cc9c5e5c6096cdbcd014.tar.gz
uhd-361300327fceb20a5256cc9c5e5c6096cdbcd014.tar.bz2
uhd-361300327fceb20a5256cc9c5e5c6096cdbcd014.zip
N210: TXRX_UHD now has bootloader #ifdef'ed into it. Safe firmware now embedded into FPGA bootloader.
Also did some cleanup of unused source files and consolidated bootloader stuff into bootloader_utils.
-rw-r--r--firmware/zpu/apps/blinkenlights.c28
-rw-r--r--firmware/zpu/apps/flash_test.c67
-rw-r--r--firmware/zpu/apps/hardware_testbed.c47
-rw-r--r--firmware/zpu/apps/txrx_uhd.c21
-rw-r--r--firmware/zpu/apps/uart_flash_loader.c169
-rw-r--r--firmware/zpu/usrp2/CMakeLists.txt3
-rw-r--r--firmware/zpu/usrp2p/CMakeLists.txt7
-rw-r--r--firmware/zpu/usrp2p/bootloader/CMakeLists.txt10
-rw-r--r--firmware/zpu/usrp2p/bootloader/fpga_bootloader.c202
-rw-r--r--firmware/zpu/usrp2p/bootloader/fw_bootloader.c50
-rw-r--r--firmware/zpu/usrp2p/bootloader/icap_test.c31
-rw-r--r--firmware/zpu/usrp2p/bootloader/serial_loader_burner.c49
-rw-r--r--firmware/zpu/usrp2p/bootloader_utils.c53
-rw-r--r--firmware/zpu/usrp2p/bootloader_utils.h1
14 files changed, 74 insertions, 664 deletions
diff --git a/firmware/zpu/apps/blinkenlights.c b/firmware/zpu/apps/blinkenlights.c
deleted file mode 100644
index 30cb33a7f..000000000
--- a/firmware/zpu/apps/blinkenlights.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Ettus Research LLC
- *
- */
-
-#include "memory_map.h"
-#include <nonstdio.h>
-
-int main(int argc, char *argv[]) {
-
- uint32_t c = 0;
- uint8_t i = 0;
-
- output_regs->led_src = 0;
-
- while(1) {
- //delay(5000000);
- for(c=0;c<50000;c++) asm("NOP");
- output_regs->leds = (i++ % 2) ? 0xFF : 0x00; //blink everything on that register
- }
-
- return 0;
-}
-
-//void delay(uint32_t t) {
-// while(t-- != 0) asm("NOP");
-//}
diff --git a/firmware/zpu/apps/flash_test.c b/firmware/zpu/apps/flash_test.c
deleted file mode 100644
index 5b4569030..000000000
--- a/firmware/zpu/apps/flash_test.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Ettus Research LLC
- *
- */
-
-#include <memory_map.h>
-#include <hal_io.h>
-#include <hal_uart.h>
-#include <xilinx_s3_icap.h>
-#include <nonstdio.h>
-#include <spi_flash.h>
-#include <spi.h>
-#include <clocks.h>
-#include <string.h>
-
-//just a test to write to SPI flash and retrieve the same values.
-//uses the MOBFLEET SPI flash library
-
-void delay(uint32_t t) {
- while(t-- != 0) asm("NOP");
-}
-
-int main(int argc, char *argv[]) {
- uint16_t i, t;
- uint8_t buf[260];
- const uint8_t testdata[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
-
- hal_disable_ints(); // In case we got here via jmp 0x0
-// spi_init();
- hal_uart_init();
-// clocks_init(); //set up AD9510, enable FPGA clock @ 1x divisor
-
- puts("SPI Flash test\n");
- puts("Initializing SPI\n");
-
- spif_init();
- delay(800000);
- puts("Erasing sector 1\n");
- spi_flash_erase(0x00010000, 256);
- delay(800000);
- puts("Reading back data\n");
- spi_flash_read(0x00010000, 256, buf);
- delay(800000);
-
- t=1;
- for(i=4; i<250; i++) {
- if(buf[i] != 0xFF) t=0;
- }
-
- if(!t) puts("Data was not initialized to 0xFF. Unsuccessful erase or read\n");
- else puts("Data initialized to 0xFF, erase confirmed\n");
-
- puts("Writing test buffer\n");
- spi_flash_program(0x00010000, 16, testdata);
- //memset(buf, 0, 256);
-
- delay(800000);
- puts("Wrote data, reading back\n");
-
- spi_flash_read(0x00010000, 16, buf);
-
- if(memcmp(testdata, buf, 16)) puts("Data is not the same between read and write. Unsuccessful write or read\n");
- else puts("Successful write! Flash write correct\n");
-
- return 0;
-}
diff --git a/firmware/zpu/apps/hardware_testbed.c b/firmware/zpu/apps/hardware_testbed.c
deleted file mode 100644
index e68e68ff7..000000000
--- a/firmware/zpu/apps/hardware_testbed.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Ettus Research LLC
- *
- */
-
-#include <memory_map.h>
-#include <nonstdio.h>
-#include <hal_io.h>
-#include <xilinx_s3_icap.h>
-#include <spi_flash.h>
-//#include <spi_flash_private.h>
-#include <clocks.h>
-#include <ihex.h>
-#include <bootloader_utils.h>
-#include <string.h>
-#include <hal_uart.h>
-#include <spi.h>
-
-//so this is just an evolving file used to set up and test different bits of hardware (EEPROM, clock chip, A/D, D/A, PHY)
-void delay(uint32_t t) {
- while(t-- != 0) asm("NOP");
-}
-
-int main(int argc, char *argv[]) {
-
- hal_disable_ints();
- hal_uart_init();
- spi_init();
-
- puts("Hardware testbed. Init clocks...");
-
- clocks_init();
-
- //now, hopefully, we should be running at 100MHz instead of 50MHz, meaning our UART is twice as fast and we're talking at 230400.
-
- while(1) {
- delay(500000);
- puts("Eat at Joe's.");
- }
-
-
-
-
-
- return 0;
-}
diff --git a/firmware/zpu/apps/txrx_uhd.c b/firmware/zpu/apps/txrx_uhd.c
index 8c27618e9..7a99303bf 100644
--- a/firmware/zpu/apps/txrx_uhd.c
+++ b/firmware/zpu/apps/txrx_uhd.c
@@ -39,8 +39,8 @@
#include <string.h>
#include <stdbool.h>
-#ifdef USRP2P
-#include "u2p_init.h"
+#ifdef BOOTLOADER
+#include <bootloader_utils.h>
#endif
extern uint16_t dsp0_dst_port, err0_dst_port, dsp1_dst_port;
@@ -265,7 +265,6 @@ static void handle_inp_packet(uint32_t *buff, size_t num_lines){
handle_eth_packet(buff, num_lines);
}
-
//------------------------------------------------------------------
/*
@@ -288,15 +287,23 @@ int
main(void)
{
u2_init();
-#ifdef USRP2P
- u2p_init();
-#endif
-
+#ifdef BOOTLOADER
+ spif_init();
+ set_default_mac_addr();
+ set_default_ip_addr();
+ putstr("\nUSRP N210 UDP bootloader\n");
+#else
putstr("\nTxRx-UHD-ZPU\n");
+#endif
print_mac_addr(ethernet_mac_addr()); newline();
print_ip_addr(get_ip_addr()); newline();
printf("FPGA compatibility number: %d\n", USRP2_FPGA_COMPAT_NUM);
printf("Firmware compatibility number: %d\n", USRP2_FW_COMPAT_NUM);
+
+#ifdef BOOTLOADER
+ //load the production FPGA image or firmware if appropriate
+ do_the_bootload_thing();
+#endif
//1) register the addresses into the network stack
register_addrs(ethernet_mac_addr(), get_ip_addr());
diff --git a/firmware/zpu/apps/uart_flash_loader.c b/firmware/zpu/apps/uart_flash_loader.c
deleted file mode 100644
index 4ec89284a..000000000
--- a/firmware/zpu/apps/uart_flash_loader.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Ettus Research LLC
- *
- */
-
-//#include <stdio.h>
-#include <stdlib.h>
-#include <memory_map.h>
-#include <nonstdio.h>
-#include <hal_io.h>
-#include <hal_uart.h>
-#include <xilinx_s3_icap.h>
-#include <spi_flash.h>
-#include <spi_flash_private.h>
-//#include <clocks.h>
-#include <ihex.h>
-#include <bootloader_utils.h>
-
-//uses UART to load files to Flash in Intel HEX 16-bit format.
-//this is one example of a "safe" firmware image to be loaded by a bootloader into main RAM.
-//this CANNOT write to main RAM, since it is resident there.
-
-//Sector 0-31: Safe FPGA bootloader image
-//Sector 32-63: Production bootloader image
-//Sector 64: Production firmware image
-//Sector 127: Safe firmware image
-
-
-void uart_flash_loader(void) {
-
- char buf[256]; //input data buffer
- uint8_t ihx[32]; //ihex data buffer
- uint32_t slot_offset = PROD_FW_IMAGE_LOCATION_ADDR; //initial slot offset to program to.
- uint32_t extended_addr = 0x00000000; //extended Intel hex segment address
-
- size_t sector_size = spi_flash_log2_sector_size();
- ihex_record_t ihex_record;
- ihex_record.data = ihx;
- int i;
-
-
- //not gonna win a turing prize for my C text parsing
- while(1) {
- gets(buf);
- if(!strncmp(buf, "!SECTORSIZE", 7)) { //return the sector size in log format
- putstr("OK ");
- puthex8((uint32_t) sector_size); //err, this should probably be decimal for human readability. we do have itoa now...
- putstr("\n");
- }
- else if(!strncmp(buf, "!SETADDR", 7)) { //set start address for programming
- slot_offset = atol(&buf[8]);
- puts("OK");
-// puthex32(slot_offset);
-// putstr("\n");
- }
- else if(!strncmp(buf, "!ERASE", 6)) { //erase a sector
- uint32_t sector = atol(&buf[6]);
- uint32_t size = 2 << (sector_size-1);
- uint32_t addr = sector << sector_size;
-
- spi_flash_erase(addr, size); //we DO NOT implement write protection here. it is up to the HOST PROGRAM to not issue an ERASE unless it means it.
- //unfortunately the Flash cannot write-protect the segments that really matter, so we only use global write-protect
- //as a means of avoiding accidental writes from runaway code / garbage on the SPI bus.
- puts("OK");
- }
-//can't exactly run firmware if you're already executing out of main RAM
-/* else if(!strncmp(buf, "!RUNSFW", 7)) {
- if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) {
- puts("OK");
- spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE);
- start_program(RAM_BASE);
- } else {
- puts("NOK");
- }
- }
- else if(!strncmp(buf, "!RUNPFW", 7)) {
- if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) {
- puts("OK");
- spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES-1, (void *)RAM_BASE);
- start_program(RAM_BASE);
- } else {
- puts("NOK");
- }
- }
-*/
- else if(!strncmp(buf, "!RUNPFPGA", 8)) {
- if(is_valid_fpga_image(PROD_FPGA_IMAGE_LOCATION_ADDR)) {
- puts("OK");
- //icap_reload_fpga(PROD_FPGA_IMAGE_LOCATION_ADDR);
- } else {
- puts("NOK");
- }
- }
- else if(!strncmp(buf, "!RUNSFPGA", 8)) {
- if(is_valid_fpga_image(SAFE_FPGA_IMAGE_LOCATION_ADDR)) {
- puts("OK");
- //icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR);
- } else {
- puts("NOK");
- }
- }
- else if(!strncmp(buf, "!READ", 5)) {
- uint32_t addr = atol(&buf[5]);
- spi_flash_read(addr, 16, ihx);
- for(i=0; i < 16; i++) {
- puthex8(ihx[i]);
- }
- putstr("\n");
- }
-
- else if(!ihex_parse(buf, &ihex_record)) { //last, try to see if the input was a valid IHEX line
- switch (ihex_record.type) {
- case 0:
- spi_flash_program(ihex_record.addr + slot_offset + extended_addr, ihex_record.length, ihex_record.data);
- puts("OK");
- break;
- case 1:
- //here we would expect a CRC checking or something else to take place. for now we do nothing.
- //well, we set the extended segment addr back to 0
- extended_addr = 0;
- puts("DONE");
- break;
- case 4:
- //set the upper 16 bits of the address
- extended_addr = ((ihex_record.data[0] << 8) + ihex_record.data[1]) << 16;
- puts("OK");
- break;
- default:
- puts("NOK");
- }
- }
- else puts("NOK");
- } //while(1)
-}
-
-void delay(uint32_t t) {
- while(t-- != 0) asm("NOP");
-}
-
-int main(int argc, char *argv[]) {
- //uint8_t buf[32];
- //int i = 0;
-
- hal_disable_ints(); // In case we got here via jmp 0x0
-
-// delay(10000000);
-
- //before anything else you might want to blinkenlights just to indicate code startup to the user.
-
- hal_uart_init();
- spif_init();
-// i2c_init(); //for EEPROM
- puts("USRP2+ UART firmware loader");
-
-// puts("Debug: loading production image, 10 bytes.");
-
-// spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, 10, buf);
-// for(i=0; i < 10; i++) {
-// puthex8(buf[i]);
-// }
-
- uart_flash_loader();
-
- //shouldn't get here. should reboot.
- puts("shit happened.\n");
-
- return 0;
-}
diff --git a/firmware/zpu/usrp2/CMakeLists.txt b/firmware/zpu/usrp2/CMakeLists.txt
index 75acae750..190ea9af1 100644
--- a/firmware/zpu/usrp2/CMakeLists.txt
+++ b/firmware/zpu/usrp2/CMakeLists.txt
@@ -34,6 +34,3 @@ ADD_EXECUTABLE(usrp2_txrx_uhd.elf ${CMAKE_SOURCE_DIR}/apps/txrx_uhd.c)
TARGET_LINK_LIBRARIES(usrp2_txrx_uhd.elf libusrp2fw)
GEN_OUTPUTS(usrp2_txrx_uhd.elf)
-ADD_EXECUTABLE(usrp2_blinkenlights.elf ${CMAKE_SOURCE_DIR}/apps/blinkenlights.c)
-TARGET_LINK_LIBRARIES(usrp2_blinkenlights.elf libusrp2fw)
-GEN_OUTPUTS(usrp2_blinkenlights.elf)
diff --git a/firmware/zpu/usrp2p/CMakeLists.txt b/firmware/zpu/usrp2p/CMakeLists.txt
index c7ab9abdb..976dccb9a 100644
--- a/firmware/zpu/usrp2p/CMakeLists.txt
+++ b/firmware/zpu/usrp2p/CMakeLists.txt
@@ -42,10 +42,3 @@ ADD_EXECUTABLE(usrp2p_txrx_uhd.elf ${CMAKE_SOURCE_DIR}/apps/txrx_uhd.c)
TARGET_LINK_LIBRARIES(usrp2p_txrx_uhd.elf libusrp2pfw)
GEN_OUTPUTS(usrp2p_txrx_uhd.elf)
-ADD_EXECUTABLE(usrp2p_blinkenlights.elf ${CMAKE_SOURCE_DIR}/apps/blinkenlights.c)
-TARGET_LINK_LIBRARIES(usrp2p_blinkenlights.elf libusrp2pfw)
-GEN_OUTPUTS(usrp2p_blinkenlights.elf)
-
-ADD_EXECUTABLE(usrp2p_uart_flash_loader.elf ${CMAKE_SOURCE_DIR}/apps/uart_flash_loader.c)
-TARGET_LINK_LIBRARIES(usrp2p_uart_flash_loader.elf libusrp2pfw)
-GEN_OUTPUTS(usrp2p_uart_flash_loader.elf)
diff --git a/firmware/zpu/usrp2p/bootloader/CMakeLists.txt b/firmware/zpu/usrp2p/bootloader/CMakeLists.txt
index 51e06ff54..07f234302 100644
--- a/firmware/zpu/usrp2p/bootloader/CMakeLists.txt
+++ b/firmware/zpu/usrp2p/bootloader/CMakeLists.txt
@@ -33,8 +33,10 @@ MACRO(GEN_RMI target)
ENDMACRO(GEN_RMI)
########################################################################
-ADD_EXECUTABLE(udp_bootloader.elf udp_bootloader.c)
-TARGET_LINK_LIBRARIES(udp_bootloader.elf libusrp2pfw)
+ADD_EXECUTABLE(bootloader.elf ${CMAKE_SOURCE_DIR}/apps/txrx_uhd.c)
+ADD_DEFINITIONS(-DUSRP2P)
+ADD_DEFINITIONS(-DBOOTLOADER)
+TARGET_LINK_LIBRARIES(bootloader.elf libusrp2pfw)
SET(GEN_OUTPUTS_BIN_SIZE 0x3fff)
-GEN_OUTPUTS(udp_bootloader.elf)
-GEN_RMI(udp_bootloader.bin)
+GEN_OUTPUTS(bootloader.elf)
+GEN_RMI(bootloader.bin)
diff --git a/firmware/zpu/usrp2p/bootloader/fpga_bootloader.c b/firmware/zpu/usrp2p/bootloader/fpga_bootloader.c
deleted file mode 100644
index f5a71a8bb..000000000
--- a/firmware/zpu/usrp2p/bootloader/fpga_bootloader.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/* -*- c -*- */
-/*
- * Copyright 2009-2011 Ettus Research LLC
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This code is bootloader f/w for the slot 0 fpga image. It's job is
- * to figure out which fpga image should be loaded, and then to load
- * that image from the SPI flash. (FIXME handle retries, errors,
- * etc.)
- *
- * If the center button is down during boot, it loads firwmare
- * from 0:0 instead of its normal action.
- */
-
-#include <stdlib.h>
-#include <hal_io.h>
-#include <nonstdio.h>
-#include <mdelay.h>
-#include <quadradio/flashdir.h>
-#include <xilinx_v5_icap.h>
-#include <bootconfig.h>
-#include <bootconfig_private.h>
-#include <spi_flash.h>
-#include <string.h>
-#include <bootloader_utils.h>
-#include <hal_interrupts.h>
-
-#define VERBOSE 1
-
-#define OUR_FPGA_IMAGE_NUMBER 0 // this code only runs in slot 0
-
-void hal_uart_init(void);
-void spif_init(void);
-void i2c_init(void);
-void bootconfig_init(void);
-
-void pic_interrupt_handler() __attribute__ ((interrupt_handler));
-
-void pic_interrupt_handler()
-{
- // nop stub
-}
-
-static int
-flash_addr_of_fpga_slot(unsigned int fpga_slot)
-{
- const struct flashdir *fd = get_flashdir();
- return fd->slot[fpga_slot + fd->fpga_slot0].start << spi_flash_log2_sector_size();
-}
-
-
-/*
- * If the first 256 bytes of the image contain the string of bytes,
- * ff ff ff ff aa 99 55 66, we consider it a likely bitstream.
- */
-static bool
-looks_like_a_bitstream(unsigned int fpga_slot)
-{
- unsigned char buf[256];
- static const unsigned char pattern[] = {
- 0xff, 0xff, 0xff, 0xff, 0xaa, 0x99, 0x55, 0x66
- };
-
- // Read the first 256 bytes of the bitstream
- spi_flash_read(flash_addr_of_fpga_slot(fpga_slot), sizeof(buf), buf);
-
- for (int i = 0; i <= sizeof(buf) - sizeof(pattern); i++)
- if (memcmp(pattern, &buf[i], sizeof(pattern)) == 0)
- return true;
-
- return false;
-}
-
-static bool
-plausible_bootconfig(bootconfig_t bc)
-{
- // Are the fields in range?
- if (!validate_bootconfig(bc))
- return false;
-
- if (!looks_like_a_bitstream(map_fpga_image_number_to_fpga_slot(bc.fpga_image_number)))
- return false;
-
- return true;
-}
-
-// Attempt to boot the fpga image specified in next_boot
-static void
-initial_boot_attempt(eeprom_boot_info_t *ee)
-{
- if (ee->next_boot.fpga_image_number == OUR_FPGA_IMAGE_NUMBER){
- load_firmware();
- return;
- }
-
- ee->nattempts = 1;
- _bc_write_eeprom_shadow();
-
- unsigned int target_slot =
- map_fpga_image_number_to_fpga_slot(ee->next_boot.fpga_image_number);
- int flash_addr = flash_addr_of_fpga_slot(target_slot);
-
- putstr("fpga_bootloader: chaining to ");
- puthex4(ee->next_boot.fpga_image_number);
- putchar(':');
- puthex4(ee->next_boot.firmware_image_number);
- newline();
- mdelay(100);
-
- while (1){
- icap_reload_fpga(flash_addr);
- }
-}
-
-int
-main(int argc, char **argv)
-{
- hal_disable_ints(); // In case we got here via jmp 0x0
- hal_uart_init();
- i2c_init();
- bootconfig_init(); // Must come after i2c_init.
- spif_init(); // Needed for get_flashdir.
-
- sr_leds->leds = 0xAAAA;
-
- putstr("\n\n>>> fpga_bootloader <<<\n");
-
- putstr("\nBOOTSTS ");
- int bootsts = icap_read_config_reg(rBOOTSTS);
- puthex32_nl(bootsts);
- putstr("STAT ");
- int stat = icap_read_config_reg(rSTAT);
- puthex32_nl(stat);
-
- bool fallback =
- ((bootsts & (BOOTSTS_VALID_0 | BOOTSTS_FALLBACK_0))
- == (BOOTSTS_VALID_0 | BOOTSTS_FALLBACK_0));
-
- if (fallback){
- puts("FALLBACK_0 is set");
- // FIXME handle fallback condition.
- }
-
- const struct flashdir *fd = get_flashdir();
- if (fd == 0)
- abort();
-
- eeprom_boot_info_t *ee = _bc_get_eeprom_shadow();
-
- if (VERBOSE){
- putstr("nattempts: ");
- puthex8_nl(ee->nattempts);
- }
-
- mdelay(500); // wait for low-pass on switches
- putstr("switches: "); puthex32_nl(readback->switches);
-
- bool center_btn_down = (readback->switches & BTN_CENTER) != 0;
- if (center_btn_down){
- putstr("Center button is down!\n");
- // Force boot of image 0:0
- ee->next_boot = make_bootconfig(0, 0);
- }
-
- // if next_boot is valid, try it
- if (plausible_bootconfig(ee->next_boot))
- initial_boot_attempt(ee); // no return
-
- // if default_boot is valid, try it
- if (plausible_bootconfig(ee->default_boot)){
- ee->next_boot = ee->default_boot;
- initial_boot_attempt(ee); // no return
- }
-
- // If we're here, we're in trouble. Try all of them...
- for (int i = 0; i < 4; i++){
- bootconfig_t bc = make_bootconfig(i, 0);
- if (plausible_bootconfig(bc)){
- ee->next_boot = bc;
- initial_boot_attempt(ee); // no return
- }
- }
-
- // FIXME, try to find something we can load
- puts("\n!!! Failed to find a valid FPGA bitstream!\n\n");
-
- return 0;
-}
diff --git a/firmware/zpu/usrp2p/bootloader/fw_bootloader.c b/firmware/zpu/usrp2p/bootloader/fw_bootloader.c
deleted file mode 100644
index de561cf22..000000000
--- a/firmware/zpu/usrp2p/bootloader/fw_bootloader.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* -*- c -*- */
-/*
- * Copyright 2009-2011 Ettus Research LLC
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <memory_map.h>
-#include <nonstdio.h>
-#include <stdlib.h>
-#include <bootconfig.h>
-#include <bootconfig_private.h>
-#include <bootloader_utils.h>
-#include <hal_interrupts.h>
-
-
-void hal_uart_init(void);
-void spif_init(void);
-void i2c_init(void);
-void bootconfig_init(void);
-
-void pic_interrupt_handler() __attribute__ ((interrupt_handler));
-
-void pic_interrupt_handler()
-{
- // nop stub
-}
-
-int
-main(int argc, char **argv)
-{
- hal_disable_ints(); // In case we got here via jmp 0x0
- hal_uart_init();
- i2c_init();
- bootconfig_init(); // Must come after i2c_init.
- spif_init(); // Needed for get_flashdir.
-
- load_firmware();
-}
diff --git a/firmware/zpu/usrp2p/bootloader/icap_test.c b/firmware/zpu/usrp2p/bootloader/icap_test.c
deleted file mode 100644
index 5feb9d014..000000000
--- a/firmware/zpu/usrp2p/bootloader/icap_test.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2010 Ettus Research LLC
- *
- */
-
-#include <memory_map.h>
-#include <hal_io.h>
-#include <xilinx_s3_icap.h>
-#include <nonstdio.h>
-
-void delay(uint32_t t) {
- while(t-- != 0) asm("NOP");
-}
-
-
-int main(int argc, char *argv[]) {
- pic_init();
- hal_uart_init();
- puts("\nStarting delay...\n");
-
- output_regs->leds = 0xFF;
- delay(4000000);
- output_regs->leds = 0x00;
- delay(4000000);
-
- puts("Rebooting FPGA to 0x00000000\n");
- icap_reload_fpga((uint32_t)0x00000000);
-
- return 0;
-}
diff --git a/firmware/zpu/usrp2p/bootloader/serial_loader_burner.c b/firmware/zpu/usrp2p/bootloader/serial_loader_burner.c
deleted file mode 100644
index 6d5d135ab..000000000
--- a/firmware/zpu/usrp2p/bootloader/serial_loader_burner.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2009-2011 Ettus Research LLC
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <hal_io.h>
-#include <nonstdio.h>
-#include <mdelay.h>
-#include <gdbstub2.h>
-
-void hal_uart_init(void);
-void spif_init(void);
-
-void pic_interrupt_handler() __attribute__ ((interrupt_handler));
-
-void pic_interrupt_handler()
-{
- // nop stub
-}
-
-int
-main(int argc, char **argv)
-{
- hal_uart_init();
- spif_init();
-
- sr_leds->leds = 0;
- mdelay(100);
- sr_leds->leds = ~0;
- mdelay(100);
- sr_leds->leds = 0;
-
- puts("\n\n>>> stage1: serial_loader_burner <<<");
-
- gdbstub2_main_loop();
-}
diff --git a/firmware/zpu/usrp2p/bootloader_utils.c b/firmware/zpu/usrp2p/bootloader_utils.c
index 371c518a7..15e21f054 100644
--- a/firmware/zpu/usrp2p/bootloader_utils.c
+++ b/firmware/zpu/usrp2p/bootloader_utils.c
@@ -10,8 +10,13 @@
#include <string.h>
#include <bootloader_utils.h>
#include <spi_flash.h>
+#include <i2c.h>
#include <memory_map.h>
#include <nonstdio.h>
+#include <xilinx_s3_icap.h>
+#include <mdelay.h>
+
+#define BUTTON_PUSHED ((router_status->irqs & PIC_BUTTON) ? 0 : 1)
int is_valid_fpga_image(uint32_t addr) {
// printf("is_valid_fpga_image(): starting with addr=%x...\n", addr);
@@ -46,3 +51,51 @@ void start_program(void)
//all this does is tap that register
*((volatile uint32_t *) SR_ADDR_BLDRDONE) = 1;
}
+
+void do_the_bootload_thing(void) {
+ bool production_image = find_safe_booted_flag();
+ set_safe_booted_flag(0); //haven't booted yet
+
+ if(BUTTON_PUSHED) { //see memory_map.h
+ puts("Starting USRP2+ in safe mode. Loading safe firmware.");
+ return;
+ }
+
+ if(!production_image) {
+ puts("Checking for valid production FPGA image...");
+ if(is_valid_fpga_image(PROD_FPGA_IMAGE_LOCATION_ADDR)) {
+ puts("Valid production FPGA image found. Attempting to boot.");
+ set_safe_booted_flag(1);
+ mdelay(300); //so serial output can finish
+ icap_reload_fpga(PROD_FPGA_IMAGE_LOCATION_ADDR);
+ }
+ puts("No valid production FPGA image found.\nFalling through to built-in firmware.");
+ return;
+ }
+ if(is_valid_fw_image(PROD_FW_IMAGE_LOCATION_ADDR)) {
+ puts("Valid production firmware found. Loading...");
+ spi_flash_read(PROD_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE);
+ puts("Finished loading. Starting image.");
+ mdelay(300);
+ start_program();
+ puts("ERROR: Return from main program! This should never happen!");
+ //if this happens, though, the safest thing to do is reboot the whole FPGA and start over.
+ mdelay(300);
+ icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR);
+ return;
+ }
+ puts("No valid production firmware found. Falling through to built-in firmware.");
+ /*
+ if(is_valid_fw_image(SAFE_FW_IMAGE_LOCATION_ADDR)) {
+ spi_flash_read(SAFE_FW_IMAGE_LOCATION_ADDR, FW_IMAGE_SIZE_BYTES, (void *)RAM_BASE);
+ puts("Finished loading. Starting image.");
+ mdelay(300);
+ start_program();
+ puts("ERROR: return from main program! This should never happen!");
+ mdelay(300);
+ icap_reload_fpga(SAFE_FPGA_IMAGE_LOCATION_ADDR);
+ return;
+ }
+ puts("ERROR: no safe firmware image available. Falling through to built-in firmware.");
+ */
+}
diff --git a/firmware/zpu/usrp2p/bootloader_utils.h b/firmware/zpu/usrp2p/bootloader_utils.h
index 0f49ae6cd..d70299b88 100644
--- a/firmware/zpu/usrp2p/bootloader_utils.h
+++ b/firmware/zpu/usrp2p/bootloader_utils.h
@@ -20,3 +20,4 @@
int is_valid_fpga_image(uint32_t addr);
int is_valid_fw_image(uint32_t addr);
void start_program(void);
+void do_the_bootload_thing(void);