memdisk/dskprobe: Show the status of the last command when debugging
[profile/ivi/syslinux.git] / memdisk / memdisk.inc
index cfba2df..91040ba 100644 (file)
@@ -8,6 +8,7 @@
 ;
 ;   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
 ;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+;   Portions copyright 2009 Shao Miller [El Torito code, mBFT, safe hook]
 ;
 ;  This program is free software; you can redistribute it and/or modify
 ;  it under the terms of the GNU General Public License as published by
        call debug_tracer
        db %1
 %endmacro
+%macro WRITEHEX2 0-1 al
+%ifnidni %1,al
+       push ax
+       mov al,%1
+       call writehex2
+       pop ax
+%else
+       call writehex2
+%endif
+%endmacro
+%macro WRITEHEX4 0-1 ax
+%ifnidni %1,ax
+       push ax
+       mov ax,%1
+       call writehex4
+       pop ax
+%else
+       call writehex4
+%endif
+%endmacro
+%macro WRITEHEX8 0-1 eax
+%ifnidni %1,eax
+       push eax
+       mov eax,%1
+       call writehex8
+       pop eax
+%else
+       call writehex8
+%endif
+%endmacro
 
 %else  ; DEBUG_TRACERS
 
 %macro TRACER  1
 %endmacro
+%macro WRITEHEX2 0-1
+%endmacro
+%macro WRITEHEX4 0-1
+%endmacro
+%macro WRITEHEX8 0-1
+%endmacro
 
 %endif ; DEBUG_TRACERS
 
@@ -43,7 +80,6 @@
 
                org 0h
 
-%define SECTORSIZE_LG2 9               ; log2(sector size)
 %define        SECTORSIZE      (1 << SECTORSIZE_LG2)
 
                ; Parameter registers definition; this is the definition
                ; must be first in the binary
 Pointers:      dw Int13Start
                dw Int15Start
-               dw PatchArea
+               dw MemDisk_Info         ; Portions are patched by installer
                dw TotalSize
                dw IretPtr
 
 IretPtr                equ Int13Start.iret
 Int13Start:
+               jmp strict near .SafeHookEnd ; 3-byte jump
+               db '$INT13SF'           ; Signature for "safe hook"
+               db 'MEMDISK '           ; Vendor ID
+               dd 0                    ; SEG:OFF of previous INT 13h hook
+                                       ; Must be filled in by installer
+               dd 0                    ; "Safe hook" flags
+; ---- "Safe hook" structure ends here ---
+
+; This next field should be guaranteed at this position after the
+; "safe hook" structure.  This allows for a MEMDISK OS driver to
+; immediately find out the particular parameters using the mBFT
+; and MDI structures.  This binary will have the offset to the mBFT
+; in this field to begin with, so the installer knows where the mBFT
+; is.  This is akin to the "Pointers" section above.  The installer
+; will refill this field with the physical address of the mBFT for
+; future consumers, such as OS drivers.
+               dd mBFT                 ; Offset from hook to the mBFT
+
+.SafeHookEnd:
                cmp word [cs:Recursive],0
-               jne jmp_oldint13
+               jne recursive
 
                ; Swap stack
                mov [cs:Stack],esp
@@ -100,6 +155,10 @@ Int13Start:
                mov ss,ax
                mov sp,[cs:MyStack]
 
+%if ELTORITO
+               cmp word [cs:SavedAX],4a00h     ; El Torito function?
+               jae our_drive                   ; We grab it
+%endif
                ; See if DL points to our class of device (FD, HD)
                push dx
                push dx
@@ -111,9 +170,19 @@ Int13Start:
                jz our_drive            ; If ZF=1, we have an exact match
                cmp dl,[cs:DriveNo]
                jb .nomatch             ; Drive < Our drive
+               cmp dl,[cs:DriveShiftLimit]
+               jae .nomatch            ; Drive > The maximum drive
+                                       ; number that we will shift for.
+                                       ; This leaves any higher-up BIOS
+                                       ; drives alone, such as an optical
+                                       ; disc drive 0xA0 or 0xE0
                dec dl                  ; Drive > Our drive, adjust drive #
 .nomatch:
+               TRACER '!'
+               WRITEHEX2 dl
+               TRACER ','
                mov ax,[cs:SavedAX]
+               WRITEHEX4
                inc word [cs:Recursive]
                pushf
                call far [cs:OldInt13]
@@ -124,7 +193,9 @@ Int13Start:
                cmp byte [cs:SavedAX+1],08h     ; Get drive params function?
                je .norestoredl                 ; DL = number of drives
                cmp byte [cs:SavedAX+1],15h     ; Get disk type function?
