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:
commit
c18ea700cc
|
@ -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")
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue