From eecf71e4a0d0df5c5c478c941c62214a18dd406b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 13 Sep 2007 12:57:25 +0100 Subject: [PATCH 01/10] Removed file checked in accidentally --- src/payload/hello.img | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/payload/hello.img diff --git a/src/payload/hello.img b/src/payload/hello.img deleted file mode 100644 index bc7774a7..00000000 --- a/src/payload/hello.img +++ /dev/null @@ -1 +0,0 @@ -hello world! \ No newline at end of file From 99411e36da52884257c8645beda2f601827fbb22 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 13 Sep 2007 13:34:38 +0100 Subject: [PATCH 02/10] Added netdev_priv() to ease Linux driver compatibility. --- src/include/gpxe/netdevice.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h index d82c6d8f..b96b3c04 100644 --- a/src/include/gpxe/netdevice.h +++ b/src/include/gpxe/netdevice.h @@ -326,6 +326,17 @@ netdev_put ( struct net_device *netdev ) { ref_put ( &netdev->refcnt ); } +/** + * Get driver private area for this network device + * + * @v netdev Network device + * @ret priv Driver private area for this network device + */ +static inline __attribute__ (( always_inline )) void * +netdev_priv ( struct net_device *netdev ) { + return netdev->priv; +} + extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ); extern void netdev_tx_complete_err ( struct net_device *netdev, struct io_buffer *iobuf, int rc ); From f09173326c3ec710764769e782859dba79afe945 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 17 Sep 2007 18:38:04 +0100 Subject: [PATCH 03/10] Moved iobuf.h assertions outside the static inline functions, so that the assert message's file and line number gives some clue as to the real location of the problem. Added similar assertions to list.h. --- src/include/gpxe/iobuf.h | 28 ++++++++++++++++++++++++---- src/include/gpxe/list.h | 18 ++++++++++++++++++ 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/include/gpxe/iobuf.h b/src/include/gpxe/iobuf.h index e3db01ac..ff787754 100644 --- a/src/include/gpxe/iobuf.h +++ b/src/include/gpxe/iobuf.h @@ -67,9 +67,13 @@ struct io_buffer { static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) { iobuf->data += len; iobuf->tail += len; - assert ( iobuf->tail <= iobuf->end ); return iobuf->data; } +#define iob_reserve( iobuf, len ) ( { \ + void *__result; \ + __result = iob_reserve ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) /** * Add data to start of I/O buffer @@ -80,9 +84,13 @@ static inline void * iob_reserve ( struct io_buffer *iobuf, size_t len ) { */ static inline void * iob_push ( struct io_buffer *iobuf, size_t len ) { iobuf->data -= len; - assert ( iobuf->data >= iobuf->head ); return iobuf->data; } +#define iob_push( iobuf, len ) ( { \ + void *__result; \ + __result = iob_push ( (iobuf), (len) ); \ + assert ( (iobuf)->data >= (iobuf)->head ); \ + __result; } ) /** * Remove data from start of I/O buffer @@ -96,6 +104,11 @@ static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) { assert ( iobuf->data <= iobuf->tail ); return iobuf->data; } +#define iob_pull( iobuf, len ) ( { \ + void *__result; \ + __result = iob_pull ( (iobuf), (len) ); \ + assert ( (iobuf)->data <= (iobuf)->tail ); \ + __result; } ) /** * Add data to end of I/O buffer @@ -107,9 +120,13 @@ static inline void * iob_pull ( struct io_buffer *iobuf, size_t len ) { static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) { void *old_tail = iobuf->tail; iobuf->tail += len; - assert ( iobuf->tail <= iobuf->end ); return old_tail; } +#define iob_put( iobuf, len ) ( { \ + void *__result; \ + __result = iob_put ( (iobuf), (len) ); \ + assert ( (iobuf)->tail <= (iobuf)->end ); \ + __result; } ) /** * Remove data from end of I/O buffer @@ -119,8 +136,11 @@ static inline void * iob_put ( struct io_buffer *iobuf, size_t len ) { */ static inline void iob_unput ( struct io_buffer *iobuf, size_t len ) { iobuf->tail -= len; - assert ( iobuf->tail >= iobuf->data ); } +#define iob_unput( iobuf, len ) do { \ + iob_unput ( (iobuf), (len) ); \ + assert ( (iobuf)->tail >= (iobuf)->data ); \ + } while ( 0 ) /** * Empty an I/O buffer diff --git a/src/include/gpxe/list.h b/src/include/gpxe/list.h index 0e65901c..602382be 100644 --- a/src/include/gpxe/list.h +++ b/src/include/gpxe/list.h @@ -10,6 +10,7 @@ */ #include +#include /* * Simple doubly linked list implementation. @@ -62,6 +63,11 @@ static inline void __list_add ( struct list_head *new, static inline void list_add ( struct list_head *new, struct list_head *head ) { __list_add ( new, head, head->next ); } +#define list_add( new, head ) do { \ + assert ( (head)->next->prev == (head) ); \ + assert ( (head)->prev->next == (head) ); \ + list_add ( (new), (head) ); \ + } while ( 0 ) /** * Add a new entry to the tail of a list @@ -76,6 +82,11 @@ static inline void list_add_tail ( struct list_head *new, struct list_head *head ) { __list_add ( new, head->prev, head ); } +#define list_add_tail( new, head ) do { \ + assert ( (head)->next->prev == (head) ); \ + assert ( (head)->prev->next == (head) ); \ + list_add_tail ( (new), (head) ); \ + } while ( 0 ) /* * Delete a list entry by making the prev/next entries @@ -101,6 +112,13 @@ static inline void __list_del ( struct list_head * prev, static inline void list_del ( struct list_head *entry ) { __list_del ( entry->prev, entry->next ); } +#define list_del( entry ) do { \ + assert ( (entry)->prev != NULL ); \ + assert ( (entry)->next != NULL ); \ + assert ( (entry)->next->prev == (entry) ); \ + assert ( (entry)->prev->next == (entry) ); \ + list_del ( (entry) ); \ + } while ( 0 ) /** * Test whether a list is empty From db124b12551f91a2437014fb74a122ff0d0db08b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 16 Sep 2007 17:36:40 +0100 Subject: [PATCH 04/10] Add fls() for non-constant values. --- src/core/bitops.c | 10 ++++++++++ src/include/strings.h | 6 +----- 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 src/core/bitops.c diff --git a/src/core/bitops.c b/src/core/bitops.c new file mode 100644 index 00000000..75d57bf9 --- /dev/null +++ b/src/core/bitops.c @@ -0,0 +1,10 @@ +#include + +int __flsl ( long x ) { + int r = 0; + + for ( r = 0 ; x ; r++ ) { + x >>= 1; + } + return r; +} diff --git a/src/include/strings.h b/src/include/strings.h index a087b1d5..968a7c11 100644 --- a/src/include/strings.h +++ b/src/include/strings.h @@ -40,17 +40,13 @@ __constant_flsl ( unsigned long x ) { return r; } -#define __constant_fls(x) __constant_flsl(x) - /* We don't actually have these functions yet */ -extern int __fls ( int x ); extern int __flsl ( long x ); #define flsl( x ) \ ( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) ) -#define fls( x ) \ - ( __builtin_constant_p ( x ) ? __constant_fls ( x ) : __fls ( x ) ) +#define fls( x ) flsl ( x ) extern int strcasecmp ( const char *s1, const char *s2 ); From 7e3527a65831b9dc6d6f370f393a437b7caa2524 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 16 Sep 2007 17:39:29 +0100 Subject: [PATCH 05/10] Don't get stuck in an infinite loop on negative integers! --- src/core/bitops.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/bitops.c b/src/core/bitops.c index 75d57bf9..53abaaea 100644 --- a/src/core/bitops.c +++ b/src/core/bitops.c @@ -1,10 +1,11 @@ #include int __flsl ( long x ) { - int r = 0; + unsigned long value = x; + int ls = 0; - for ( r = 0 ; x ; r++ ) { - x >>= 1; + for ( ls = 0 ; value ; ls++ ) { + value >>= 1; } - return r; + return ls; } From 9c264faa0c69abf9d83bd66cba40f32f297eae24 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 15 Sep 2007 18:44:35 +0100 Subject: [PATCH 06/10] Add const attribute to byte-swapping functions --- src/arch/i386/include/bits/byteswap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arch/i386/include/bits/byteswap.h b/src/arch/i386/include/bits/byteswap.h index 16e31f34..54b93ab9 100644 --- a/src/arch/i386/include/bits/byteswap.h +++ b/src/arch/i386/include/bits/byteswap.h @@ -1,7 +1,7 @@ #ifndef ETHERBOOT_BITS_BYTESWAP_H #define ETHERBOOT_BITS_BYTESWAP_H -static inline __attribute__ ((always_inline)) uint16_t +static inline __attribute__ ((always_inline, const)) uint16_t __i386_bswap_16(uint16_t x) { __asm__("xchgb %b0,%h0\n\t" @@ -10,7 +10,7 @@ __i386_bswap_16(uint16_t x) return x; } -static inline __attribute__ ((always_inline)) uint32_t +static inline __attribute__ ((always_inline, const)) uint32_t __i386_bswap_32(uint32_t x) { __asm__("xchgb %b0,%h0\n\t" @@ -21,7 +21,7 @@ __i386_bswap_32(uint32_t x) return x; } -static inline __attribute__ ((always_inline)) uint64_t +static inline __attribute__ ((always_inline, const)) uint64_t __i386_bswap_64(uint64_t x) { union { From af303db75d467e1268806303766db02150d101d6 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 13 Sep 2007 01:53:04 +0100 Subject: [PATCH 07/10] Use RFC4390 whenever hardware address exceeds 16 bytes; this allows us to construct DHCP packets suitable for Infiniband. --- src/include/gpxe/dhcp.h | 7 +++++++ src/net/udp/dhcp.c | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/include/gpxe/dhcp.h b/src/include/gpxe/dhcp.h index 43bccf18..18baa86a 100644 --- a/src/include/gpxe/dhcp.h +++ b/src/include/gpxe/dhcp.h @@ -432,6 +432,13 @@ struct dhcphdr { /** Opcode for a reply from server to client */ #define BOOTP_REPLY 2 +/** BOOTP reply must be broadcast + * + * Clients that cannot accept unicast BOOTP replies must set this + * flag. + */ +#define BOOTP_FL_BROADCAST 0x8000 + /** DHCP magic cookie */ #define DHCP_MAGIC_COOKIE 0x63825363UL diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index 9e48fe11..8e34ccb6 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -298,6 +298,7 @@ static int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype, void *data, size_t max_len, struct dhcp_packet *dhcppkt ) { struct dhcphdr *dhcphdr = data; + unsigned int hlen; int rc; /* Sanity check */ @@ -309,9 +310,17 @@ static int create_dhcp_packet ( struct net_device *netdev, uint8_t msgtype, dhcphdr->xid = dhcp_xid ( netdev ); dhcphdr->magic = htonl ( DHCP_MAGIC_COOKIE ); dhcphdr->htype = ntohs ( netdev->ll_protocol->ll_proto ); - dhcphdr->hlen = netdev->ll_protocol->ll_addr_len; - memcpy ( dhcphdr->chaddr, netdev->ll_addr, dhcphdr->hlen ); dhcphdr->op = dhcp_op[msgtype]; + /* If hardware length exceeds the chaddr field length, don't + * use the chaddr field. This is as per RFC4390. + */ + hlen = netdev->ll_protocol->ll_addr_len; + if ( hlen > sizeof ( dhcphdr->chaddr ) ) { + hlen = 0; + dhcphdr->flags = htons ( BOOTP_FL_BROADCAST ); + } + dhcphdr->hlen = hlen; + memcpy ( dhcphdr->chaddr, netdev->ll_addr, hlen ); /* Initialise DHCP packet structure */ dhcppkt->dhcphdr = dhcphdr; @@ -494,6 +503,14 @@ struct dhcp_netdev_desc { uint16_t device; } __attribute__ (( packed )); +/** DHCP client identifier */ +struct dhcp_client_id { + /** Link-layer protocol */ + uint8_t ll_proto; + /** Link-layer address */ + uint8_t ll_addr[MAX_LL_ADDR_LEN]; +} __attribute__ (( packed )); + /** * Create DHCP request * @@ -511,7 +528,9 @@ int create_dhcp_request ( struct net_device *netdev, int msgtype, struct dhcp_packet *dhcppkt ) { struct device_description *desc = &netdev->dev->desc; struct dhcp_netdev_desc dhcp_desc; + struct dhcp_client_id client_id; size_t dhcp_features_len; + size_t ll_addr_len; int rc; /* Create DHCP packet */ @@ -570,6 +589,21 @@ int create_dhcp_request ( struct net_device *netdev, int msgtype, return rc; } + /* Add DHCP client identifier. Required for Infiniband, and + * doesn't hurt other link layers. + */ + client_id.ll_proto = netdev->ll_protocol->ll_proto; + ll_addr_len = netdev->ll_protocol->ll_addr_len; + assert ( ll_addr_len <= sizeof ( client_id.ll_addr ) ); + memcpy ( client_id.ll_addr, netdev->ll_addr, ll_addr_len ); + if ( ( rc = set_dhcp_packet_option ( dhcppkt, DHCP_CLIENT_ID, + &client_id, + ( ll_addr_len + 1 ) ) ) != 0 ) { + DBG ( "DHCP could not set client ID: %s\n", + strerror ( rc ) ); + return rc; + } + return 0; } From 1af346b5315987cbc89a789dd5246ccb8c845437 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 17 Sep 2007 18:57:32 +0100 Subject: [PATCH 08/10] Minor debug message improvement. --- src/net/netdevice.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 460de89c..59a50205 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -476,8 +476,9 @@ static void net_step ( struct process *process __unused ) { * NIC faster than they arrive. */ if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) { - DBGC ( netdev, "NETDEV %p processing %p\n", - netdev, iobuf ); + DBGC ( netdev, "NETDEV %p processing %p (%p+%zx)\n", + netdev, iobuf, iobuf->data, + iob_len ( iobuf ) ); netdev->ll_protocol->rx ( iobuf, netdev ); } } From 2ee76d0c938c4b8250a30d606feeaed68788ed6b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 21 Sep 2007 01:19:04 +0100 Subject: [PATCH 09/10] Added defines for Infiniband files (which can't be committed to the main tree yet, but reserving the error numbers now avoids problems later). --- src/include/gpxe/errfile.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/include/gpxe/errfile.h b/src/include/gpxe/errfile.h index 4f9e7bc6..1b0ed33f 100644 --- a/src/include/gpxe/errfile.h +++ b/src/include/gpxe/errfile.h @@ -101,8 +101,10 @@ #define ERRFILE_via_rhine ( ERRFILE_DRIVER | 0x00440000 ) #define ERRFILE_via_velocity ( ERRFILE_DRIVER | 0x00450000 ) #define ERRFILE_w89c840 ( ERRFILE_DRIVER | 0x00460000 ) +#define ERRFILE_ipoib ( ERRFILE_DRIVER | 0x00470000 ) #define ERRFILE_scsi ( ERRFILE_DRIVER | 0x00700000 ) +#define ERRFILE_arbel ( ERRFILE_DRIVER | 0x00710000 ) #define ERRFILE_aoe ( ERRFILE_NET | 0x00000000 ) #define ERRFILE_arp ( ERRFILE_NET | 0x00010000 ) @@ -123,6 +125,7 @@ #define ERRFILE_dhcp ( ERRFILE_NET | 0x00100000 ) #define ERRFILE_dns ( ERRFILE_NET | 0x00110000 ) #define ERRFILE_tftp ( ERRFILE_NET | 0x00120000 ) +#define ERRFILE_infiniband ( ERRFILE_NET | 0x00130000 ) #define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 ) #define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 ) From 5793dbe96fc94abe48cfb3303776215f345ccab4 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 21 Sep 2007 01:23:57 +0100 Subject: [PATCH 10/10] Infinband requires longer link-layer addresses and headers than Ethernet. --- src/include/gpxe/netdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h index d82c6d8f..2cbd0efb 100644 --- a/src/include/gpxe/netdevice.h +++ b/src/include/gpxe/netdevice.h @@ -19,10 +19,10 @@ struct ll_protocol; struct device; /** Maximum length of a link-layer address */ -#define MAX_LL_ADDR_LEN 6 +#define MAX_LL_ADDR_LEN 20 /** Maximum length of a link-layer header */ -#define MAX_LL_HEADER_LEN 16 +#define MAX_LL_HEADER_LEN 32 /** Maximum length of a network-layer address */ #define MAX_NET_ADDR_LEN 4