-               je .norestoredl                 ; CX:DX = size of device
+               jne .restoredl
+               test byte [bp+4],80h            ; Hard disk?
+               jnz .norestoredl                ; CX:DX = size of device
 .restoredl:
                mov dl,[bp+4]
 .norestoredl:
@@ -141,6 +212,8 @@ Int13Start:
                lss esp,[cs:Stack]
 .iret:         iret
 
+recursive:
+               TRACER '@'
 jmp_oldint13:
                jmp far [cs:OldInt13]
 
@@ -154,9 +227,18 @@ our_drive:
                pushad
                mov bp,sp               ; Point BP to the entry stack frame
                TRACER 'F'
+               WRITEHEX4
                ; Note: AX == P_AX here
                cmp ah,Int13FuncsCnt-1
                ja Invalid_jump
+%if ELTORITO
+               mov al,[CD_PKT.type]    ; Check if we are in
+               cmp al,0                ; El Torito no emulation mode
+               ja .emulation           ; No.  We support the function
+               cmp ah,3fh              ; Yes.  We must not support functions
+               jbe Invalid_jump        ; 0 through 3Fh.  Check and decide
+.emulation:
+%endif
                xor al,al               ; AL = 0 is standard entry condition
                mov di,ax
                shr di,7                ; Convert AH to an offset in DI
@@ -227,13 +309,15 @@ GetDriveType:
                test byte [DriveNo],80h
                mov bl,02h              ; Type 02h = floppy with changeline
                jz .floppy
-               ; Hard disks only...
+               ; Hard disks only!  DO NOT set CX:DX for floppies...
+               ; it apparently causes Win98SE DOS to go into an loop
+               ; resetting the drive over and over.  Sigh.
                inc bx                  ; Type = 03h
-.floppy:
                mov dx,[DiskSize]       ; Return the disk size in sectors
                mov P_DX,dx
                mov cx,[DiskSize+2]
                mov P_CX,cx
+.floppy:
                mov P_AH,bl             ; 02h floppy, 03h hard disk
                pop ax                  ; Drop return address
                xor ax,ax               ; Success...
@@ -343,8 +427,9 @@ EDDPresence:
                jne Invalid
                mov P_BX,0AA55h         ; EDD signature
                mov P_AX,03000h         ; EDD 3.0
-               mov P_CX,0003h          ; Bit 0 - Fixed disk access subset
+               mov P_CX,0007h          ; Bit 0 - Fixed disk access subset
                                        ; Bit 1 - Locking and ejecting subset
+                                       ; Bit 2 - EDD subset
                pop ax                  ; Drop return address
                xor ax,ax               ; Success
                jmp DoneWeird           ; Success, but AH != 0, sigh...
@@ -525,10 +610,36 @@ edd_setup_regs:
 EDDEject:
                mov ax,0B200h           ; Volume Not Removable
                ret
-
+%if ELTORITO
+ElToritoTerminate:
+               TRACER 'T'
+               mov ax,[cs:SavedAX]
+               cmp al,1                ; We only support query, not terminate
+               jne ElToritoErr         ; Fail
+               cmp dl,7fh              ; Terminate all?
+               je .doit
+               cmp dl,[cs:DriveNo]     ; Terminate our drive?
+               je .doit
+               jmp ElToritoErr         ; Fail
+.doit:         mov es,P_DS             ; Caller's DS:SI pointed to packet
+               mov di,P_SI             ; We'll use ES:DI
+               mov si,CD_PKT.size      ; First byte is packet size
+               xor cx,0                ; Empty our count
+               ;mov cl,[ds:si]         ; We'll copy that many bytes
+               mov cl,13h
+               rep movsb               ; Copy until CX is zero
+               mov ax,0                ; Success
+               ret
+ElToritoEmulate:
+ElToritoBoot:
+ElToritoCatalog:
+ElToritoErr:
+               TRACER '!'
+               mov ax,100h             ; Invalid parameter
+               ret
+%endif ; ELTORITO
 %endif ; EDD
 
-
 ;
 ; INT 15h intercept routines
 ;
@@ -832,7 +943,7 @@ writehex_common:
                ret
 %endif
 
-               section .data
+               section .data align=16
                alignb 2
 Int13Funcs     dw Reset                ; 00h - RESET
                dw GetStatus            ; 01h - GET STATUS
@@ -910,7 +1021,14 @@ Int13Funcs        dw Reset                ; 00h - RESET
                dw EDDSeek              ; 47h - EDD SEEK
                dw EDDGetParms          ; 48h - EDD GET PARAMETERS
                dw EDDDetectChange      ; 49h - EDD MEDIA CHANGE STATUS
-%endif
+%if ELTORITO                           ; EDD El Torito Functions
+                                       ; ELTORITO _must_ also have EDD
+               dw ElToritoEmulate      ; 4Ah - Initiate Disk Emulation
+               dw ElToritoTerminate    ; 4Bh - Terminate Disk Emulation
+               dw ElToritoBoot         ; 4Ch - Initiate Disk Emu. and Reboot
+               dw ElToritoCatalog      ; 4Dh - Return Boot Catalog
+%endif ; ELTORITO
+%endif ; EDD
 
 Int13FuncsEnd  equ $
 Int13FuncsCnt  equ (Int13FuncsEnd-Int13Funcs) >> 1
@@ -944,13 +1062,30 @@ 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
+               alignb 16, db 0
+mBFT:
+; Fields common to all ACPI tables
+               dd '    '               ; ACPI signature ("mBFT")
+                                       ; This is filled-in by the installer
+                                       ; to avoid an accidentally valid mBFT
+               dd mBFT_Len             ; ACPI table length
+               db 1                    ; ACPI revision
+               db 0                    ; ACPI table checksum
+               db 'MEMDSK'             ; ACPI OEM ID
+               db 'Syslinux'           ; ACPI OEM table ID
+               dd 0                    ; ACPI OEM revision
+               dd 0                    ; ACPI ASL compiler vendor ID
+               dd 0                    ; ACPI ASL compiler revision
+; The next field is mBFT-specific and filled-in by the installer
+               dd 0                    ; "Safe hook" physical address
+
+; Note that the above ends on a DWORD boundary.
+; The MDI has always started at such a boundary.
+; Portions of the MDI are patched by the installer
 MemDisk_Info   equ $                   ; Pointed to by installation check
 MDI_Bytes      dw MDI_Len              ; Total bytes in MDI structure
 MDI_Version    db VERSION_MINOR, VERSION_MAJOR ; MEMDISK version
 
-PatchArea      equ $                   ; This gets filled in by the installer
-
 DiskBuf                dd 0                    ; Linear address of high memory disk
 DiskSize       dd 0                    ; Size of disk in blocks
 CommandLine    dw 0, 0                 ; Far pointer to saved command line
@@ -966,8 +1101,16 @@ DPT_ptr           dw 0                    ; If nonzero, pointer to DPT
                                        ; Original DPT pointer follows
 
 MDI_Len                equ $-MemDisk_Info
+mBFT_Len       equ $-mBFT              ; mBFT includes the MDI
 
 ; ---- MDI structure ends here ---
+DriveShiftLimit        db 0ffh                 ; Installer will probe for
+                                       ; a range of contiguous drives.
+                                       ; Any BIOS drives above this region
+                                       ; shall not be impacted by our
+                                       ; shifting behaviour
+               db 0                    ; pad to a DWORD
+               dw 0                    ; pad to a QWORD
 MemInt1588     dw 0                    ; 1MB-65MB memory amount (1K)
 
 Cylinders      dw 0                    ; Cylinder count
@@ -1006,16 +1149,34 @@ EDD_DPT:
 .dpilen                db 2ch                  ; DPI len
 .res1          db 0                    ; Reserved
 .res2          dw 0                    ; Reserved
-.bustype       equ 'MEM '              ; Host bus type (4 bytes, space padded)
-.inttype       equ 'MEMORY  '          ; Interface type (8 bytes, spc. padded)
+.bustype       dd 'MEM '               ; Host bus type (4 bytes, space padded)
+.inttype       dd '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
 
-%endif
+%if ELTORITO
+; El Torito CD Specification Packet - mostly filled in by installer
+CD_PKT:
+.size          db 13h  ; Packet size (19 bytes)
+.type          db 0    ; Boot media type (flags)
+.driveno       db 0E0h ; INT 13h drive number
+.controller    db 0    ; Controller index
+.start         dd 0    ; Starting LBA of image
+.devno         dw 0    ; Device number
+.user_buf      dw 0    ; User buffer segment
+.load_seg      dw 0    ; Load segment
+.sect_count    dw 0    ; Emulated sectors to load
+.geom1         db 0    ; Cylinders bits 0 thru 7
+.geom2         db 0    ; Sects/track 0 thru 5, cyls 8, 9
+.geom3         db 0    ; Heads
+%endif ; ELTORITO
+
+%endif ; EDD
+
+; End patch area
 
-               ; End patch area
                alignb 4, db 0
 Stack          dd 0                    ; Saved SS:ESP on invocation
                dw 0