aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-09-30 13:22:36 +0100
committerMatt Fleming <matt.fleming@intel.com>2013-09-30 13:33:26 +0100
commit47179ebc03dcb3177312d97cd912605704c40686 (patch)
treee766d15f3153fcabfccbb5e4a6e318d6c7c50478
parent3e86c0e35b96fef58dbfbb96e3ef509ea4047d2e (diff)
parent2fe3a7bdd20d6fada21bd455a902c2b02f46a02d (diff)
downloadsyslinux-47179ebc03dcb3177312d97cd912605704c40686.tar.gz
Merge branch 'elflink-pxe-fixes-for-mfleming-2' of git://github.com/geneC/syslinux into firmware
Pull various network stack fixes from Gene Cumm and adapt to the 6.xx core_udp_* API, * 'elflink-pxe-fixes-for-mfleming-2' of git://github.com/geneC/syslinux: PXE ISR: Force polling on select hardware WORKAROUND core/lwip: Fix NULL pointer check PXE: use ddprintf macro com32: Define ddprintf() macro PXELINUX: specify PXE/lwIP undiif: show thread of execution on UNDIIF_ID_DEBUG core: dprintf() the banner. PXELINUX: Use sendto() instead of connect()/send()/disconnect() core: make mbox_post()/__sem_down_slow() check if valid core: mbox/semaphore NULL checks core/lwip/undi: Improve UNDIIF_ID_DEBUG messages Conflicts: core/fs/pxe/pxe.c core/fs/pxe/tftp.c core/init.c
-rw-r--r--com32/include/dprintf.h3
-rw-r--r--core/bios.c2
-rw-r--r--core/fs/pxe/bios.c24
-rw-r--r--core/fs/pxe/core.c60
-rw-r--r--core/fs/pxe/isr.c24
-rw-r--r--core/fs/pxe/pxe.c6
-rw-r--r--core/fs/pxe/tftp.c13
-rw-r--r--core/include/mbox.h5
-rw-r--r--core/include/net.h3
-rw-r--r--core/include/thread.h5
-rw-r--r--core/legacynet/core.c37
-rw-r--r--core/lwip/src/arch/sys_arch.c7
-rw-r--r--core/lwip/src/netif/undiif.c27
-rw-r--r--core/macros.inc5
-rw-r--r--core/pxelinux.asm5
-rw-r--r--core/thread/mbox.c22
-rw-r--r--core/thread/semaphore.c28
-rw-r--r--efi/udp.c85
18 files changed, 292 insertions, 69 deletions
diff --git a/com32/include/dprintf.h b/com32/include/dprintf.h
index ef23282b..b3f1b46b 100644
--- a/com32/include/dprintf.h
+++ b/com32/include/dprintf.h
@@ -18,9 +18,11 @@
# ifdef DEBUG_STDIO
# define dprintf printf
# define vdprintf vprintf
+# define ddprintf dprintf
# else
void dprintf(const char *, ...);
void vdprintf(const char *, va_list);
+# define ddprintf(...) { printf(__VA_ARGS__); dprintf(__VA_ARGS__); }
# endif
#else
@@ -31,6 +33,7 @@ void vdprintf(const char *, va_list);
#define vdprintf(fmt, ap) \
if (syslinux_debug_enabled) \
vprintf(fmt, ap)
+#define ddprintf printf
#endif /* CORE_DEBUG */
diff --git a/core/bios.c b/core/bios.c
index 9e911947..25e857b9 100644
--- a/core/bios.c
+++ b/core/bios.c
@@ -642,6 +642,8 @@ void bios_init(void)
syslinux_memscan_add(&bios_memscan);
mem_init();
+ dprintf("%s%s", syslinux_banner, copyright_str);
+
/* CPU-dependent initialization and related checks. */
check_escapes();
diff --git a/core/fs/pxe/bios.c b/core/fs/pxe/bios.c
index c16b7c08..e3d9adc8 100644
--- a/core/fs/pxe/bios.c
+++ b/core/fs/pxe/bios.c
@@ -179,13 +179,13 @@ int pxe_init(bool quiet)
/* Found nothing at all !! */
if (!quiet)
- printf("No !PXE or PXENV+ API found; we're dead...\n");
+ ddprintf("No !PXE or PXENV+ API found; we're dead...\n");
return -1;
have_pxenv:
APIVer = pxenv->version;
if (!quiet)
- printf("Found PXENV+ structure\nPXE API version is %04x\n", APIVer);
+ ddprintf("Found PXENV+ structure\nPXE API version is %04x\n", APIVer);
/* if the API version number is 0x0201 or higher, use the !PXE structure */
if (APIVer >= 0x201) {
@@ -223,10 +223,10 @@ int pxe_init(bool quiet)
have_entrypoint:
if (!quiet) {
- printf("%s entry point found (we hope) at %04X:%04X via plan %c\n",
+ ddprintf("%s entry point found (we hope) at %04X:%04X via plan %c\n",
type, PXEEntry.seg, PXEEntry.offs, plan);
- printf("UNDI code segment at %04X len %04X\n", code_seg, code_len);
- printf("UNDI data segment at %04X len %04X\n", data_seg, data_len);
+ ddprintf("UNDI code segment at %04X len %04X\n", code_seg, code_len);
+ ddprintf("UNDI data segment at %04X len %04X\n", data_seg, data_len);
}
syslinux_memscan_new(pxelinux_scan_memory);
@@ -273,7 +273,7 @@ static int pxe_get_cached_info(int type, void *buf, size_t bufsiz)
{
int err;
static __lowmem struct s_PXENV_GET_CACHED_INFO get_cached_info;
- printf(" %02x", type);
+ ddprintf(" %02x", type);
memset(&get_cached_info, 0, sizeof get_cached_info);
get_cached_info.PacketType = type;
@@ -281,7 +281,7 @@ static int pxe_get_cached_info(int type, void *buf, size_t bufsiz)
get_cached_info.Buffer = FAR_PTR(buf);
err = pxe_call(PXENV_GET_CACHED_INFO, &get_cached_info);
if (err) {
- printf("PXE API call failed, error %04x\n", err);
+ ddprintf("PXE API call failed, error %04x\n", err);
kaboom();
}
@@ -339,7 +339,7 @@ __export void unload_pxe(uint16_t flags)
memset(&unload_call, 0, sizeof unload_call);
err = pxe_call(api, &unload_call);
if (err || unload_call.Status != PXENV_STATUS_SUCCESS) {
- printf("PXE unload API call %04x failed: 0x%x\n",
+ ddprintf("PXE unload API call %04x failed: 0x%x\n",
api, unload_call.Status);
goto cant_free;
}
@@ -367,7 +367,7 @@ __export void unload_pxe(uint16_t flags)
*(uint32_t *)(4 * 0x1a), int_addr);
cant_free:
- printf("Failed to free base memory error %04x-%08x (%d/%dK)\n",
+ ddprintf("Failed to free base memory error %04x-%08x (%d/%dK)\n",
api, *(uint32_t *)(4 * 0x1a), bios_fbm(), real_base_mem);
return;
}
@@ -380,7 +380,7 @@ void net_parse_dhcp(void)
bp = lmalloc(dhcp_max_packet);
if (!bp) {
- printf("Out of low memory\n");
+ ddprintf("Out of low memory\n");
kaboom();
}
@@ -389,7 +389,7 @@ void net_parse_dhcp(void)
/*
* Get the DHCP client identifiers (query info 1)
*/
- printf("Getting cached packet ");
+ ddprintf("Getting cached packet ");
pkt_len = pxe_get_cached_info(1, bp, dhcp_max_packet);
parse_dhcp(bp, pkt_len);
/*
@@ -424,7 +424,7 @@ void net_parse_dhcp(void)
*/
pkt_len = pxe_get_cached_info(3, bp, dhcp_max_packet);
parse_dhcp(bp, pkt_len);
- printf("\n");
+ ddprintf("\n");
lfree(bp);
}
diff --git a/core/fs/pxe/core.c b/core/fs/pxe/core.c
index e6bbee9b..a43ac465 100644
--- a/core/fs/pxe/core.c
+++ b/core/fs/pxe/core.c
@@ -6,6 +6,8 @@
#include <net.h>
#include "pxe.h"
+#include <dprintf.h>
+
const struct url_scheme url_schemes[] = {
{ "tftp", tftp_open, 0 },
{ "http", http_open, O_DIRECTORY },
@@ -32,7 +34,7 @@ int core_udp_open(struct pxe_pvt_inode *socket)
priv->conn->recv_timeout = 15; /* A 15 ms recv timeout... */
err = netconn_bind(priv->conn, NULL, 0);
if (err) {
- printf("netconn_bind error %d\n", err);
+ ddprintf("netconn_bind error %d\n", err);
return -1;
}
@@ -67,6 +69,7 @@ void core_udp_connect(struct pxe_pvt_inode *socket, uint32_t ip,
struct net_private_lwip *priv = &socket->net.lwip;
struct ip_addr addr;
+ dprintf("net_core_connect: %08X %04X\n", ntohl(ip), port);
addr.addr = ip;
netconn_connect(priv->conn, &addr, port);
}
@@ -138,13 +141,13 @@ void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len)
nbuf = netbuf_new();
if (!nbuf) {
- printf("netbuf allocation error\n");
+ ddprintf("netbuf allocation error\n");
return;
}
pbuf = netbuf_alloc(nbuf, len);
if (!pbuf) {
- printf("pbuf allocation error\n");
+ ddprintf("pbuf allocation error\n");
goto out;
}
@@ -152,7 +155,52 @@ void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len)
err = netconn_send(conn, nbuf);
if (err) {
- printf("netconn_send error %d\n", err);
+ ddprintf("netconn_send error %d\n", err);
+ goto out;
+ }
+
+out:
+ netbuf_delete(nbuf);
+}
+
+ /**
+ * Send a UDP packet to a destination
+ *
+ * @param:socket, the open socket
+ * @param:data, data buffer to send
+ * @param:len, size of data bufer
+ * @param:ip, the ip address
+ * @param:port, the port number, host-byte order
+ */
+void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data,
+ size_t len, uint32_t ip, uint16_t port)
+{
+ struct netconn *conn = socket->net.lwip.conn;
+ struct ip_addr addr;
+ struct netbuf *nbuf;
+ void *pbuf;
+ int err;
+
+ nbuf = netbuf_new();
+ if (!nbuf) {
+ ddprintf("netbuf allocation error\n");
+ return;
+ }
+
+ pbuf = netbuf_alloc(nbuf, len);
+ if (!pbuf) {
+ ddprintf("pbuf allocation error\n");
+ goto out;
+ }
+
+ memcpy(pbuf, data, len);
+
+ dprintf("core_udp_sendto: %08X %04X\n", ntohl(ip), port);
+ addr.addr = ip;
+
+ err = netconn_sendto(conn, nbuf, &addr, port);
+ if (err) {
+ ddprintf("netconn_sendto error %d\n", err);
goto out;
}
@@ -176,7 +224,7 @@ void net_core_init(void)
/* Start up the undi driver for lwip */
err = undiif_start(IPInfo.myip, IPInfo.netmask, IPInfo.gateway);
if (err) {
- printf("undiif driver failed to start: %d\n", err);
+ ddprintf("undiif driver failed to start: %d\n", err);
kaboom();
}
@@ -192,7 +240,7 @@ void probe_undi(void)
pxe_call(PXENV_UNDI_GET_INFORMATION, &pxe_undi_info);
pxe_call(PXENV_UNDI_GET_IFACE_INFO, &pxe_undi_iface);
- printf("UNDI: baseio %04x int %d MTU %d type %d \"%s\" flags 0x%x\n",
+ ddprintf("UNDI: baseio %04x int %d MTU %d type %d \"%s\" flags 0x%x\n",
pxe_undi_info.BaseIo, pxe_undi_info.IntNumber,
pxe_undi_info.MaxTranUnit, pxe_undi_info.HwType,
pxe_undi_iface.IfaceType, pxe_undi_iface.ServiceFlags);
diff --git a/core/fs/pxe/isr.c b/core/fs/pxe/isr.c
index 069fefd5..d0a0bf90 100644
--- a/core/fs/pxe/isr.c
+++ b/core/fs/pxe/isr.c
@@ -18,6 +18,14 @@ static DECLARE_INIT_SEMAPHORE(pxe_receive_thread_sem, 0);
static DECLARE_INIT_SEMAPHORE(pxe_poll_thread_sem, 0);
static struct thread *pxe_thread, *poll_thread;
+#ifndef PXE_POLL_FORCE
+# define PXE_POLL_FORCE 0
+#endif
+
+#ifndef PXE_POLL_BY_MODEL
+# define PXE_POLL_BY_MODEL 1
+#endif
+
/*
* Note: this *must* be called with interrupts enabled.
*/
@@ -73,7 +81,7 @@ static bool install_irq_vector(uint8_t irq, void (*isr)(void), far_ptr_t *old)
if (!ok)
*entry = *old; /* Restore the old vector */
- printf("UNDI: IRQ %d(0x%02x): %04x:%04x -> %04x:%04x\n", irq, vec,
+ ddprintf("UNDI: IRQ %d(0x%02x): %04x:%04x -> %04x:%04x\n", irq, vec,
old->seg, old->offs, entry->seg, entry->offs);
return ok;
@@ -251,8 +259,20 @@ void pxe_start_isr(void)
poll_thread = start_thread("pxe poll", 4096, POLL_THREAD_PRIORITY,
pxe_poll_thread, NULL);
- if (!irq || !(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ))
+ if (!irq || !(pxe_undi_iface.ServiceFlags & PXE_UNDI_IFACE_FLAG_IRQ)) {
asm volatile("orb $1,%0" : "+m" (pxe_need_poll));
+ dprintf("pxe_start_isr: forcing pxe_need_poll\n");
+ } else if (PXE_POLL_BY_MODEL) {
+ dprintf("pxe_start_isr: trying poll by model\n");
+ int hwad = ((int)MAC[0] << 16) + ((int)MAC[1] << 8) + MAC[2];
+ dprintf("pxe_start_isr: got %06x %04x\n", hwad, pxe_undi_iface.ServiceFlags);
+ if (hwad == 0x000023ae) {
+ if (pxe_undi_iface.ServiceFlags == 0xdc1b) {
+ asm volatile("orb $1,%0" : "+m" (pxe_need_poll));
+ dprintf("pxe_start_isr: forcing pxe_need_poll by model\n");
+ }
+ }
+ }
}
int reset_pxe(void)
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 4591edc9..4de4dbfb 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -371,7 +371,7 @@ static void get_prefix(void)
*(p + 2) = 0; /* Zero-terminate after delimiter */
}
- printf("TFTP prefix: %s\n", path_prefix);
+ ddprintf("TFTP prefix: %s\n", path_prefix);
if (url_type(path_prefix) == URL_SUFFIX) {
/*
@@ -476,7 +476,7 @@ static int pxe_open_config(struct com32_filedata *filedata)
if (open_file(ConfigName, O_RDONLY, filedata) >= 0)
return 0;
- printf("%-68s\n", "Unable to locate configuration file");
+ ddprintf("%-68s\n", "Unable to locate configuration file");
kaboom();
}
@@ -532,7 +532,7 @@ static void ip_init(void)
gendotquad(dot_quad_buf, ip);
ip = ntohl(ip);
- printf("My IP address seems to be %08X %s\n", ip, dot_quad_buf);
+ ddprintf("My IP address seems to be %08X %s\n", ip, dot_quad_buf);
}
/*
diff --git a/core/fs/pxe/tftp.c b/core/fs/pxe/tftp.c
index b5dc72e4..1f374a3f 100644
--- a/core/fs/pxe/tftp.c
+++ b/core/fs/pxe/tftp.c
@@ -255,18 +255,15 @@ void tftp_open(struct url_info *url, int flags, struct inode *inode,
timeout_ptr = TimeoutTable; /* Reset timeout */
sendreq:
- core_udp_disconnect(socket);
timeout = *timeout_ptr++;
if (!timeout)
return; /* No file available... */
oldtime = jiffies();
- core_udp_connect(socket, url->ip, url->port);
- core_udp_send(socket, rrq_packet_buf, rrq_len);
+ core_udp_sendto(socket, rrq_packet_buf, rrq_len, url->ip, url->port);
/* If the WRITE call fails, we let the timeout take care of it... */
wait_pkt:
- core_udp_disconnect(socket);
for (;;) {
buf_len = sizeof(reply_packet_buf);
@@ -277,8 +274,10 @@ wait_pkt:
if (now - oldtime >= timeout)
goto sendreq;
} else {
- /* Make sure the packet actually came from the server */
- if (src_ip == url->ip)
+ /* Make sure the packet actually came from the server and
+ is long enough for a TFTP opcode */
+ dprintf("tftp_open: got packet buflen=%d\n", buf_len);
+ if ((src_ip == url->ip) && (buf_len >= 2))
break;
}
}
@@ -290,8 +289,6 @@ wait_pkt:
inode->size = -1;
socket->tftp_blksize = TFTP_BLOCKSIZE;
buffersize = buf_len - 2; /* bytes after opcode */
- if (buffersize < 0)
- goto wait_pkt; /* Garbled reply */
/*
* Get the opcode type, and parse it
diff --git a/core/include/mbox.h b/core/include/mbox.h
index 3c35ce4e..6fec267c 100644
--- a/core/include/mbox.h
+++ b/core/include/mbox.h
@@ -45,7 +45,8 @@ mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout);
*/
static inline void mbox_set_invalid(struct mailbox *mbox)
{
- sem_set_invalid(&mbox->prod_sem);
+ if (!!mbox)
+ sem_set_invalid(&mbox->prod_sem);
}
/*
@@ -53,7 +54,7 @@ static inline void mbox_set_invalid(struct mailbox *mbox)
*/
static inline bool mbox_is_valid(struct mailbox *mbox)
{
- return sem_is_valid(&mbox->prod_sem);
+ return ((!!mbox) && sem_is_valid(&mbox->prod_sem));
}
#endif /* _MBOX_H */
diff --git a/core/include/net.h b/core/include/net.h
index a5dcd724..c64191d8 100644
--- a/core/include/net.h
+++ b/core/include/net.h
@@ -23,6 +23,9 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len,
void core_udp_send(struct pxe_pvt_inode *socket,
const void *data, size_t len);
+void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, size_t len,
+ uint32_t ip, uint16_t port);
+
void probe_undi(void);
void pxe_init_isr(void);
diff --git a/core/include/thread.h b/core/include/thread.h
index 6bfdfaa7..8ec4a267 100644
--- a/core/include/thread.h
+++ b/core/include/thread.h
@@ -93,7 +93,8 @@ void sem_init(struct semaphore *, int);
*/
static inline void sem_set_invalid(struct semaphore *sem)
{
- sem->list.next = NULL;
+ if (!!sem)
+ sem->list.next = NULL;
}
/*
@@ -101,7 +102,7 @@ static inline void sem_set_invalid(struct semaphore *sem)
*/
static inline bool sem_is_valid(struct semaphore *sem)
{
- return !!sem->list.next;
+ return ((!!sem) && (!!sem->list.next));
}
struct thread *start_thread(const char *name, size_t stack_size, int prio,
diff --git a/core/legacynet/core.c b/core/legacynet/core.c
index 3ebc8f97..eacb4927 100644
--- a/core/legacynet/core.c
+++ b/core/legacynet/core.c
@@ -147,6 +147,43 @@ void core_udp_send(struct pxe_pvt_inode *socket, const void *data, size_t len)
}
/**
+ * Send a UDP packet to a destination
+ *
+ * @param:socket, the open socket
+ * @param:data, data buffer to send
+ * @param:len, size of data bufer
+ * @param:ip, the ip address
+ * @param:port, the port number, host-byte order
+ */
+void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data, size_t len,
+ uint32_t ip, uint16_t port)
+{
+ static __lowmem struct s_PXENV_UDP_WRITE udp_write;
+ struct net_private_tftp *priv = &socket->net.tftp;
+ void *lbuf;
+ uint16_t tid;
+
+ lbuf = lmalloc(len);
+ if (!lbuf)
+ return;
+
+ memcpy(lbuf, data, len);
+
+ tid = priv->localport; /* TID(local port No) */
+ udp_write.buffer = FAR_PTR(lbuf);
+ udp_write.ip = ip;
+ udp_write.gw = gateway(udp_write.ip);
+ udp_write.src_port = tid;
+ udp_write.dst_port = htons(port);
+ udp_write.buffer_size = len;
+
+ pxe_call(PXENV_UDP_WRITE, &udp_write);
+
+ lfree(lbuf);
+}
+
+
+/**
* Network stack-specific initialization
*
* Initialize UDP stack
diff --git a/core/lwip/src/arch/sys_arch.c b/core/lwip/src/arch/sys_arch.c
index 894f6ada..4081d01e 100644
--- a/core/lwip/src/arch/sys_arch.c
+++ b/core/lwip/src/arch/sys_arch.c
@@ -48,7 +48,7 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
mstime_t rv;
- if (!!sem)
+ if (!sem || !*sem)
return SYS_ARCH_TIMEOUT;
rv = sem_down(*sem, timeout);
if (rv == (mstime_t)-1)
@@ -71,8 +71,11 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size)
void sys_mbox_free(sys_mbox_t *mbox)
{
- if (!!mbox && !!*mbox)
+ if (!!mbox && !!*mbox) {
+ sys_mbox_set_invalid(mbox);
free(*mbox);
+ *mbox = NULL;
+ }
}
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
diff --git a/core/lwip/src/netif/undiif.c b/core/lwip/src/netif/undiif.c
index 0dee67a2..e62a984d 100644
--- a/core/lwip/src/netif/undiif.c
+++ b/core/lwip/src/netif/undiif.c
@@ -174,7 +174,7 @@ static u8_t undiarp_cached_entry;
#define UNDIARP_TRY_HARD 1
#define UNDIARP_FIND_ONLY 2
-#define UNIDIF_ID_STRLEN 244
+#define UNIDIF_ID_STRLEN 300
static inline bool undi_is_ethernet(struct netif *netif)
@@ -248,7 +248,7 @@ int snprintf_eth_hdr(char *str, size_t size, char head[],
return snprintf(str, size,
"%s: d:%02x:%02x:%02x:%02x:%02x:%02x"
" s:%02x:%02x:%02x:%02x:%02x:%02x"
- " t:%4hx %c%c %s\n", head,
+ " t:%4hx %c%c%s\n", head,
d[0], d[1], d[2], d[3], d[4], d[5],
s[0], s[1], s[2], s[3], s[4], s[5],
(unsigned)htons(ethhdr->type),
@@ -273,7 +273,7 @@ int snprintf_arp_hdr(char *str, size_t size, char head[],
" %3d.%3d.%3d.%3d"
" %02x:%02x:%02x:%02x:%02x:%02x"
" %3d.%3d.%3d.%3d"
- " %c%c %s\n", head,
+ " %c%c%s\n", head,
s[0], s[1], s[2], s[3], s[4], s[5],
ip4_addr1(sip), ip4_addr2(sip),
ip4_addr3(sip), ip4_addr4(sip),
@@ -296,7 +296,7 @@ int snprintf_ip_hdr(char *str, size_t size, char head[],
return snprintf(str, size,
"%s: s:%3d.%3d.%3d.%3d %3d.%3d.%3d.%3d l:%5d"
" i:%04x p:%04x c:%04x hl:%3d"
- " %c%c %s\n", head,
+ " %c%c%s\n", head,
ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src),
ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src),
ip4_addr1(&iphdr->dest), ip4_addr2(&iphdr->dest),
@@ -323,7 +323,7 @@ int snprintf_icmp_hdr(char *str, size_t size, char head[],
return snprintf(str, size,
"%s: t:%02x c:%02x k:%04x"
" i:%04x s:%04x "
- " %c%c %s\n", head,
+ " %c%c%s\n", head,
icmphdr->type, icmphdr->code, ntohs(icmphdr->chksum),
ntohs(icmphdr->id), ntohs(icmphdr->seqno),
dir, status, tail);
@@ -345,12 +345,13 @@ int snprintf_tcp_hdr(char *str, size_t size, char head[],
iphdr = (struct ip_hdr *)((void *)ethhdr + 14);
if (IPH_PROTO(iphdr) == IP_PROTO_TCP) {
tcphdr = (struct tcp_hdr *)((void *)iphdr + (IPH_HL(iphdr) << 2));
+ u16_t lenfl = ntohs(tcphdr->_hdrlen_rsvd_flags);
return snprintf(str, size,
- "%s: s:%5d %5d q:%08x a:%08x k:%04x"
- " %c%c %s\n", head,
+ "%s: s:%5d %5d q:%08x a:%08x lf:%04x k:%04x"
+ " %c%c%s\n", head,
ntohs(tcphdr->src), ntohs(tcphdr->dest),
ntohl(tcphdr->seqno), ntohl(tcphdr->ackno),
- ntohs(tcphdr->chksum),
+ lenfl, ntohs(tcphdr->chksum),
dir, status, tail);
} else {
return 0;
@@ -372,7 +373,7 @@ int snprintf_udp_hdr(char *str, size_t size, char head[],
udphdr = (struct udp_hdr *)((void *)iphdr + (IPH_HL(iphdr) << 2));
return snprintf(str, size,
"%s: s:%5d %5d l:%d c:%04x"
- " %c%c %s\n", head,
+ " %c%c%s\n", head,
ntohs(udphdr->src), ntohs(udphdr->dest),
ntohs(udphdr->len), ntohs(udphdr->chksum),
dir, status, tail);
@@ -480,7 +481,9 @@ undi_transmit(struct netif *netif, struct pbuf *pbuf,
struct eth_hdr *ethhdr = pbuf->payload;
- strpos = snprintf_eth_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
+ strpos += snprintf(str + strpos, UNIDIF_ID_STRLEN - strpos,
+ "undi xmit thd '%s'\n", current()->name);
+ strpos += snprintf_eth_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
"undi", ethhdr, 'x', '0', "");
strpos += snprintf_arp_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
" arp", ethhdr, 'x', '0', "");
@@ -1464,7 +1467,9 @@ void undiif_input(t_PXENV_UNDI_ISR *isr)
char *str = malloc(UNIDIF_ID_STRLEN);
int strpos = 0;
- strpos = snprintf_eth_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
+ strpos += snprintf(str + strpos, UNIDIF_ID_STRLEN - strpos,
+ "undi recv thd '%s'\n", current()->name);
+ strpos += snprintf_eth_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
"undi", ethhdr, 'r', '0', "");
strpos += snprintf_arp_hdr(str + strpos, UNIDIF_ID_STRLEN - strpos,
" arp", ethhdr, 'r', '0', "");
diff --git a/core/macros.inc b/core/macros.inc
index e3aedca1..c8fbe8de 100644
--- a/core/macros.inc
+++ b/core/macros.inc
@@ -31,6 +31,11 @@
%endif
%ifdef IS_PXELINUX
%define MY_NAME 'PXELINUX'
+ %if IS_LPXELINUX > 0
+ %define MY_TYPE 'lwIP'
+ %else
+ %define MY_TYPE 'PXE'
+ %endif
%else
%define IS_PXELINUX 0
%endif
diff --git a/core/pxelinux.asm b/core/pxelinux.asm
index 6b8c9e4c..64194d38 100644
--- a/core/pxelinux.asm
+++ b/core/pxelinux.asm
@@ -561,13 +561,14 @@ pxe_file_exit_hook:
section .data16
global copyright_str, syslinux_banner
-copyright_str db ' Copyright (C) 1994-'
+copyright_str db 'Copyright (C) 1994-'
asciidec YEAR
db ' H. Peter Anvin et al', CR, LF, 0
err_bootfailed db CR, LF, 'Boot failed: press a key to retry, or wait for reset...', CR, LF, 0
bailmsg equ err_bootfailed
localboot_msg db 'Booting from local disk...', CR, LF, 0
-syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', DATE_STR, ' ', 0
+syslinux_banner db CR, LF, MY_NAME, ' ', VERSION_STR, ' ', MY_TYPE, ' '
+ db DATE_STR, ' ', 0
;
; Misc initialized (data) variables
diff --git a/core/thread/mbox.c b/core/thread/mbox.c
index c518eeba..d1c640a9 100644
--- a/core/thread/mbox.c
+++ b/core/thread/mbox.c
@@ -10,18 +10,22 @@
void mbox_init(struct mailbox *mbox, size_t size)
{
- sem_init(&mbox->prod_sem, size); /* All slots empty */
- sem_init(&mbox->cons_sem, 0); /* No slots full */
- sem_init(&mbox->head_sem, 1); /* Head mutex */
- sem_init(&mbox->tail_sem, 1); /* Tail mutex */
-
- mbox->wrap = &mbox->data[size];
- mbox->head = &mbox->data[0];
- mbox->tail = &mbox->data[0];
+ if (!!mbox) {
+ sem_init(&mbox->prod_sem, size); /* All slots empty */
+ sem_init(&mbox->cons_sem, 0); /* No slots full */
+ sem_init(&mbox->head_sem, 1); /* Head mutex */
+ sem_init(&mbox->tail_sem, 1); /* Tail mutex */
+
+ mbox->wrap = &mbox->data[size];
+ mbox->head = &mbox->data[0];
+ mbox->tail = &mbox->data[0];
+ }
};
int mbox_post(struct mailbox *mbox, void *msg, mstime_t timeout)
{
+ if (!mbox_is_valid(mbox))
+ return ENOMEM;
if (sem_down(&mbox->prod_sem, timeout) == (mstime_t)-1)
return ENOMEM;
sem_down(&mbox->head_sem, 0);
@@ -40,6 +44,8 @@ mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout)
{
mstime_t t;
+ if (!mbox)
+ return -1;
t = sem_down(&mbox->cons_sem, timeout);
if (t == (mstime_t)-1)
return -1;
diff --git a/core/thread/semaphore.c b/core/thread/semaphore.c
index 6a2e4c13..c99af9c5 100644
--- a/core/thread/semaphore.c
+++ b/core/thread/semaphore.c
@@ -3,8 +3,10 @@
void sem_init(struct semaphore *sem, int count)
{
- sem->list.next = sem->list.prev = &sem->list;
- sem->count = count;
+ if (!!sem) {
+ sem->list.next = sem->list.prev = &sem->list;
+ sem->count = count;
+ }
}
mstime_t __sem_down_slow(struct semaphore *sem, mstime_t timeout)
@@ -14,7 +16,9 @@ mstime_t __sem_down_slow(struct semaphore *sem, mstime_t timeout)
irq = irq_save();
- if (sem->count >= 0) {
+ if (!sem_is_valid(sem)) {
+ rv = -1;
+ } else if (sem->count >= 0) {
/* Something already freed the semaphore on us */
rv = 0;
} else if (timeout == -1) {
@@ -64,17 +68,19 @@ void __sem_up_slow(struct semaphore *sem)
* we don't have to do anything, since the bailout clause in
* __sem_down_slow will take care of it.
*/
- l = sem->list.next;
- if (l != &sem->list) {
- struct thread_block *block;
- block = container_of(l, struct thread_block, list);
+ if (!!sem) {
+ l = sem->list.next;
+ if (l != &sem->list) {
+ struct thread_block *block;
+ block = container_of(l, struct thread_block, list);
- sem->list.next = block->list.next;
- block->list.next->prev = &sem->list;
+ sem->list.next = block->list.next;
+ block->list.next->prev = &sem->list;
- block->thread->blocked = NULL;
+ block->thread->blocked = NULL;
- __schedule();
+ __schedule();
+ }
}
irq_restore(irq);
diff --git a/efi/udp.c b/efi/udp.c
index db9bc8f9..59bb4263 100644
--- a/efi/udp.c
+++ b/efi/udp.c
@@ -297,3 +297,88 @@ bail:
free(txdata);
free(token);
}
+
+/**
+ * Send a UDP packet to a destination
+ *
+ * @param:socket, the open socket
+ * @param:data, data buffer to send
+ * @param:len, size of data bufer
+ * @param:ip, the ip address
+ * @param:port, the port number, host-byte order
+ */
+void core_udp_sendto(struct pxe_pvt_inode *socket, const void *data,
+ size_t len, uint32_t ip, uint16_t port)
+{
+ EFI_UDP4_COMPLETION_TOKEN *token;
+ EFI_UDP4_TRANSMIT_DATA *txdata;
+ EFI_UDP4_FRAGMENT_DATA *frag;
+ EFI_UDP4_CONFIG_DATA udata;
+ EFI_STATUS status;
+ struct efi_binding *b;
+ EFI_UDP4 *udp;
+
+ (void)socket;
+
+ b = efi_create_binding(&Udp4ServiceBindingProtocol, &Udp4Protocol);
+ if (!b)
+ return;
+
+ udp = (EFI_UDP4 *)b->this;
+
+ token = zalloc(sizeof(*token));
+ if (!token)
+ goto out;
+
+ txdata = zalloc(sizeof(*txdata));
+ if (!txdata)
+ goto bail;
+
+ memset(&udata, 0, sizeof(udata));
+
+ memcpy(&udata.StationAddress, &IPInfo.myip, sizeof(IPInfo.myip));
+ memcpy(&udata.SubnetMask, &IPInfo.netmask, sizeof(IPInfo.netmask));
+ memcpy(&udata.RemoteAddress, &ip, sizeof(ip));
+ udata.RemotePort = port;
+ udata.AcceptPromiscuous = TRUE;
+ udata.TimeToLive = 64;
+
+ status = uefi_call_wrapper(udp->Configure, 2, udp, &udata);
+ if (status != EFI_SUCCESS)
+ goto bail;
+
+ status = efi_setup_event(&token->Event, (EFI_EVENT_NOTIFY)udp4_cb,
+ token);
+ if (status != EFI_SUCCESS)
+ goto bail;
+
+ txdata->UdpSessionData = NULL;
+ txdata->GatewayAddress = NULL;
+ txdata->DataLength = len;
+ txdata->FragmentCount = 1;
+ frag = &txdata->FragmentTable[0];
+
+ frag->FragmentLength = len;
+ frag->FragmentBuffer = (void *)data;
+
+ token->Packet.TxData = txdata;
+
+ status = uefi_call_wrapper(udp->Transmit, 2, udp, token);
+ if (status != EFI_SUCCESS)
+ goto close;
+
+ while (cb_status == -1)
+ uefi_call_wrapper(udp->Poll, 1, udp);
+
+ /* Reset */
+ cb_status = -1;
+
+close:
+ uefi_call_wrapper(BS->CloseEvent, 1, token->Event);
+
+bail:
+ free(txdata);
+ free(token);
+out:
+ efi_destroy_binding(b, &Udp4ServiceBindingProtocol);
+}