Merge pull request #822 from antmicro/bios-dynamic-ip

software/bios: add an option to change ip and mac address in runtime
This commit is contained in:
enjoy-digital 2021-02-24 09:27:48 +01:00 committed by GitHub
commit c18ea700cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 217 additions and 24 deletions

View File

@ -1346,7 +1346,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
@ -1381,6 +1381,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")

View File

@ -253,25 +253,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)
@ -285,6 +283,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;
@ -374,13 +489,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");

View File

@ -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);

View File

@ -4,11 +4,13 @@
#include <stdlib.h>
#include <generated/csr.h>
#include <generated/soc.h>
#include <libliteeth/mdio.h>
#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 <address>");
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 <address>");
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 <address>");
return;
}
set_mac_addr(params[0]);
}
define_command(eth_mac_addr, eth_mac_addr_handler, "Set the mac address", LITEETH_CMDS);
#endif

View File

@ -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++)

View File

@ -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);