diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-09-30 13:22:36 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-09-30 13:33:26 +0100 |
commit | 47179ebc03dcb3177312d97cd912605704c40686 (patch) | |
tree | e766d15f3153fcabfccbb5e4a6e318d6c7c50478 | |
parent | 3e86c0e35b96fef58dbfbb96e3ef509ea4047d2e (diff) | |
parent | 2fe3a7bdd20d6fada21bd455a902c2b02f46a02d (diff) | |
download | syslinux-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.h | 3 | ||||
-rw-r--r-- | core/bios.c | 2 | ||||
-rw-r--r-- | core/fs/pxe/bios.c | 24 | ||||
-rw-r--r-- | core/fs/pxe/core.c | 60 | ||||
-rw-r--r-- | core/fs/pxe/isr.c | 24 | ||||
-rw-r--r-- | core/fs/pxe/pxe.c | 6 | ||||
-rw-r--r-- | core/fs/pxe/tftp.c | 13 | ||||
-rw-r--r-- | core/include/mbox.h | 5 | ||||
-rw-r--r-- | core/include/net.h | 3 | ||||
-rw-r--r-- | core/include/thread.h | 5 | ||||
-rw-r--r-- | core/legacynet/core.c | 37 | ||||
-rw-r--r-- | core/lwip/src/arch/sys_arch.c | 7 | ||||
-rw-r--r-- | core/lwip/src/netif/undiif.c | 27 | ||||
-rw-r--r-- | core/macros.inc | 5 | ||||
-rw-r--r-- | core/pxelinux.asm | 5 | ||||
-rw-r--r-- | core/thread/mbox.c | 22 | ||||
-rw-r--r-- | core/thread/semaphore.c | 28 | ||||
-rw-r--r-- | efi/udp.c | 85 |
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); @@ -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); +} |