diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/zpu/lib/bootconfig.c | 101 | ||||
-rw-r--r-- | firmware/zpu/lib/gdbstub2.c | 506 | ||||
-rw-r--r-- | firmware/zpu/lib/gdbstub2.h | 25 | ||||
-rw-r--r-- | firmware/zpu/lib/mdelay.c | 59 | ||||
-rw-r--r-- | firmware/zpu/lib/u2_init.c | 15 | ||||
-rw-r--r-- | firmware/zpu/usrp2/memory_map.h | 6 | ||||
-rw-r--r-- | firmware/zpu/usrp2p/memory_map.h | 6 |
7 files changed, 25 insertions, 693 deletions
diff --git a/firmware/zpu/lib/bootconfig.c b/firmware/zpu/lib/bootconfig.c deleted file mode 100644 index 93adc05c2..000000000 --- a/firmware/zpu/lib/bootconfig.c +++ /dev/null @@ -1,101 +0,0 @@ -/* -*- c -*- */ -/* - * Copyright 2009 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/>. - */ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include "bootconfig.h" -#include "bootconfig_private.h" -#include <stdint.h> -#include <stddef.h> -#include <i2c.h> -#include <quadradio/i2c_addr.h> -#include <mdelay.h> -#include <xilinx_v5_icap.h> -#include <nonstdio.h> - -eeprom_boot_info_t eeprom_shadow; - -static eeprom_boot_info_t eeprom_default = { - .magic = EEPROM_BOOT_INFO_MAGIC, - .nattempts = 1, - .next_boot.fpga_image_number = 0, - .next_boot.firmware_image_number = 0, - .default_boot.fpga_image_number = 0, - .default_boot.firmware_image_number = 0 -}; - -eeprom_boot_info_t * -_bc_get_eeprom_shadow(void) -{ - return &eeprom_shadow; -} - - -bool -_bc_write_eeprom_shadow(void) -{ - return eeprom_write(I2C_ADDR_MBOARD, BOOT_INFO_OFFSET, &eeprom_shadow, sizeof(eeprom_shadow)); -} - -void -bootconfig_init(void) -{ - if (!eeprom_read(I2C_ADDR_MBOARD, BOOT_INFO_OFFSET, &eeprom_shadow, sizeof(eeprom_shadow)) - || eeprom_shadow.magic != EEPROM_BOOT_INFO_MAGIC){ - eeprom_shadow = eeprom_default; - _bc_write_eeprom_shadow(); - } -} - -bootconfig_t -bootconfig_get_default(void) -{ - return eeprom_shadow.default_boot; -} - -bool -bootconfig_set_default(bootconfig_t bc) -{ - if (!validate_bootconfig(bc)) - return false; - - eeprom_shadow.default_boot = bc; - eeprom_shadow.next_boot = bc; - return _bc_write_eeprom_shadow(); -} - -void -bootconfig_boot(bootconfig_t bc) -{ - if (!validate_bootconfig(bc)) - return; - - eeprom_shadow.next_boot = bc; - eeprom_shadow.nattempts = 1; - _bc_write_eeprom_shadow(); - - if (1){ - puts("\nbootconfig: chaining to FPGA slot 0 bootloader"); - mdelay(100); - } - - while (1){ - // Reload fpga with code from SPI flash address 0x0. - icap_reload_fpga(0x00000000); - } -} diff --git a/firmware/zpu/lib/gdbstub2.c b/firmware/zpu/lib/gdbstub2.c deleted file mode 100644 index 4c63dfce2..000000000 --- a/firmware/zpu/lib/gdbstub2.c +++ /dev/null @@ -1,506 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 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/>. - */ - -/* - * Implement a eensy weensy part of the GDB Remote Serial Protocol - * - * See Appendix D of the GDB manual - * - * m<addr>,<length> -- read <length> bytes of memory starting at <addr> - * Reply: - * XX... XX... is memory contents in hex - * ENN ENN NN is a hex error number - * - * M<addr>,<length>:XX... -- write memory, data in hex - * Reply: - * OK for success - * ENN for an error. NN is a hex error number - * - * X<addr>,<length>:XX... -- write memory, data in binary - * Reply: - * OK for success - * ENN for an error. NN is a hex error number - * - * c<addr> -- continue. <addr> is the address to resume (goto). - * Reply: <none> - * - * \x80 New Format... - */ - -#include "gdbstub2.h" -#include "loader_parser.h" -#include "hal_uart.h" -#include <stdbool.h> -#include <stddef.h> - -#define MAX_PACKET 1024 - -/* - * Get raw character from serial port, no echo. - */ -static inline int -gdb_getc(void) -{ - return hal_uart_getc(); -} - -/* - * Put character to serial port. Raw output. - */ -static inline void -gdb_putc(int ch) -{ - hal_uart_putc(ch); -} - -// ------------------------------------------------------------------------ - -#define GDB_ESCAPE 0x7d - -static unsigned char hex_table[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' -}; - -static int -put_hex8_checksum(int ch, int checksum) -{ - unsigned char t = hex_table[(ch >> 4) & 0xf]; - checksum += t; - gdb_putc(t); - - t = hex_table[ch & 0xf]; - checksum += t; - gdb_putc(t); - return checksum; -} - -static void -put_hex8(int ch) -{ - put_hex8_checksum(ch, 0); -} - -static bool -hex4_to_bin(int ch, int *value) -{ - if ('0' <= ch && ch <= '9'){ - *value = ch - '0'; - return true; - } - if ('a' <= ch && ch <= 'f'){ - *value = ch - 'a' + 10; - return true; - } - if ('A' <= ch && ch <= 'F'){ - *value = ch - 'A' + 10; - return true; - } - *value = 0; - return false; -} - -static bool -hex8_to_bin(const unsigned char *s, int *value) -{ - int v0, v1; - if (hex4_to_bin(s[0], &v0) && hex4_to_bin(s[1], &v1)){ - *value = (v0 << 4) | v1; - return true; - } - return false; -} - -static bool -hex_to_bin_array(unsigned char *binary_data, const unsigned char *hex_data, size_t nbytes) -{ - for (size_t i = 0; i < nbytes; i++){ - int t; - if (!hex8_to_bin(&hex_data[2*i], &t)) - return false; - binary_data[i] = t; - } - return true; -} - -static bool -needs_escaping(int ch) -{ - return ch == '$' || ch == '#' || ch == GDB_ESCAPE; -} - -/* - * \brief Wait for a packet. - * \param[out] pkt_buf gets the received packet payload. - * \param[in] max_size is the maximum number of bytes to write into \p pkt_buf. - * \param[out] actual_size is the number of bytes written to \p pkt_buf. - * - * \returns true iff the payload fits and the checksum is OK. - * - * Packets have this format: - * - * $<packet-data>#<checksum> - * - * Where <packet-data> is anything and <checksum> is a two byte hex - * checksum. In <packet-data> '$', '#' and 0x7d are escaped with 0x7d. - * The checksum is computed as the modulo 256 sum of all characters - * btween the leading '$' and the trailing '#' (an 8-bit unsigned - * checksum). - */ -static bool -get_packet(unsigned char *pkt_buf, size_t max_size, size_t *actual_size) -{ - typedef enum states { - LOOKING_FOR_DOLLAR, - LOOKING_FOR_HASH, - CSUM1, - CSUM2, - } state_t; - - *actual_size = 0; - unsigned char csum[2] = {0, 0}; - state_t state = LOOKING_FOR_DOLLAR; - size_t pi = 0; - - while (1){ - int ch = gdb_getc(); - - switch (state){ - case LOOKING_FOR_DOLLAR: - if (ch == '$'){ - pi = 0; - state = LOOKING_FOR_HASH; - } - else if (ch == '#'){ // most likely missed the $ - return false; - } - break; - - case LOOKING_FOR_HASH: - if (ch == '$'){ - return false; - } - else if (ch == '#'){ - state = CSUM1; - } - else { - if (pi >= max_size) // payload too big - return false; - - if (ch == GDB_ESCAPE) - ch = gdb_getc(); - - pkt_buf[pi++] = ch; - } - break; - - case CSUM1: - csum[0] = ch; - state = CSUM2; - break; - - case CSUM2: - csum[1] = ch; - *actual_size = pi; - - // accept .. as a correct checksum - if (csum[0] == '.' && csum[1] == '.') - return true; - - int expected_checksum; - if (!hex8_to_bin(csum, &expected_checksum)) - return false; - - int checksum = 0; - for (size_t i = 0; i < pi; i++) - checksum += pkt_buf[i]; - - checksum &= 0xff; - return checksum == expected_checksum; - } - } -} - -static void -put_packet_trailer(int checksum) -{ - gdb_putc('#'); - put_hex8(checksum & 0xff); - gdb_putc('\r'); - gdb_putc('\n'); -} - -static void -put_packet(const unsigned char *pkt_buf, size_t size) -{ - gdb_putc('$'); - - int checksum = 0; - for (size_t i = 0; i < size; i++){ - int ch = pkt_buf[i]; - if (needs_escaping(ch)) - gdb_putc(GDB_ESCAPE); - gdb_putc(ch); - checksum += ch; - } - put_packet_trailer(checksum); -} - -/*! - * Read a hex number - * - * \param[inout] bufptr - pointer to pointer to buffer (updated on return) - * \param[in] end - one past end of valid data in buf - * \param[out] value - the parsed value - * - * \returns true iff a valid hex number was read from bufptr - */ -static bool -parse_number(const unsigned char **bufptr, const unsigned char *end, unsigned int *value) -{ - const unsigned char *buf = *bufptr; - unsigned int v = 0; - bool valid = false; - int nibble; - - while (buf < end && hex4_to_bin(*buf, &nibble)){ - valid = true; - v = (v << 4) | nibble; - buf++; - } - - *value = v; - *bufptr = buf; - return valid; -} - -static bool -parse_char(const unsigned char **bufptr, const unsigned char *end, unsigned char *ch) -{ - const unsigned char *buf = *bufptr; - if (buf < end){ - *ch = *buf++; - *bufptr = buf; - return true; - } - return false; -} - -static bool -expect_char(const unsigned char **bufptr, const unsigned char *end, unsigned char expected) -{ - unsigned char ch; - return parse_char(bufptr, end, &ch) && ch == expected; -} - -static bool -expect_end(const unsigned char **bufptr, const unsigned char *end) -{ - return *bufptr == end; -} - -static bool -parse_addr_length(const unsigned char **bufptr, const unsigned char *end, - unsigned int *addr, unsigned int *length) -{ - return (parse_number(bufptr, end, addr) - && expect_char(bufptr, end, ',') - && parse_number(bufptr, end, length)); -} - -static void -put_error(int error) -{ - unsigned char buf[3]; - buf[0] = 'E'; - buf[1] = hex_table[(error >> 4) & 0xf]; - buf[2] = hex_table[error & 0xf]; - - put_packet(buf, sizeof(buf)); -} - -static void -put_ok(void) -{ - const unsigned char buf[2] = "OK"; - put_packet(buf, sizeof(buf)); -} - -/* - * Read memory and send the reply. - * We do it on the fly so that our packet size is effectively unlimited - */ -static void -read_memory(unsigned int addr, unsigned int nbytes) -{ - int checksum = 0; - gdb_putc('$'); - - if ((addr & 0x3) == 0 && (nbytes & 0x3) == 0){ // word aligned - union { - unsigned int i; - unsigned char c[4]; - } u; - - unsigned int *p = (unsigned int *) addr; - unsigned int length = nbytes / 4; - - for (unsigned int i = 0; i < length; i++){ - u.i = p[i]; // do a word read - checksum = put_hex8_checksum(u.c[0], checksum); - checksum = put_hex8_checksum(u.c[1], checksum); - checksum = put_hex8_checksum(u.c[2], checksum); - checksum = put_hex8_checksum(u.c[3], checksum); - } - } - else { // byte aligned - unsigned char *p = (unsigned char *) addr; - for (unsigned int i = 0; i < nbytes; i++) - checksum = put_hex8_checksum(p[i], checksum); - } - - put_packet_trailer(checksum); -} - -static unsigned int -get_unaligned_int(const unsigned char *p) -{ - // we're bigendian - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | (p[3]); -} - -static bool -write_memory(unsigned int addr, size_t nbytes, - const unsigned char *data) -{ - if ((addr & 0x3) == 0 && (nbytes & 0x3) == 0){ // word-aligned dst - unsigned int *dst = (unsigned int *) addr; - size_t length = nbytes / 4; - for (size_t i = 0; i < length; i++){ - unsigned int t = get_unaligned_int(&data[4*i]); - dst[i] = t; // word writes - } - } - else { // non-word-aligned dst - unsigned char *dst = (unsigned char *) addr; - for (size_t i = 0; i < nbytes; i++){ - dst[i] = data[i]; - } - } - return true; -} - -void -gdbstub2_main_loop(void) -{ - unsigned char inpkt[MAX_PACKET + 24]; - unsigned char binary_data[MAX_PACKET/2] __attribute__((aligned (4))); - - hal_uart_set_mode(UART_MODE_RAW); //tell UART HAL not to map \n to \r\n - - while (1){ - size_t inpkt_len; - bool ok = get_packet(inpkt, sizeof(inpkt), &inpkt_len); - if (!ok){ - gdb_putc('-'); - continue; - } - gdb_putc('+'); - - const unsigned char *buf = inpkt; - const unsigned char *end = inpkt + inpkt_len; - unsigned char ch; - - if (!parse_char(&buf, end, &ch)){ // empty packet - put_packet(0, 0); - continue; - } - - unsigned int addr; - unsigned int length; - - switch(ch){ - case 'm': // m<addr>,<length> -- read <length> bytes starting at <addr> - if (!(parse_addr_length(&buf, end, &addr, &length) && expect_end(&buf, end))){ - put_error(1); - } - else { - read_memory(addr, length); - } - break; - - case 'M': // M<addr>,<length>:XX... -- write <length> bytes starting at <addr> - // XX... is the data in hex - if (!(parse_addr_length(&buf, end, &addr, &length) - && expect_char(&buf, end, ':') - && (end - buf) == 2 * length)){ - put_error(1); - } - else { - if (!hex_to_bin_array(binary_data, buf, length)) - put_error(2); - else if (!write_memory(addr, length, binary_data)) - put_error(3); - else - put_ok(); - } - break; - - case 'X': // X<addr>,<length>:XX... -- write <length> bytes starting at <addr> - // XX... is the data in binary - if (!(parse_addr_length(&buf, end, &addr, &length) - && expect_char(&buf, end, ':') - && (end - buf) == length)){ - put_error(1); - } - else { - if (!write_memory(addr, length, buf)) - put_error(3); - else - put_ok(); - } - break; - - case 'c': // c<addr> -- continue. <addr> is the address to resume (goto). - if (!(parse_number(&buf, end, &addr) - && expect_end(&buf, end))){ - put_error(1); - } - else { - typedef void (*fptr_t)(void); - (*(fptr_t) addr)(); // most likely no return - } - break; -/* - case 0x80: - { - unsigned char *output = binary_data; // reuse - size_t sizeof_output = sizeof(binary_data); - size_t actual_olen; - loader_parser(buf, end-buf, - output, sizeof_output, &actual_olen); - put_packet(output, actual_olen); - } - break; -*/ - default: // unknown packet type - put_packet(0, 0); - break; - } - } -} diff --git a/firmware/zpu/lib/gdbstub2.h b/firmware/zpu/lib/gdbstub2.h deleted file mode 100644 index 15cdde939..000000000 --- a/firmware/zpu/lib/gdbstub2.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 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/>. - */ - -#ifndef INCLUDED_GDBSTUB_H -#define INCLUDED_GDBSTUB_H - -void gdbstub2_main_loop(void); - -#endif /* INCLUDED_GDBSTUB_H */ - diff --git a/firmware/zpu/lib/mdelay.c b/firmware/zpu/lib/mdelay.c index 958acf3f5..8f9b14112 100644 --- a/firmware/zpu/lib/mdelay.c +++ b/firmware/zpu/lib/mdelay.c @@ -19,56 +19,13 @@ #include "mdelay.h" #include "memory_map.h" -// Delay about one millisecond. -// -// Need 33,333 cycles at 33 MHz. -// Each time around the loop is 10 cycles -// - -#define LOOPCNT(wb_div) (MASTER_CLK_RATE/(wb_div) / 10000) - -inline static void -delay_1ms(int loop_count) -{ -/* int i; - for (i = 0; i < loop_count; i++){ - asm volatile ("or r0, r0, r0\n\ - or r0, r0, r0\n\ - or r0, r0, r0\n\ - or r0, r0, r0\n\ - or r0, r0, r0\n\ - or r0, r0, r0\n\ - or r0, r0, r0\n"); +void mdelay(int ms){ + if (hwconfig_simulation_p()) return; + for(int i = 0; i < ms; i++){ + static const uint32_t num_ticks = MASTER_CLK_RATE/1000; + const uint32_t ticks_begin = router_status->time64_ticks_rb; + while((router_status->time64_ticks_rb - ticks_begin) < num_ticks){ + /*NOP*/ + } } -*/ -} - -// delay about ms milliseconds -void -mdelay(int ms) -{ - static int loop_count = -1; - - if (hwconfig_simulation_p()) - return; - - if (loop_count < 0){ - // set correct loop_count - static unsigned short lc[8] = { - 0, - LOOPCNT(1), - LOOPCNT(2), - LOOPCNT(3), - LOOPCNT(4), - LOOPCNT(5), - LOOPCNT(6), - LOOPCNT(7) - }; - - loop_count = lc[hwconfig_wishbone_divisor() & 0x7]; - } - - int i; - for (i = 0; i < ms; i++) - delay_1ms(loop_count); } diff --git a/firmware/zpu/lib/u2_init.c b/firmware/zpu/lib/u2_init.c index 191a0e816..71bd2c594 100644 --- a/firmware/zpu/lib/u2_init.c +++ b/firmware/zpu/lib/u2_init.c @@ -51,10 +51,17 @@ u2_init(void) hal_enable_ints(); // flash all leds to let us know board is alive - hal_set_leds(0x0, 0x1f); - mdelay(100); - hal_set_leds(0x1f, 0x1f); - mdelay(100); + hal_set_led_src(0x0, 0x1f); /* software ctrl */ + hal_set_leds(0x0, 0x1f); mdelay(300); + hal_set_leds(LED_E, LED_E); mdelay(300); + hal_set_leds(LED_C, LED_C); mdelay(300); + hal_set_leds(LED_A, LED_A); mdelay(300); + for (int i = 0; i < 3; i++){ //blink all + static const int blinks = LED_E | LED_C | LED_A; + hal_set_leds(0x0, 0x1f); mdelay(100); + hal_set_leds(blinks, 0x1f); mdelay(100); + } + hal_set_led_src(0x1f & ~LED_D, 0x1f); /* hardware ctrl */ hal_set_leds(LED_D, 0x1f); // Leave one on #if 0 diff --git a/firmware/zpu/usrp2/memory_map.h b/firmware/zpu/usrp2/memory_map.h index b1ca4aa6d..e728a1ddb 100644 --- a/firmware/zpu/usrp2/memory_map.h +++ b/firmware/zpu/usrp2/memory_map.h @@ -166,10 +166,10 @@ typedef struct { volatile uint32_t _padding[8]; volatile uint32_t status; volatile uint32_t hw_config; // see below - volatile uint32_t dummy[3]; + volatile uint32_t time64_secs_rb; + volatile uint32_t time64_ticks_rb; + volatile uint32_t compat_num; volatile uint32_t irqs; - volatile uint32_t pri_enc_bp_status; - volatile uint32_t cycle_count; } router_status_t; #define router_status ((router_status_t *) ROUTER_STATUS_BASE) diff --git a/firmware/zpu/usrp2p/memory_map.h b/firmware/zpu/usrp2p/memory_map.h index 85c64466d..e043bed8a 100644 --- a/firmware/zpu/usrp2p/memory_map.h +++ b/firmware/zpu/usrp2p/memory_map.h @@ -159,10 +159,10 @@ typedef struct { volatile uint32_t _padding[8]; volatile uint32_t status; volatile uint32_t hw_config; // see below - volatile uint32_t dummy[3]; + volatile uint32_t time64_secs_rb; + volatile uint32_t time64_ticks_rb; + volatile uint32_t compat_num; volatile uint32_t irqs; - volatile uint32_t pri_enc_bp_status; - volatile uint32_t cycle_count; } router_status_t; #define router_status ((router_status_t *) ROUTER_STATUS_BASE) |