📄 bup6.asm
字号:
;*****************************************************************;
;-----------------------------------------------------------------------;
include mbiosmac.mac
include makeflag.equ
;-----------------------------------------------------------------------;
extrn check_p6:near
extrn go_to_flat_mode_stack:near
extrn comeback_from_flat_mode_stack:near
extrn flash_write_enable:near
extrn flash_write_disable:near
extrn read_sio_byte:near
extrn write_sio_byte:near
extrn e000_read_rom_write_x:near
extrn flash_found_table:byte
extrn update_blocks:word
;---------------------------------------;
cgroup group _text
_text segment word public 'CODE'
assume cs:cgroup
.586p
;-----------------------------------------------------------------------;
; BIOS Update Feature for Pentium Pro (P6) Processor ;
;-----------------------------------------------------------------------;
; The specification as described in Pentium Pro Processor BIOS Writer's;
; Guide Version 2.0 January, 1996 is implemented. ;
;-----------------------------------------------------------------------;
; return codes
success equ 00h
not_implemented equ 86h
erase_failure equ 90h
write_failure equ 91h
read_failure equ 92h
storage_full equ 93h
cpu_not_present equ 94h
invalid_header equ 95h
invalid_header_cs equ 96h
security_failure equ 97h
invalid_revision equ 98h
update_num_invalid equ 99h
; other equates
block_length equ 2048
header_version equ 00000001h
loader_revision equ 00000001h
extern micro_code_start_addr:dword
;-----------------------------------------------------------------------;
UpdateHeaderStruc struc
HeaderVersion dd ? ; update header version#
UpdateRevision dd ? ; update version#
Date dd ? ; update date in binary
; 07/18/95 as 0x07181995
Processor dd ? ; type, family,model,stepping of CPU
Checksum dd ? ; checksum
LoaderRevision dd ? ; update loader version#
Reserved db 24 dup(?); 24 bytes reserved
UpdateHeaderStruc ends
;-----------------------------------------------------------------------;
; INT-15.ASM ;
; this routine is called from INT-15 ISR to support any special int-15 ;
; function if any. if you do not have any special func, simply return ;
; control to INT-15 ISR by RET. otherwise balance stack and return ;
; control to caller of INT-15 by IRET or RET 2. ;
; here is how INT-15 code will look like. ;
;int_15 proc far ;
; cmp ah,87h ;
; jz int_15_87 ;
; call special_int_15 ;
; ... ;
;int_15_87: ;
; ... ;
;int_15 endp ;
;=======================================================================;
; EXAMPLE: INT15 function to GATE-A20 support. ;
; input : (ah) 24h ;
; (al) 03h ;
; output: (ah) return code ;
; 00h successful ;
; 86h function not supported ;
; (NC) successful ;
; (CY) unsuccessful ;
; if successful ;
; (bx) bit 0..0 = GateA20 not supported on 8042;
; 1 = GateA20 supported on 8042 ;
; bit 1..0 = GateA20 not supported with ;
; bit-1 of I/O port 92H ;
; 1 = GateA20 supported with bit-1 ;
; of I/O port 92H ;
; Let us assume the chipset concerned has the support for GateA20 thru' ;
; bit-1 of I/O port 92H. In this case SPECIAL_INT_15 shoule be like as ;
; follows: ;
; ;
; special_int_15: ;
; cmp ah,24h ; func# 24h ? ;
; jnz si15_00 ; no.. ;
; cmp al,03h ; subfunc# 03h ? ;
; jnz si15_00 ; no.. ;
; POP BX ; ===VERY VERY IMPORTANT=== ;
; ; discard return address ;
; mov bx,02h ; bit 1 = 1..GateA20 thru' bit-1;
; ; of I/O port 92H ;
; sti ; enable interrupt ;
; xor ah,ah ; AH = 00..successful ;
; ; NC..successful ;
; x?? proc far ;
; ret 0002 ;
; x?? endp ;
; ;
; si15_00: ;
; ret ;
;-----------------------------------------------------------------------;
; SPECIAL_INT_15 ;
;-----------------------------------------------------------------------;
; input : ;
; none ;
; stack available ;
; register usage : do not destroy any register ;
;-----------------------------------------------------------------------;
public check_bu ; special int 15 func if any
check_bu:
cmp ax,0d042h ; BU function ?
jz bu_00 ; yes
bu_02:
ret
;-----------------------------------------------------------------------;
; PROCESSOR SPECIFIC UPDATE FUNCTIONS ;
;-----------------------------------------------------------------------;
bu_00:
call check_p6 ; check for P6 presence
jnz bu_02 ; P6 absent
add sp,0002h ; discard return address
mov ah,not_implemented
cmp bl,(offset cgroup:bu_func_table_end-offset cgroup:bu_func_table)/2
jae bu_01 ; invalid subfunc
push bx
; movzx bx,bl
xor bh,bh
shl bx,1
mov ax,cgroup:word ptr [bu_func_table+bx]
pop bx
call ax
bu_01:
mov al,00h ; AL = 00 additional OEM info
cmp ah,01h
cmc ; status in return carry flag
sti
retf 0002
;-----------------------------------------------------------------------;
; BU_FUNC_TABLE ;
;-----------------------------------------------------------------------;
bu_func_table label byte
dw offset cgroup:bl_00 ; subfunc 00h
dw offset cgroup:bl_01 ; subfunc 01h
dw offset cgroup:bl_02 ; subfunc 02h
dw offset cgroup:bl_03 ; subfunc 03h
bu_func_table_end label byte
;-----------------------------------------------------------------------;
; PRESENCE TEST ;
; this function verifies that BIOS has implemented the required BIOS ;
; update functions. ;
; input : ;
; AX D042 ;
; BL 00 ;
; output: ;
; CF return status ;
; NC = success ;
; CY = error ;
; AH return code ;
; AL additional OEM information ;
; EBX Signature Part-1 ('INTE') ;
; ECX Signature Part-2 ('LPEP') ;
; EDX Version# of BIOS update loader ;
; SI Update count (1-based) indicating #of update blocks ;
; system can record in NVRAM ;
;-----------------------------------------------------------------------;
bl_00:
mov ebx,'INTE' ; signature part-1
mov ecx,'LPEP' ; signature part-2
mov edx,loader_revision ; version# 1
mov si,cgroup:update_blocks ; #of update blocks (each of 2KBytes
; length) available in NVRAM
mov ah,success ; return code
ret
;-----------------------------------------------------------------------;
; WRITE BIOS UPDATE DATA ;
; this function integrates a new BIOS update into the BIOS storage area.;
; input : ;
; AX D042 ;
; BL 01 ;
; ES:DI Real Mode Pointer to the Intel Update structure ;
; this buffer is 2048 bytes in length ;
; CX Scratch Pad1 (Real Mode Scratch segment 64K in length) ;
; DX Scratch Pad2 (Real Mode Scratch segment 64K in length) ;
; SI Scratch Pad3 (Real Mode Scratch segment 64K in length) ;
; SS:SP Stack (32K minimum) ;
; output: ;
; CF return status ;
; NC = success ;
; CY = error ;
; AH return code ;
; AL additional OEM information ;
;-----------------------------------------------------------------------;
bl_01:
push es
push ds
push di
push si
push es
pop ds
xchg si,di ; DS:SI = ptr to update structure
; DI = scratch pad3
mov ah,invalid_header ; errro code
; check header version
cmp (UpdateHeaderStruc ptr ds:[si]).HeaderVersion,header_version
jnz bl01_00 ; header version error
; check loader revision
cmp (UpdateHeaderStruc ptr ds:[si]).LoaderRevision,loader_revision
jnz bl01_00 ; loader revision error
; verify the update structure checksum
mov ah,invalid_header_cs ; errro code
pushad
mov cx,block_length/4 ; CX = block length in unit of DWORD
xor ebx,ebx
bl01_01:
lods ds:dword ptr [si]
add ebx,eax
loop bl01_01
popad
jnz bl01_00 ; error, invalid checksum
; read 128K flash containing microcode in scratch buffer..
push es
pushad
mov es,cx ; use scratch pad1 for read 1st 64k
xor di,di ; ES:DI = pointer to read buffer
xor cx,cx ; #of bytes to read (=0000, 64k)
mov esi,cgroup:micro_code_start_addr
and esi,0ffff0000h ; read from 1st 64k flash
push esi
call read_bytes ; read to scratch pad1
mov es,dx ; use scratch pad2 for read 2nd 48k
xor di,di ; ES:DI = pointer to read buffer
xor cx,cx ; 64k
pop esi
add esi,10000h ; read from 2nd 64k flash in case of the micore module cross the 64k flash boundary
call read_bytes ; read to scratch pad2
popad
pop es
; 128K flash is read at scratch pad1:0000, 64K
; at scratch pad2:0000, 64K
; check the validity of update..
; DS:SI = Pointer to update (source) buffer
; search for any existing update block having the same processor signature
; as in supplied update data
push es
pushad
mov es,cx ; ES = scratch pad1
mov bp,dx ; BP = scratch pad2
xor ebx,ebx ; EBX bit31-16 = segment of 1st empty block
; bit15-0 = offset of 1st empty block
; EBX = 0000 => no empty block found
mov eax,cgroup:micro_code_start_addr
and eax,0000ffffh ; keep offset in scratch pad1
mov di,ax ; di = micro code start offset in scratch pad1 (1st flash)
mov eax,(UpdateHeaderStruc ptr ds:dword ptr [si]).Processor; get processor signature
movzx ecx,cgroup:word ptr update_blocks; ECX = #of blocks to be searched in scratch pad1
; ECX bit31-16 = #of blocks to be searched in scratch pad2
bl01_03:
cmp (UpdateHeaderStruc ptr es:[di]).HeaderVersion,000000000h; empty ?
jnz bl01_05 ; no, so check for processor
; this block is empty
or ebx,ebx ; empty block already found ?
jnz bl01_06 ; yes
push es
push di
pop ebx ; EBX bit31-16 = segment of 1st empty block
; bit15-0 = offset of 1st empty block
jmp short bl01_06
bl01_05:
cmp eax,(UpdateHeaderStruc ptr es:[di]).Processor; match ?
jz bl01_04 ; yes..
bl01_06:
add di,block_length ; ES:DI ptr to next block
jnc bl01_30 ; not cross boundary yet..
mov es,dx ; ES = next scratch pad (pad2)
bl01_30:
loop bl01_03 ; continue search
bl01_07:
; no existing data block contain data for given processor
; EBX bit31-16 = segment of 1st empty block
; bit15-0 = offset of 1st empty block
push eax
mov eax,cgroup:micro_code_start_addr
and eax,0000ffffh ; keep offset in next scratch
mov di,ax
pop eax
or ebx,ebx
jz bl01_12
push ebx
pop di
pop es ; ES:DI = ptr to empty block
bl01_12:
mov ebx,(UpdateHeaderStruc ptr ds:[si]).UpdateRevision; get update revision from given data
jmp short bl01_13
bl01_04:
; DS:SI = Pointer to update (source) buffer
; ES:DI = ptr to update data block which already contain data for given processor
mov ebx,(UpdateHeaderStruc ptr ds:[si]).UpdateRevision; get update revision from given data
cmp ebx,(UpdateHeaderStruc ptr es:[di]).UpdateRevision; given update revison > existing ?
jbe bl01_08 ; no, invalid update revision
; authenticate the update
call get_processor_update_revision; EDX = processor update revision
cmp ebx,edx ; supplied revision > current revision ?
jbe bl01_08 ; no, invalid update revision
bl01_13:
; validate update revision by actually loading the update into current processor
; DS:SI = ptr to update data
push 0000h
push ds
pop eax ; EAX = DS
shl eax,4
movzx esi,si
add eax,esi ; EAX = 32bit address of update data structure
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -