Problem Description: After over several thousand reboots of Ivy Bridge + Panther Point PCH on ASUS motherboard with external ATI HD4350 PCIe Gfx card, the system fails. It comes complete to stop in the dead loop in the Option ROM of ATI HD4350 PCIe Gfx card.
Here is what is happening:
This, what you all are looking is part of Option ROM code which tests if BIOS INT 0x10/(or another BIOS INT) is called. It is very ugly problem I have experienced.
0xc000:0000000000004857 8a46ea mov al, byte ptr [bp - 0x16] ; address in bp-0x16 if BIOS INT in use??
0xc000:000000000000485a 32e4 xor ah, ah
0xc000:000000000000485c 85c0 test ax, ax ; test if al is 0?
0xc000:000000000000485e 0f8f8300 jnle $+0x0087 ;a=48e5, jump if NOT zero
What is in the al, upon first instruction gets executed?! It is a BIOS INT which is in use. In this case it is 0x00 (NO BIOS INT called, expected BIOS INT 0x10).
Then it doubles stack segment to relax use of code (moves stack segment ss to es), and then takes from the stack some address, probably some table address, where the whole table is also on the another part of the stack. Takes the element from the table, pushes it on the stack, then repeats unnecessary the address retrieval (which forces me to think that this code is obviously written in high language, presumably "C", and compiler compiled this with low optimization), then it has two domains to assess: if the byte on address in bx register is 0x5b, it will do local calculations.
0xc000:0000000000004862 8cd0 mov ax, ss
0xc000:0000000000004864 8b5eba mov bx, word ptr [bp - 0x46]
0xc000:0000000000004867 8ec0 mov es, ax
0xc000:0000000000004869 268b5f02 mov bx, word ptr es:[bx + 0x02]
0xc000:000000000000486d 895ee0 mov word ptr [bp - 0x20], bx
0xc000:0000000000004870 8b5eba mov bx, word ptr [bp - 0x46]
0xc000:0000000000004873 268b5f02 mov bx, word ptr es:[bx + 0x02]
Actually, it is searching/finding why this thread of execution is located here, but NO BIOS INT (it expects Video INT 0x10)! What is 0x5b? One of video modes for the card. Or maybe some error code from the video card. Not sure.
0xc000:0000000000004877 803f5b cmp byte ptr [bx], 0x5b
0xc000:000000000000487a 754a jnz $+0x4c ;a=48c6
0xc000:000000000000487c c646ea10 mov byte ptr [bp - 0x16], 0x10
As we see here, if NO BIOS INT at all, and error code = 0x5b, it will push back BIOS INT 0x10, video int to handle the cause/video mode:
What is 0x5b? One of video modes for the card. Or maybe some error code from the video card. Again, not sure.
If not 0x5b code found, it will call 3 functions, one after another (in desperate attempt to recover):
0xc000:00000000000048c6 8d46b8 lea ax, word ptr [bp - 0x48]
0xc000:00000000000048c9 e8cbfc call $-0x0332 ;a=4597
0xc000:00000000000048cc 8ad0 mov dl, al
0xc000:00000000000048ce 8d46b8 lea ax, word ptr [bp - 0x48]
0xc000:00000000000048d1 e82e00 call $+0x0031 ;a=4902
0xc000:00000000000048d4 8ada mov bl, dl
0xc000:00000000000048d6 32ff xor bh, bh
0xc000:00000000000048d8 c1e302 shl bx, 0x2
0xc000:00000000000048db 8d46b8 lea ax, word ptr [bp - 0x48]
0xc000:00000000000048de ff9710a4 call word ptr [bx - 0x5bf0] ; calling fixed location in Video legacy space: 0xa800
0xc000:00000000000048e2 e972ff jmp $-0x008b ;a=4857 ? jump back to start
I am just wondering if the last call is meaningful at all, since it cleans bh, and shifts bl two bits left. The maximum value in bx could be 0x03fc, let say 0x03f0 0x03f0 - 0x5bf0 = 0xa800. Yes, it does make sense, since it is probably calling video space above first 640KB (from 0xa000). It is last line of defense, last attempt for recovery, since it exhausted all other possibilities.
We need Video Card expert to look into this, because the following code is very interesting:
0xc000:000000000000487c c646ea10 mov byte ptr [bp - 0x16], 0x10 ; INT 10H, added
0xc000:0000000000004880 8b5eba mov bx, word ptr [bp - 0x46]
0xc000:0000000000004883 268b5f06 mov bx, word ptr es:[bx + 0x06]
0xc000:0000000000004887 895ef6 mov word ptr [bp - 0x0a], bx
0xc000:000000000000488a 8b5eba mov bx, word ptr [bp - 0x46]
0xc000:000000000000488d 268b1f mov bx, word ptr es:[bx]
0xc000:0000000000004890 8b4704 mov ax, word ptr [bx + 0x04]
0xc000:0000000000004893 32e4 xor ah, ah
0xc000:0000000000004895 8bc8 mov cx, ax
0xc000:0000000000004897 83c109 add cx, 0x9
0xc000:000000000000489a 32ed xor ch, ch
0xc000:000000000000489c 80e1fe and cl, 0xfe
0xc000:000000000000489f 03e1 add sp, cx
0xc000:00000000000048a1 8b5ef6 mov bx, word ptr [bp - 0x0a]
0xc000:00000000000048a4 895eba mov word ptr [bp - 0x46], bx
0xc000:00000000000048a7 85db test bx, bx
0xc000:00000000000048a9 74ac jz $-0x52 ;a=4857 ; goes back, now it has in byte ptr [bp - 0x16] value 0x10 (Video INT)
0xc000:00000000000048ab 268b1f mov bx, word ptr es:[bx]
0xc000:00000000000048ae 8b4704 mov ax, word ptr [bx + 0x04]
0xc000:00000000000048b1 c1e808 shr ax, 0x8
0xc000:00000000000048b4 32e4 xor ah, ah
0xc000:00000000000048b6 247f and al, 0x7f
0xc000:00000000000048b8 c1e802 shr ax, 0x2
0xc000:00000000000048bb c1e002 shl ax, 0x2
0xc000:00000000000048be 8b5eb8 mov bx, word ptr [bp - 0x48]
0xc000:00000000000048c1 262907 sub word ptr es:[bx], ax
0xc000:00000000000048c4 eb91 jmp $-0x6d ;a=4857 back, now it has in byte ptr [bp - 0x16] value 0x10 (Video INT)
In ANY case, the next pass from the top will skip the loop.
It is obvious that entering this code is with NO BIOS INT invoked, and no 0x5b found in the table (maybe expects 0x5b as video parameter).
In nutshell: It checks why the thread of exec. is there... It checks the BIOS INT location, finds that there was NO BIOS INT inserted (it expects BIOS INT 0x10 int), and immediately after checks what is gfx mode, or error code... If it finds that the code is 0x5b, it then artificially inserts INT 0x10, as BIOS INT 0x10 infact occured, and tries to play with that.
Somebody who is an Option ROM video expert should know what are these conditions and what is wrong here from the Video domain point!
Truth is Death, and Lie - Life!
05:38 AM by