Merge branch 'master' of git://git.etherboot.org/scm/gpxe
authorJoshua Oreman <oremanj@xenon.get-linux.org>
Wed, 15 Apr 2009 23:20:49 +0000 (16:20 -0700)
committerJoshua Oreman <oremanj@xenon.get-linux.org>
Wed, 15 Apr 2009 23:20:49 +0000 (16:20 -0700)
src/arch/i386/firmware/pcbios/e820mangler.S
src/arch/i386/firmware/pcbios/fakee820.c
src/arch/i386/interface/pxe/pxe_entry.S
src/core/gdbstub.c
src/include/gpxe/smbios.h
src/interface/smbios/smbios_settings.c
src/net/dhcppkt.c
src/util/zbin.c

index 4ba3fb1..decb083 100644 (file)
@@ -489,6 +489,18 @@ get_mangled_e820:
        ret
        .size get_mangled_e820, . - get_mangled_e820
 
+/****************************************************************************
+ * Set/clear CF on the stack as appropriate, assumes stack is as it should
+ * be immediately before IRET
+ ****************************************************************************
+ */
+patch_cf:
+       pushw   %bp
+       movw    %sp, %bp
+       setc    8(%bp)  /* Set/reset CF; clears PF, AF, ZF, SF */
+       popw    %bp
+       ret
+
 /****************************************************************************
  * INT 15,e820 handler
  ****************************************************************************
@@ -500,7 +512,8 @@ int15_e820:
        popw    %ds
        call    get_mangled_e820
        popw    %ds
-       lret    $2
+       call    patch_cf
+       iret
        .size int15_e820, . - int15_e820
        
 /****************************************************************************
@@ -512,7 +525,7 @@ int15_e801:
        /* Call previous handler */
        pushfw
        lcall   *%cs:int15_vector
-       pushfw
+       call    patch_cf
        /* Edit result */
        pushw   %ds
        pushw   %cs:rm_ds
@@ -524,9 +537,7 @@ int15_e801:
        xchgw   %ax, %cx
        xchgw   %bx, %dx
        popw    %ds
-       /* Restore flags returned by previous handler and return */
-       popfw
-       lret    $2
+       iret
        .size int15_e801, . - int15_e801
        
 /****************************************************************************
@@ -538,16 +549,14 @@ int15_88:
        /* Call previous handler */
        pushfw
        lcall   *%cs:int15_vector
-       pushfw
+       call    patch_cf
        /* Edit result */
        pushw   %ds
        pushw   %cs:rm_ds
        popw    %ds
        call    patch_1m
        popw    %ds
-       /* Restore flags returned by previous handler and return */
-       popfw
-       lret    $2
+       iret
        .size int15_88, . - int15_88
                
 /****************************************************************************
index e171edf..552bf41 100644 (file)
@@ -63,6 +63,8 @@ void fake_e820 ( void ) {
                              "cmpl $0x534d4150, %%edx\n\t"
                              "jne 99f\n\t"
                              "pushaw\n\t"
+                             "movw %%sp, %%bp\n\t"
+                             "andb $~0x01, 22(%%bp)\n\t" /* Clear return CF */
                              "leaw e820map(%%bx), %%si\n\t"
                              "cs rep movsb\n\t"
                              "popaw\n\t"
@@ -73,8 +75,7 @@ void fake_e820 ( void ) {
                              "xorl %%ebx,%%ebx\n\t"
                              "\n1:\n\t"
                              "popfw\n\t"
-                             "clc\n\t"
-                             "lret $2\n\t"
+                             "iret\n\t"
                              "\n99:\n\t"
                              "popfw\n\t"
                              "ljmp *%%cs:real_int15_vector\n\t" )
index 22ef418..0e8c8e2 100644 (file)
@@ -199,9 +199,12 @@ pxe_int_1a:
        shll    $4, %edx
        addl    $pxenv, %edx
        movw    $0x564e, %ax
+       pushw   %bp
+       movw    %sp, %bp
+       andb    $~0x01, 8(%bp)  /* Clear CF on return */
+       popw    %bp
        popfw
-       clc
-       lret    $2
+       iret
 1:     /* INT 1A,other - pass through */
        popfw
        ljmp    *%cs:pxe_int_1a_vector
