📄 flash_bios.asm
字号:
NEWIODELAY MACRO
OUT 0EBH,AL
ENDM
.model SMALL
.data
MCH = 0 - 0
ICH = 31 - 0
TSC_ID EQU (00 SHL 3)
PIIX_ID EQU (ICH SHL 3)
DATA8042 EQU 60h
CTRL8042 EQU 61h
STAT8042 EQU 64h
IBF_8042 EQU 00000010b
OBF_8042 EQU 00000001b
A20_ON EQU 0DFh
A20_OFF EQU 0DDh
; Global Descriptor Table Register
GDTR DW 8*2 ; Limit
GDT_OFFSET DW 0
GDT_SEGMENT DW 0
GDT DW 0 ; Linit
DW 0 ; Base
DB 0 ; Hibase
DB 0 ; Access
DB 0 ; Hilimit
DB 0 ; Msbase
DATA_DT DW 0FFFFh ; Limit
DW 0 ; Base Data Segment Point
DB 0 ; Hibase
DB 93h ; Access
DB 8Fh ; Hilimit (4GB)
DB 0 ; Msbase
DATA_INDEX = ((OFFSET DATA_DT - OFFSET GDT)/8) SHL 3
.CODE
.STACK 200H
.386p
.startup
call Ct_ROM_Write_Enable ;set bios rom write enable
call Use_32bit_Address ;enter protected mode & exit
call SST_49LF002_Write_Enable ;set rom block write enable
mov edi,0ffff0000h
mov ds,di
mov es,di
call Erase_Entire_Chip
.exit
SST_49LF002_Write_Enable Proc
call JEDEC_Series_Reset
;call Use_32bit_Address ;enter protect mode & exit
mov al,0
mov esi, 0ffbf8002H ;set rom block write enable
mov bl,ds:[esi]
mov ds:[esi], al
nop
mov esi, 0ffbf0002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbe8002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbe0002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbd8002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbd0002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbc8002H ;set rom block write enable
mov ds:[esi], al
nop
mov esi, 0ffbc0002H ;set rom block write enable
mov ds:[esi], al
nop
call JEDEC_Series_Reset
clc
ret
SST_49LF002_Write_Enable endp
JEDEC_Series_Reset:
mov byte ptr es:[edi+5555h], 0AAh
mov byte ptr es:[edi+2AAAh], 055h
mov byte ptr es:[edi+5555h], 0F0h
mov byte ptr es:[edi], 0FFh
Call delay_Wait ; wait 10 ms until tww expires
ret
Erase_Entire_Chip proc near
mov es:byte ptr [edi+5555h], 0AAh ; issue 6-byte chip
mov es:byte ptr [edi+2AAAh], 055h ; erase command sequence
mov es:byte ptr [edi+5555h], 080h
mov es:byte ptr [edi+5555h], 0AAh
mov es:byte ptr [edi+2AAAh], 055h
mov es:byte ptr [edi+5555h], 10h
mov cx,333*100
call Delay_wait ; insert delay = 100ms
ret
Erase_Entire_Chip endp
;-------------------------------------------------------------
Check_Toggle_Ready proc near
push ax ; save register
mov al,ds:[edi+0fff0h] ; read a byte form the chip
and al,40h ; mask out the TOGGLE bit (DQ6)
CTR_Tog2:
mov ah,ds:[edi+0fff0h]; read the same byte from the chip again
and ah, 40h ; mask out the TOGGLE bit (DQ6)
cmp al, ah ; is DQ6 still toggling?
je CTR_Tog3 ; No, then the write operation is done
xchg ah, al ; YES, then continue checking...
jmp short CTR_Tog2
CTR_Tog3:
pop ax ; restore register
ret
Check_Toggle_Ready endp
Enter_Protect_Mode proc near
cli
mov al,A20_On ;R31
call Switch_A20 ;R31
xor eax,eax
mov ax,@data
mov ds,ax
shl eax,4
add eax,offset GDT
mov dword ptr ds:GDT_OFFSET,eax
lgdt fword ptr ds:GDTR
mov eax,CR0
or al,1
mov CR0,eax
jmp short $+2
mov ax,DATA_INDEX
mov ds,ax
mov es,ax
ret
Enter_Protect_Mode endp
;-----------------------------------------------------------
Switch_A20 proc near
pusha
cmp al,A20_ON
jne Not_Enable_A20
push ax
mov al,02h
out 092h,al
pop ax
Not_Enable_A20:
shl eax,16 ;Save al
call Buffer_8042_Full
jnz short Switch_A20_Fail
mov al,0d1h
out STAT8042,al
call Buffer_8042_Full
jnz short Switch_A20_Fail
shr eax,16 ;Load al
out DATA8042,al
call Buffer_8042_Full
jnz short Switch_A20_Fail
mov cx,4
Wait_A20_Switch:
NEWIODELAY
loop Wait_A20_Switch
clc
jmp short Switch_A20_Success
Switch_A20_Fail:
stc
Switch_A20_Success:
popa
ret
Switch_A20 endp
;-----------------------------------------------------------
Buffer_8042_Full proc near
push cx
xor cx,cx
@@:
in al,STAT8042
NEWIODELAY
and al,IBF_8042 ;Input buffer full?
loopnz @B
pop cx
ret
Buffer_8042_Full endp
Leave_Protect_Mode proc near
mov eax,CR0
and al,not 1
mov CR0,eax
jmp short $+2
ret
Leave_Protect_Mode endp
;-----------------------------------------------------------
Use_32bit_Address proc
push es
call Enter_Protect_Mode ;use 4G high address
call Leave_Protect_Mode
pop es
ret
Use_32bit_Address endp
;-----------------------------------------------------------
Delay_Wait proc ;in cx=t delay t*33(us)
Delay_wait_0:
in al,61h
test al,010h
jnz Delay_wait_0
Delay_wait_1:
in al,61h
test al,010h
jz Delay_wait_1
loop Delay_wait_0
ret
Delay_Wait endp
;----------------------------------------------------
Ct_ROM_Write_Enable proc near;
pushad
mov cx,(PIIX_ID shl 8)+4eh ;cx =0f84eh
call Get_Ct ;get PCI register [8000f84e]
or al,01H ;flash write enabled
call Set_Ct ;set PCI register [8000f84e]
popad
RET
Ct_ROM_Write_Enable endp
;------------------------------------------------------------
GET_CT PROC NEAR
GET_PCI:
CONFIG_ADDR EQU 0cf8h
mov ax,8000H ;enable PCI config.
shl eax,16
mov ax,cx
and al,NOT 03h ;32 bit access for PCI
mov dx,CONFIG_ADDR ;index is 0cf8h
out dx,eax
add dl,4 ;start from 0cfch
mov al,cl
and al,03h
add dl,al ;byte index to read
in al,dx
ret
GET_CT ENDP
;-----------------------------------------------------------------------
SET_CT PROC NEAR
SET_PCI:
xchg ax,cx
shl ecx,16 ;save value
xchg ax,cx ;restore cx
mov ax,8000H ;enable PCI config.
shl eax,16
mov ax,cx
and al,NOT 03h ;32 bit access for PCI
mov dx,CONFIG_ADDR ;index is 0cf8h
out dx,eax
add dl,4 ;start from 0cfch
mov al,cl
and al,03h
add dl,al ;byte index to read
shr ecx,16 ;restore value
mov ax,cx
out dx,al
ret
SET_CT ENDP
;-------------------------------------------------------------
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -