summaryrefslogtreecommitdiff
path: root/memdisk
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-07-08 21:46:58 -0700
committerH. Peter Anvin <hpa@zytor.com>2007-07-08 21:46:58 -0700
commit056069afebceef2b84746b2b9db7063bfa67da9f (patch)
treead57bf795eae110395eccb356e25f105d8bf26a5 /memdisk
parentcdbcdcdf43eafb7623830aa6978c667e2201db82 (diff)
downloadsyslinux-056069afebceef2b84746b2b9db7063bfa67da9f.tar.gz
MEMDISK: Try for better EDD compliance
Diffstat (limited to 'memdisk')
-rw-r--r--memdisk/memdisk.asm84
-rw-r--r--memdisk/setup.c29
2 files changed, 76 insertions, 37 deletions
diff --git a/memdisk/memdisk.asm b/memdisk/memdisk.asm
index 90779cb5..fc46e844 100644
--- a/memdisk/memdisk.asm
+++ b/memdisk/memdisk.asm
@@ -275,6 +275,8 @@ CheckIfReady: ; These are always-successful noop functions
Recalibrate:
InitWithParms:
DetectChange:
+EDDDetectChange:
+EDDLock:
SetMode:
success:
xor ax,ax ; Always successful
@@ -335,8 +337,9 @@ EDDPresence:
cmp P_BX,55AAh
jne Invalid
mov P_BX,0AA55h ; EDD signature
- mov P_AX,02100h ; EDD 1.1
- mov P_CX,0001h ; Fixed disk access subset
+ mov P_AX,03000h ; EDD 3.0
+ mov P_CX,0003h ; Bit 0 - Fixed disk access subset
+ ; Bit 1 - Locking and ejecting subset
pop ax ; Drop return address
xor ax,ax ; Success
jmp DoneWeird ; Success, but AH != 0, sigh...
@@ -372,23 +375,22 @@ EDDGetParms:
mov es,P_DS
mov di,P_SI
- mov cx,30 ; Length of our DPT
- cmp [es:di],cx
- jae .oksize
+ mov si,EDD_DPT
- mov cx,26
- cmp [es:di],cx
+ lodsw ; Length of our DPT
+ mov cx,[es:di]
+ cmp cx,26 ; Minimum size
jb .overrun
+ cmp cx,ax
+ jb .oksize
+ mov cx,ax
.oksize:
- mov [si],cx
-
- ; This should be done by the installer...
- mov eax,[DiskSize]
- mov [si+16],eax
-
- mov si,EDD_DPT
+ mov ax,cx
+ stosw
+ dec cx
+ dec cx
rep movsb
xor ax,ax
@@ -466,15 +468,17 @@ edd_setup_regs:
movzx edi,word [es:si+6] ; Segment
shl edi,4
add esi,edi
-
jmp .got_address
.linear_address:
- cmp dx,24 ; Must be large enough to hold linear address
+ cmp dx,24 ; Must be large enough to hold
+ ; linear address
jb .baddapa
- cmp dword [es:si+20],0 ; > 4 GB addresses not supported
- jne .overrun
+ cmp dword [es:si+20],0 ; > 4 GB addresses not supported
+ mov ax,0900h ; "Data boundary error" - bogus, but
+ ; no really better code available
+ jne .error
mov esi,[es:si+16]
@@ -503,12 +507,18 @@ edd_setup_regs:
ret
.overrun:
+ mov ax,0200h ; "Address mark not found" =
+ ; LBA beyond end of disk
+.error:
and word [es:si+2],0 ; No sectors transferred
- mov ax,0200h
pop es
pop ax
ret
+EDDEject:
+ mov ax,0B200h ; Volume Not Removable
+ ret
+
%endif ; EDD
@@ -863,29 +873,16 @@ Int13Funcs dw Reset ; 00h - RESET
dw EDDRead ; 42h - EDD READ
dw EDDWrite ; 43h - EDD WRITE
dw EDDVerify ; 44h - EDD VERIFY
- dw Invalid ; 45h - EDD LOCK/UNLOCK MEDIA
- dw Invalid ; 46h - EDD EJECT
+ dw EDDLock ; 45h - EDD LOCK/UNLOCK MEDIA
+ dw EDDEject ; 46h - EDD EJECT
dw EDDSeek ; 47h - EDD SEEK
dw EDDGetParms ; 48h - EDD GET PARAMETERS
+ dw EDDDetectChange ; 49h - EDD MEDIA CHANGE STATUS
%endif
Int13FuncsEnd equ $
Int13FuncsCnt equ (Int13FuncsEnd-Int13Funcs) >> 1
-%if EDD
-EDD_DPT:
-.length dw 30
- ; Bit 0 - DMA boundaries handled transparently
- ; Bit 3 - Device supports write verify
-.info dw 0009h
-.cylinders dd 0 ; No physical geometry
-.heads dd 0 ; No physical geometry
-.sectors dd 0 ; No physical geometry
-.totalsize dd 0, 0 ; Total number of sectors
-.bytespersec dw SECTORSIZE
-.eddtable dw -1, -1 ; Invalid EDD table
-
-%endif
alignb 8, db 0
Shaker dw ShakerEnd-$
@@ -902,7 +899,6 @@ ShakerEnd equ $
alignb 8, db 0
-
Mover dd 0, 0, 0, 0 ; Must be zero
dw 0ffffh ; 64 K segment size
Mover_src1: db 0, 0, 0 ; Low 24 bits of source addy
@@ -955,9 +951,23 @@ MyStack dw 0 ; Offset of stack
StatusPtr dw 0 ; Where to save status (zeroseg ptr)
DPT times 16 db 0 ; BIOS parameter table pointer (floppies)
+%if EDD
+EDD_DPT:
+.length dw 30
+.info dw 0029h
+ ; Bit 0 - DMA boundaries handled transparently
+ ; Bit 3 - Device supports write verify
+ ; Bit 5 - Media is lockable
+.cylinders dd 0 ; Filled in by installer
+.heads dd 0 ; Filled in by installer
+.sectors dd 0 ; Filled in by installer
+.totalsize dd 0, 0 ; Filled in by installer
+.bytespersec dw SECTORSIZE
+.eddtable dw -1, -1 ; Invalid DPTE pointer
- ; End patch area
+%endif
+ ; End patch area
Stack dd 0 ; Saved SS:ESP on invocation
dw 0
SavedAX dw 0 ; AX saved on invocation
diff --git a/memdisk/setup.c b/memdisk/setup.c
index 553c4467..bacaba4d 100644
--- a/memdisk/setup.c
+++ b/memdisk/setup.c
@@ -60,6 +60,18 @@ typedef union {
} fd;
} dpt_t;
+/* EDD disk parameter table */
+struct edd_dpt {
+ uint16_t len; /* Length of table */
+ uint16_t flags; /* Information flags */
+ uint32_t c; /* Physical cylinders (count!) */
+ uint32_t h; /* Physical heads (count!) */
+ uint32_t s; /* Physical sectors/track (count!) */
+ uint64_t sectors; /* Total sectors */
+ uint16_t bytespersec; /* Bytes/sector */
+ uint16_t dpte_off, dpte_seg; /* DPTE pointer */
+};
+
struct patch_area {
uint32_t diskbuf;
uint32_t disksize;
@@ -97,6 +109,7 @@ struct patch_area {
uint16_t statusptr;
dpt_t dpt;
+ struct edd_dpt edd_dpt;
};
/* This is the header in the boot sector/setup area */
@@ -675,6 +688,22 @@ void setup(syscall_t cs_syscall, void *cs_bounce)
pptr->dpt.fd.old_fd_dpt = rdz_32(BIOS_INT1E);
}
+ /* Set up an EDD drive parameter table */
+ 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;
+ }
+
/* The size is given by hptr->total_size plus the size of the E820
map -- 12 bytes per range; we may need as many as 2 additional
ranges (each insertrange() can worst-case turn 1 area into 3)