This happens because of error in the BIOS of your board.
The sample below is taken from widely installed Phoenix BIOS version 6.0 to
demonstrate why described error occurs.
At label "CheckLength" function compares the sum of the entire SMBIOS
structures pool length (typically, 3000h - 4000h bytes) and user data length
(typically 10h - 40h) with maximal value of 8000h. Clear, that this sum
typically will be smaller as 8000h. Therefore 'jg' instruction marked in
sample in red will almost always pass
execution to label "ErrNotDock" and SetStructure function will always return
an error code 87h (The system is currently not docked).
Most likely, this is an error committed by BIOS developper. The proper
instruction will be 'jle' instead of 'jg'. Since DMI write interface is not
used often, this routine was likely never really tested by BIOS
manufacturer.
;---------------------------- PNP return codes
-------------------------------
SUCCESS
equ 0 INVALID_HANDLE
equ 83h
SYSTEM_NOT_DOCKED equ 87h
USE_ESCD_SUPPORT equ 8dh
;------------------------
Set structure Subcommands --------------------------
CHANGE_BYTE
equ 00h CHANGE_WORD
equ 01h CHANGE_DWORD
equ 02h ADD_STRUCT
equ 03h DEL_STRUCT
equ 04h
CHANGE_STRING equ 05h
CHANGE_BLOCK
equ 06h
;---------------------- Layout of SMBIOS table
header ------------------------
@tag_DMI_HDR STRUCT
TableId BYTE
?
TableLen BYTE ?
TableHandle WORD
? @tag_DMI_HDR ENDS
DMI_HDR TYPEDEF
@tag_DMI_HDR
;------------------------ Layout of DMI Data
Buffer --------------------------
@tag_DMI_DATA STRUCT
; Offset
Command BYTE ?
; 00h - Identifies operation to be performed:
; 00h - Change Byte
; 01h - Change Word
; 02h - Change Double Word
; 03h - Add new structure
; 04h - Delete existring structure
; 05h - Change string value
; 06h - Change block of information
FieldOffset BYTE
? ; 01h - Starting offset within the changed
structure’s
ChangeMask DWORD ? ; 02h - AND-ing
mask to be applied to changed data
ChangeValue DWORD ?
; 06h - Data value to be OR-ed with the existing structure data
; (after applying the ChangeMask)
DataLength WORD
? ; 0Ah - Length of StructData for commands 3, 5 and
6
StructHdr DMI_HDR ? ; 0Ch - Contains the
structure header of the structure to be added, changed, or deleted
; StructData
; 10h - Data for commands 3, 5 and 6
@tag_DMI_DATA ENDS
DMI_DATA TYPEDEF
@tag_DMI_DATA
;--------------------- Stack layout on function
entry ------------------------
Function
equ word ptr [ebp + 14h]
dmiDataBuffer
equ dword ptr [ebp + 16h]
dmiWorkBuffer
equ dword ptr [ebp + 1Ah]
Control
equ word ptr [ebp + 1Eh]
dmiSelector
equ word ptr [ebp + 20h]
BiosSelector
equ word ptr [ebp + 22h]
;*****************************************************************************
;*
--- SetStructure ---
;*
;* Purpose: Modifies SMBIOS structure
;* Input: Function
- PnP BIOS Function 52h
;*
dmiDataBuffer - Pointer to buffer with new/change data
;*
dmiWorkBuffer - Pointer to work buffer area for the BIOS
;*
Control - Conditions for performing
operation ;*
Bit 0 = 0 - Do not set the specified structure, but
;*
validate its parameters
;*
Bit 0 = 1 - Set the structure immediately
;*
dmiSelector - SMBIOS data read/write selector
;*
BiosSelector - PnP BIOS readable/writeable selector
;* Output: PNP return code
;*****************************************************************************
SetStructure PROC NEAR
push bx
push di
push si
push ds
;------------------------------- Check ESCD
----------------------------------
mov di,3960
call 5aa2
call 3c02
; This subroutine in real-mode does nothing
mov ax, USE_ESCD_SUPPORT
jc Done
xor ax,ax
call 3c03
; This subroutine in real-mode does nothing
jnc DoneSuccess
or ax,ax
; ax = SUCCESS?
jnz Done
; no, return error
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;---------------------------- Check Parameters
-------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call CheckParameters ; This function checks function parameters.
; If write is possible, returns NC.
; Otherwise CY and error code on AX are returned
jc Done
; Return error code, if check fails
mov bx,Control ; word ptr [ebp+1e]
test bx,0001 ;
Physical write is required?
jz Done
; No, processing is completed.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;---------------------------- Modify structure
-------------------------------
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push ax
mov ax,0300
call GetSMBIOSPool ; This function returns parameters of:
; SMBIOS structures pool
; ax - Full size of entire SMBIOS table pool
; di - offset of first structure relative
; to dmiSelector
mov di,ax
; di - Full size of entire SMBIOS structures pool
mov bx,ax
; bx - Full size of entire SMBIOS structures pool
pop ax
mov es,dmiSelector
lds si,dmiDataBuffer
;-------------------
Calculate and check command length ----------------------
mov cx,SIZE DMA_DATA ; Assumed length of data structure
cmp byte ptr [si + DMI_DATA.Command],ADD_STRUCT
jz AddLength
cmp byte ptr [si + DMI_DATA.Command],CHANGE_BLOCK
jz AddLength
cmp byte ptr [si + DMI_DATA.Command],CHANGE_STRING
jnz CheckLength
AddLength: add cx,word ptr [si +
DMI_DATA.DataLength]
CheckLength: push cx
; cx - full length of data structure
add cx,di
; di - Full size of entire SMBIOS structures pool
cmp cx,8000h ; Size of
new SMBIOS pool is too large?
pop cx
; restore full length of data structure
jg ErrNotDock
;----------------
Copy command past of SMBIOS structures pool -----------------
repe movsb
; Copy data from dmiDataBuffer to es:di,
; where:
; es - dmiSelector
; di - Size of SMBIOS structures pool
;----------------------------- Perform command
-------------------------------
mov dx,1
mov si,es
; es - dmiSelector
mov di,373f
call 5aa2
mov di,bx
cmp word ptr es:[di+0e],-01
jnz DoneSuccess
ErrInvHnd: mov ax,INVALID_HANDLE
jmp Done
DoneSuccess: mov ax,SUCCESS
jmp Done
ErrNotDock: mov ax,SYSTEM_NOT_DOCKED
Done:
pop ds
pop si
pop di
pop bx
ret
|