memdisk: correct the types for the EDD DPT, and write a real one
authorH. Peter Anvin <hpa@zytor.com>
Fri, 31 Jul 2009 15:27:58 +0000 (08:27 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Fri, 31 Jul 2009 15:27:58 +0000 (08:27 -0700)
Fix the sizes of some of the fields in the EDD DPT.  Write a real one
to the best of our ability.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
memdisk/memdisk.inc
memdisk/setup.c

index b4d45c4..cfba2df 100644 (file)
@@ -944,12 +944,6 @@ Mover_dst1:        db 0, 0, 0              ; Low 24 bits of target addy
 Mover_dst2:    db 0                    ; High 8 bits of source addy
 Mover_dummy2:  dd 0, 0, 0, 0           ; More space for the BIOS
 
-               alignb 4, db 0
-Stack          dd 0                    ; Saved SS:ESP on invocation
-               dw 0
-SavedAX                dw 0                    ; AX saved on invocation
-Recursive      dw 0                    ; Recursion counter
-
                alignb 4, db 0
 MemDisk_Info   equ $                   ; Pointed to by installation check
 MDI_Bytes      dw MDI_Len              ; Total bytes in MDI structure
@@ -1008,21 +1002,26 @@ EDD_DPT:
 .totalsize     dd 0, 0                 ; Filled in by installer
 .bytespersec   dw SECTORSIZE
 .eddtable      dw -1, -1               ; Invalid DPTE pointer
-.dpikey                dw 0                    ; Device Path Info magic (not impl.)
-                                       ; Would be 0beddh if implemented
+.dpikey                dw 0BEDDh               ; Device Path Info magic
 .dpilen                db 2ch                  ; DPI len
 .res1          db 0                    ; Reserved
-.res2          db 0                    ; Reserved
-.bustype       equ 'PCI '              ; Host bus type (4 bytes, space padded)
-.inttype       equ 'ATA     '          ; Interface type (8 bytes, spc. padded)
+.res2          dw 0                    ; Reserved
+.bustype       equ 'MEM '              ; Host bus type (4 bytes, space padded)
+.inttype       equ 'MEMORY  '          ; Interface type (8 bytes, spc. padded)
 .intpath       dd 0, 0                 ; Interface path
 .devpath       dd 0, 0, 0, 0           ; Device path
 .res3          db 0                    ; Reserved
-.chksum                db 0                    ; DPI checksum (not implemented)
+.chksum                db 0                    ; DPI checksum
 
 %endif
 
                ; End patch area
+               alignb 4, db 0
+Stack          dd 0                    ; Saved SS:ESP on invocation
+               dw 0
+SavedAX                dw 0                    ; AX saved on invocation
+Recursive      dw 0                    ; Recursion counter
+
                alignb 4, db 0          ; We *MUST* end on a dword boundary
 
 E820Table      equ $                   ; The installer loads the E820 table here
index 7af1610..013f3df 100644 (file)
@@ -81,8 +81,9 @@ struct edd_dpt {
     uint16_t bytespersec;      /* Bytes/sector */
     uint16_t dpte_off, dpte_seg;       /* DPTE pointer */
     uint16_t dpikey;           /* Device Path Info magic */
+    uint8_t  dpilen;           /* Device Path Info length */
     uint8_t  res1;             /* Reserved */
-    uint8_t  res2;             /* Reserved */
+    uint16_t res2;             /* Reserved */
     uint8_t  bustype[4];       /* Host bus type */
     uint8_t  inttype[8];       /* Interface type */
     uint64_t intpath;          /* Interface path */
@@ -717,6 +718,17 @@ static void relocate_rm_code(uint32_t newbase)
     sti();
 }
 
+static uint8_t checksum_buf(const void *buf, int count)
+{
+    const uint8_t *p = buf;
+    uint8_t c;
+
+    while (count--)
+       c += *p++;
+
+    return c;
+}
+
 #define STACK_NEEDED   512     /* Number of bytes of stack */
 
 struct real_mode_args rm_args;
@@ -896,20 +908,23 @@ void setup(const struct real_mode_args *rm_args_ptr)
 
     /* Set up an EDD drive parameter table */
     if (do_edd) {
-      pptr->edd_dpt.sectors = geometry->sectors;
-      /* The EDD spec has this as <= 15482880  sectors (1024x240x63);
-        this seems to make very little sense.  Try for something saner. */
-      if (geometry->c <= 1024 && geometry->h <= 255 && geometry->s <= 63) {
-       pptr->edd_dpt.c = geometry->c;
-       pptr->edd_dpt.h = geometry->h;
-       pptr->edd_dpt.s = geometry->s;
-       pptr->edd_dpt.flags |= 0x0002;  /* Geometry valid */
-      }
-      if (!(geometry->driveno & 0x80)) {
-       /* Floppy drive.  Mark it as a removable device with
-          media change notification; media is present. */
-       pptr->edd_dpt.flags |= 0x0014;
-      }
+       pptr->edd_dpt.sectors = geometry->sectors;
+       /* The EDD spec has this as <= 15482880  sectors (1024x240x63);
+          this seems to make very little sense.  Try for something saner. */
+       if (geometry->c <= 1024 && geometry->h <= 255 && geometry->s <= 63) {
+           pptr->edd_dpt.c = geometry->c;
+           pptr->edd_dpt.h = geometry->h;
+           pptr->edd_dpt.s = geometry->s;
+           pptr->edd_dpt.flags |= 0x0002;      /* Geometry valid */
+       }
+       if (!(geometry->driveno & 0x80)) {
+           /* Floppy drive.  Mark it as a removable device with
+              media change notification; media is present. */
+           pptr->edd_dpt.flags |= 0x0014;
+       }
+       
+       pptr->edd_dpt.devpath[0] = pptr->diskbuf;
+       pptr->edd_dpt.chksum  = -checksum_buf(&pptr->edd_dpt.dpikey, 73-30);
     }
 
     /* The size is given by hptr->total_size plus the size of the E820