From fc6b02d0da1cfc40ebf7a2738d86bd454c671822 Mon Sep 17 00:00:00 2001 From: Aleksandra Swierkowska Date: Wed, 13 Jan 2021 18:14:50 +0100 Subject: [PATCH 1/3] libliteeth/udp: add udp_set_ip and udp_set_mac functions --- litex/soc/software/libliteeth/udp.c | 17 ++++++++++++++--- litex/soc/software/libliteeth/udp.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/litex/soc/software/libliteeth/udp.c b/litex/soc/software/libliteeth/udp.c index 9fa071901..8c34f30bd 100644 --- a/litex/soc/software/libliteeth/udp.c +++ b/litex/soc/software/libliteeth/udp.c @@ -166,6 +166,18 @@ static void send_packet(void) static unsigned char my_mac[6]; static unsigned int my_ip; +void udp_set_ip(unsigned int ip) +{ + my_ip = ip; +} + +void udp_set_mac(const unsigned char *macaddr) +{ + int i; + for(i=0;i<6;i++) + my_mac[i] = macaddr[i]; +} + /* ARP cache - one entry only */ static unsigned char cached_mac[6]; static unsigned int cached_ip; @@ -420,9 +432,8 @@ void udp_start(const unsigned char *macaddr, unsigned int ip) ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER); ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER); - for(i=0;i<6;i++) - my_mac[i] = macaddr[i]; - my_ip = ip; + udp_set_ip(ip); + udp_set_mac(macaddr); cached_ip = 0; for(i=0;i<6;i++) diff --git a/litex/soc/software/libliteeth/udp.h b/litex/soc/software/libliteeth/udp.h index 47e844b8a..5691acf0b 100644 --- a/litex/soc/software/libliteeth/udp.h +++ b/litex/soc/software/libliteeth/udp.h @@ -10,6 +10,8 @@ typedef void (*udp_callback)(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *data, unsigned int length); +void udp_set_ip(unsigned int ip); +void udp_set_mac(const unsigned char *macaddr); void udp_start(const unsigned char *macaddr, unsigned int ip); int udp_arp_resolve(unsigned int ip); void *udp_get_tx_buffer(void); From 1c8df130b459a7f59b92efa623c80fbb57ba40f2 Mon Sep 17 00:00:00 2001 From: Aleksandra Swierkowska Date: Tue, 16 Feb 2021 17:31:21 +0100 Subject: [PATCH 2/3] integration/soc.py: add parameter dynamic_ip to add_ethernet --- litex/soc/integration/soc.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/litex/soc/integration/soc.py b/litex/soc/integration/soc.py index 16db19962..ef0cbc635 100644 --- a/litex/soc/integration/soc.py +++ b/litex/soc/integration/soc.py @@ -1333,7 +1333,7 @@ class LiteXSoC(SoC): base_address = self.bus.regions["main_ram"].origin) # Add Ethernet --------------------------------------------------------------------------------- - def add_ethernet(self, name="ethmac", phy=None, phy_cd="eth", software_debug=False): + def add_ethernet(self, name="ethmac", phy=None, phy_cd="eth", dynamic_ip=False, software_debug=False): # Imports from liteeth.mac import LiteEthMAC @@ -1368,6 +1368,9 @@ class LiteXSoC(SoC): eth_rx_clk, eth_tx_clk) + if dynamic_ip: + self.add_constant("ETH_DYNAMIC_IP") + # Software Debug if software_debug: self.add_constant("ETH_UDP_TX_DEBUG") From 7abd66d710da85d5cf8de0678fd0b90b8adf3899 Mon Sep 17 00:00:00 2001 From: Aleksandra Swierkowska Date: Wed, 13 Jan 2021 18:16:27 +0100 Subject: [PATCH 3/3] bios/boot: add functions changing local and remote IP in runtime --- litex/soc/software/bios/boot.c | 155 ++++++++++++++++++--- litex/soc/software/bios/boot.h | 3 + litex/soc/software/bios/cmds/cmd_liteeth.c | 59 ++++++++ 3 files changed, 197 insertions(+), 20 deletions(-) diff --git a/litex/soc/software/bios/boot.c b/litex/soc/software/bios/boot.c index ed2174f44..a57bab3ba 100644 --- a/litex/soc/software/bios/boot.c +++ b/litex/soc/software/bios/boot.c @@ -275,25 +275,23 @@ int serialboot(void) #ifdef CSR_ETHMAC_BASE -#ifndef LOCALIP1 -#define LOCALIP1 192 -#define LOCALIP2 168 -#define LOCALIP3 1 -#define LOCALIP4 50 -#endif - -#ifndef REMOTEIP1 -#define REMOTEIP1 192 -#define REMOTEIP2 168 -#define REMOTEIP3 1 -#define REMOTEIP4 100 -#endif - #ifndef TFTP_SERVER_PORT #define TFTP_SERVER_PORT 69 #endif -static const unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00}; +static unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00}; + +#ifdef LOCALIP1 +static unsigned int local_ip[4] = {LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4}; +#else +static unsigned int local_ip[4] = {192, 168, 1, 50}; +#endif + +#ifdef REMOTEIP1 +static unsigned int remote_ip[4] = {REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4}; +#else +static unsigned int remote_ip[4] = {192, 168, 1, 100}; +#endif static int copy_file_from_tftp_to_ram(unsigned int ip, unsigned short server_port, const char *filename, char *buffer) @@ -307,6 +305,123 @@ const char *filename, char *buffer) return size; } +#ifdef ETH_DYNAMIC_IP + +static uint8_t parse_ip(const char * ip_address, unsigned int * ip_to_change) +{ + uint8_t n = 0; + uint8_t k = 0; + uint8_t i; + uint8_t size = strlen(ip_address); + unsigned int ip_to_set[4]; + char buf[3]; + + if (size < 7 || size > 15) { + printf("Error: Invalid IP address length."); + return -1; + } + + /* Extract numbers from input, check for potential errors */ + for (i = 0; i < size; i++) { + if ((ip_address[i] == '.' && k != 0) || (ip_address[i] == '\n' && i == size - 1)) { + ip_to_set[n] = atoi(buf); + n++; + k = 0; + memset(buf, '\0', sizeof(buf)); + } else if (ip_address[i] >= '0' && ip_address[i] <= '9' && k < 3) { + buf[k] = ip_address[i]; + k++; + } else { + printf("Error: Invalid IP address format. Correct format is \"X.X.X.X\"."); + return -1; + } + } + ip_to_set[n] = atoi(buf); + + /* Check if a correct number of numbers was extracted from the input*/ + if (n != 3) { + printf("Error: Invalid IP address format. Correct format is \"X.X.X.X\"."); + return -1; + } + + /* Set the extracted IP address as local or remote ip */ + for (i = 0; i <= n; i++) { + ip_to_change[i] = ip_to_set[i]; + } + return 0; +} + +void set_local_ip(const char * ip_address) +{ + if (parse_ip(ip_address, local_ip) == 0) { + udp_set_ip(IPTOINT(local_ip[0], local_ip[1], local_ip[2], local_ip[3])); + printf("Local IP: %d.%d.%d.%d", local_ip[0], local_ip[1], local_ip[2], local_ip[3]); + } +} + +void set_remote_ip(const char * ip_address) +{ + if (parse_ip(ip_address, remote_ip) == 0) { + printf("Remote IP: %d.%d.%d.%d", remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]); + } +} + +static uint8_t parse_mac_addr(const char * mac_address) +{ + uint8_t n = 0; + uint8_t k = 0; + uint8_t i; + uint8_t size = strlen(mac_address); + unsigned int mac_to_set[6]; + char buf[2]; + + if (size != 17) { + printf("Error: Invalid MAC address length."); + return -1; + } + + /* Extract numbers from input, check for potential errors */ + for (i = 0; i < size; i++) { + if ((mac_address[i] == ':' && k != 0) || (mac_address[i] == '\n' && i == size - 1)) { + mac_to_set[n] = strtol(buf, NULL, 16); + n++; + k = 0; + memset(buf, '\0', sizeof(buf)); + } else if (((mac_address[i] >= '0' && mac_address[i] <= '9') || + (mac_address[i] >= 'a' && mac_address[i] <= 'f') || + (mac_address[i] >= 'A' && mac_address[i] <= 'F')) && k < 2) { + buf[k] = mac_address[i]; + k++; + } else { + printf("Error: Invalid MAC address format. Correct format is \"XX:XX:XX:XX:XX:XX\"."); + return -1; + } + } + mac_to_set[n] = strtol(buf, NULL, 16); + + /* Check if correct number of numbers was extracted from input */ + if (n != 5) { + printf("Error: Invalid MAC address format. Correct format is \"XX:XX:XX:XX:XX:XX\"."); + return -1; + } + + /* Set the extracted MAC address as macadr */ + for (i = 0; i <= n; i++) { + macadr[i] = mac_to_set[i]; + } + return 0; +} + +void set_mac_addr(const char * mac_address) +{ + if (parse_mac_addr(mac_address) == 0) { + udp_set_mac(macadr); + printf("MAC address : %x:%x:%x:%x:%x:%x", macadr[0], macadr[1], macadr[2], macadr[3], macadr[4], macadr[5]); + } +} + +#endif + static void netboot_from_json(const char * filename, unsigned int ip, unsigned short tftp_port) { int size; @@ -396,13 +511,13 @@ void netboot(void) { unsigned int ip; - printf("Booting from network...\n"); - printf("Local IP : %d.%d.%d.%d\n", LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4); - printf("Remote IP: %d.%d.%d.%d\n", REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4); - ip = IPTOINT(REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4); - udp_start(macadr, IPTOINT(LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4)); + printf("Local IP: %d.%d.%d.%d\n", local_ip[0], local_ip[1], local_ip[2], local_ip[3]); + printf("Remote IP: %d.%d.%d.%d\n", remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]); + + ip = IPTOINT(remote_ip[0], remote_ip[1], remote_ip[2], remote_ip[3]); + udp_start(macadr, IPTOINT(local_ip[0], local_ip[1], local_ip[2], local_ip[3])); /* Boot from boot.json */ printf("Booting from boot.json...\n"); diff --git a/litex/soc/software/bios/boot.h b/litex/soc/software/bios/boot.h index 1a366b5ca..5b783fba5 100644 --- a/litex/soc/software/bios/boot.h +++ b/litex/soc/software/bios/boot.h @@ -1,6 +1,9 @@ #ifndef __BOOT_H #define __BOOT_H +void set_local_ip(const char * ip_address); +void set_remote_ip(const char * ip_address); +void set_mac_addr(const char * mac_address); int serialboot(void); void netboot(void); void flashboot(void); diff --git a/litex/soc/software/bios/cmds/cmd_liteeth.c b/litex/soc/software/bios/cmds/cmd_liteeth.c index e1f0a4e54..a8daeef09 100644 --- a/litex/soc/software/bios/cmds/cmd_liteeth.c +++ b/litex/soc/software/bios/cmds/cmd_liteeth.c @@ -4,11 +4,13 @@ #include #include +#include #include #include "../command.h" #include "../helpers.h" +#include "../boot.h" /** * Command "mdio_write" @@ -134,3 +136,60 @@ static void mdio_dump_handler(int nb_params, char **params) define_command(mdio_dump, mdio_dump_handler, "Dump MDIO registers", LITEETH_CMDS); #endif + +/** + * Command "eth_local_ip" + * + * Set local ip + * + */ +#ifdef ETH_DYNAMIC_IP +static void eth_local_ip_handler(int nb_params, char **params) +{ + if (nb_params < 1) { + printf("eth_local_ip
"); + return; + } + + set_local_ip(params[0]); +} +define_command(eth_local_ip, eth_local_ip_handler, "Set the local ip address", LITEETH_CMDS); +#endif + +/** + * Command "eth_remote_ip" + * + * Set remote ip. + * + */ +#ifdef ETH_DYNAMIC_IP +static void eth_remote_ip_handler(int nb_params, char **params) +{ + if (nb_params < 1) { + printf("eth_remote_ip
"); + return; + } + + set_remote_ip(params[0]); +} +define_command(eth_remote_ip, eth_remote_ip_handler, "Set the remote ip address", LITEETH_CMDS); +#endif + +/** + * Command "eth_mac_addr" + * + * Set mac address. + * + */ +#ifdef ETH_DYNAMIC_IP +static void eth_mac_addr_handler(int nb_params, char **params) +{ + if (nb_params < 1) { + printf("eth_mac_addr
"); + return; + } + + set_mac_addr(params[0]); +} +define_command(eth_mac_addr, eth_mac_addr_handler, "Set the mac address", LITEETH_CMDS); +#endif