diff options
| -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) | 
