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)
|
base_address = self.bus.regions["main_ram"].origin)
|
||||||
|
|
||||||
# Add Ethernet ---------------------------------------------------------------------------------
|
# 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
|
# Imports
|
||||||
from liteeth.mac import LiteEthMAC
|
from liteeth.mac import LiteEthMAC
|
||||||
|
|
||||||
|
@ -1381,6 +1381,9 @@ class LiteXSoC(SoC):
|
||||||
eth_rx_clk,
|
eth_rx_clk,
|
||||||
eth_tx_clk)
|
eth_tx_clk)
|
||||||
|
|
||||||
|
if dynamic_ip:
|
||||||
|
self.add_constant("ETH_DYNAMIC_IP")
|
||||||
|
|
||||||
# Software Debug
|
# Software Debug
|
||||||
if software_debug:
|
if software_debug:
|
||||||
self.add_constant("ETH_UDP_TX_DEBUG")
|
self.add_constant("ETH_UDP_TX_DEBUG")
|
||||||
|
|
|
@ -253,25 +253,23 @@ int serialboot(void)
|
||||||
|
|
||||||
#ifdef CSR_ETHMAC_BASE
|
#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
|
#ifndef TFTP_SERVER_PORT
|
||||||
#define TFTP_SERVER_PORT 69
|
#define TFTP_SERVER_PORT 69
|
||||||
#endif
|
#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,
|
static int copy_file_from_tftp_to_ram(unsigned int ip, unsigned short server_port,
|
||||||
const char *filename, char *buffer)
|
const char *filename, char *buffer)
|
||||||
|
@ -285,6 +283,123 @@ const char *filename, char *buffer)
|
||||||
return size;
|
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)
|
static void netboot_from_json(const char * filename, unsigned int ip, unsigned short tftp_port)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
|
@ -374,13 +489,13 @@ void netboot(void)
|
||||||
{
|
{
|
||||||
unsigned int ip;
|
unsigned int ip;
|
||||||
|
|
||||||
|
|
||||||
printf("Booting from network...\n");
|
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);
|
printf("Local IP: %d.%d.%d.%d\n", local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
|
||||||
udp_start(macadr, IPTOINT(LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4));
|
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 */
|
/* Boot from boot.json */
|
||||||
printf("Booting from boot.json...\n");
|
printf("Booting from boot.json...\n");
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef __BOOT_H
|
#ifndef __BOOT_H
|
||||||
#define __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);
|
int serialboot(void);
|
||||||
void netboot(void);
|
void netboot(void);
|
||||||
void flashboot(void);
|
void flashboot(void);
|
||||||
|
|
|
@ -4,11 +4,13 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <generated/csr.h>
|
#include <generated/csr.h>
|
||||||
|
#include <generated/soc.h>
|
||||||
|
|
||||||
#include <libliteeth/mdio.h>
|
#include <libliteeth/mdio.h>
|
||||||
|
|
||||||
#include "../command.h"
|
#include "../command.h"
|
||||||
#include "../helpers.h"
|
#include "../helpers.h"
|
||||||
|
#include "../boot.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Command "mdio_write"
|
* 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);
|
define_command(mdio_dump, mdio_dump_handler, "Dump MDIO registers", LITEETH_CMDS);
|
||||||
#endif
|
#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 char my_mac[6];
|
||||||
static unsigned int my_ip;
|
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 */
|
/* ARP cache - one entry only */
|
||||||
static unsigned char cached_mac[6];
|
static unsigned char cached_mac[6];
|
||||||
static unsigned int cached_ip;
|
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_reader_ev_pending_write(ETHMAC_EV_SRAM_READER);
|
||||||
ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
|
ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
|
||||||
|
|
||||||
for(i=0;i<6;i++)
|
udp_set_ip(ip);
|
||||||
my_mac[i] = macaddr[i];
|
udp_set_mac(macaddr);
|
||||||
my_ip = ip;
|
|
||||||
|
|
||||||
cached_ip = 0;
|
cached_ip = 0;
|
||||||
for(i=0;i<6;i++)
|
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);
|
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);
|
void udp_start(const unsigned char *macaddr, unsigned int ip);
|
||||||
int udp_arp_resolve(unsigned int ip);
|
int udp_arp_resolve(unsigned int ip);
|
||||||
void *udp_get_tx_buffer(void);
|
void *udp_get_tx_buffer(void);
|
||||||
|
|
Loading…
Reference in New Issue