index 45df7f2..c808395 100644 (file)
@@ -344,12 +344,10 @@ static void gdbstub_state_cksum2 ( struct gdbstub *stub, char ch ) {
 static void gdbstub_state_wait_ack ( struct gdbstub *stub, char ch ) {
        if ( ch == '+' ) {
                stub->parse = gdbstub_state_new;
-       } else if ( ch == '-' ) {
-               gdbstub_tx_packet ( stub ); /* retransmit */
-       } else if ( ch == '$' ) {
-               /* GDB is reconnecting, drop our packet and listen to GDB */
-               stub->trans->send ( "-", 1 );
-               stub->parse = gdbstub_state_new;
+       } else {
+               /* This retransmit is very aggressive but necessary to keep
+                * in sync with GDB. */
+               gdbstub_tx_packet ( stub );
        }
 }
 
index 2b0fcbd..a294236 100644 (file)
@@ -113,6 +113,25 @@ struct smbios_system_information {
 /** SMBIOS system information structure type */
 #define SMBIOS_TYPE_SYSTEM_INFORMATION 1
 
+/** SMBIOS enclosure information structure */
+struct smbios_enclosure_information {
+       /** SMBIOS structure header */
+       struct smbios_header header;
+       /** Manufacturer string */
+       uint8_t manufacturer;
+       /** Type string */
+       uint8_t type;
+       /** Version string */
+       uint8_t version;
+       /** Serial number string */
+       uint8_t serial;
+       /** Asset tag */
+       uint8_t asset_tag;
+} __attribute__ (( packed ));
+
+/** SMBIOS enclosure information structure type */
+#define SMBIOS_TYPE_ENCLOSURE_INFORMATION 3
+
 /**
  * SMBIOS entry point descriptor
  *
index 61c2d91..ec594c5 100644 (file)
@@ -198,4 +198,12 @@ struct setting smbios_named_settings[] __setting = {
                                           serial ),
                .type = &setting_type_string,
        },
+       {
+               .name = "asset",
+               .description = "Asset tag",
+               .tag = SMBIOS_STRING_TAG ( SMBIOS_TYPE_ENCLOSURE_INFORMATION,
+                                          struct smbios_enclosure_information,
+                                          asset_tag ),
+               .type = &setting_type_string,
+       },
 };
index 1f2d373..2f3e680 100644 (file)
@@ -155,6 +155,8 @@ int dhcppkt_store ( struct dhcp_packet *dhcppkt, unsigned int tag,
                memset ( field_data, 0, field->len );
                memcpy ( dhcp_packet_field ( dhcppkt->dhcphdr, field ),
                         data, len );
+               /* Erase any equivalent option from the options block */
+               dhcpopt_store ( &dhcppkt->options, tag, NULL, 0 );
                return 0;
        }
 
@@ -181,14 +183,16 @@ int dhcppkt_fetch ( struct dhcp_packet *dhcppkt, unsigned int tag,
                    void *data, size_t len ) {
        struct dhcp_packet_field *field;
        void *field_data;
-       size_t field_len;
+       size_t field_len = 0;
        
-       /* If this is a special field, return it */
+       /* Identify special field, if any */
        if ( ( field = find_dhcp_packet_field ( tag ) ) != NULL ) {
                field_data = dhcp_packet_field ( dhcppkt->dhcphdr, field );
                field_len = field->used_len ( field_data, field->len );
-               if ( ! field_len )
-                       return -ENOENT;
+       }
+
+       /* Return special field, if it exists and is populated */
+       if ( field_len ) {
                if ( len > field_len )
                        len = field_len;
                memcpy ( data, field_data, len );
index c1082b3..d4eebe5 100644 (file)
@@ -57,6 +57,10 @@ struct zinfo_file {
        unsigned int num_entries;
 };
 
+static unsigned long align ( unsigned long value, unsigned long align ) {
+       return ( ( value + align - 1 ) & ~( align - 1 ) );
+}
+
 static int read_file ( const char *filename, void **buf, size_t *len ) {
        FILE *file;
        struct stat stat;
@@ -140,14 +144,13 @@ static int process_zinfo_copy ( struct input_file *input,
        struct zinfo_copy *copy = &zinfo->copy;
        size_t offset = copy->offset;
        size_t len = copy->len;
-       unsigned int align = copy->align;
 
        if ( ( offset + len ) > input->len ) {
                fprintf ( stderr, "Input buffer overrun on copy\n" );
                return -1;
        }
 
-       output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
+       output->len = align ( output->len, copy->align );
        if ( ( output->len + len ) > output->max_len ) {
                fprintf ( stderr, "Output buffer overrun on copy\n" );
                return -1;
@@ -170,7 +173,6 @@ static int process_zinfo_pack ( struct input_file *input,
        struct zinfo_pack *pack = &zinfo->pack;
        size_t offset = pack->offset;
        size_t len = pack->len;
-       unsigned int align = pack->align;
        unsigned long packed_len;
 
        if ( ( offset + len ) > input->len ) {
@@ -178,7 +180,7 @@ static int process_zinfo_pack ( struct input_file *input,
                return -1;
        }
 
-       output->len = ( ( output->len + align - 1 ) & ~( align - 1 ) );
+       output->len = align ( output->len, pack->align );
        if ( output->len > output->max_len ) {
                fprintf ( stderr, "Output buffer overrun on pack\n" );
                return -1;
@@ -222,8 +224,9 @@ static int process_zinfo_subtract ( struct input_file *input,
        }
 
        target = ( output->buf + offset );
-       delta = ( ( output->len / subtract->divisor ) -
-                 ( input->len / subtract->divisor ) );
+       delta = ( ( align ( output->len, subtract->divisor ) -
+                   align ( input->len, subtract->divisor ) )
+                 / subtract->divisor );
 
        switch ( datasize ) {
        case 1: {
@@ -251,7 +254,7 @@ static int process_zinfo_subtract ( struct input_file *input,
        }
 
        if ( DEBUG ) {
-               fprintf ( stderr, "SUBx [%#zx,%#zx) (%#lx+(%#lx/%#lx)-(%#lx/%#lx)) = %#lx\n",
+               fprintf ( stderr, "SUBx [%#zx,%#zx) (%#lx+(%#lx/%#x)-(%#lx/%#x)) = %#lx\n",
                          offset, ( offset + datasize ), old, output->len, subtract->divisor,
                          input->len, subtract->divisor, new );
        }