Запись в чип BIOS используя SPI

Тема в разделе "WASM.OS.DEVEL", создана пользователем acckiitvar, 18 дек 2011.

  1. acckiitvar

    acckiitvar Member

    Публикаций:
    0
    Регистрация:
    26 сен 2011
    Сообщения:
    71
    Здравствуйте, надо записать информацию в чип биос, или хотя бы его стереть(чип). Южный мост ICH8, чип MATRONIX MX25L1605. Использовал следующую процедуру для стирания:
    Код (Text):
    1. org 100h
    2. use16
    3.  
    4.     ;open a20 line
    5.     in al, 92h
    6.     or al, 02h
    7.     out 92h, al
    8.    
    9.     mov eax, cs
    10.     mov ds, ax
    11.    
    12.     ;save old_cs
    13.     mov ax, cs
    14.     mov [ds:old_cs], ax
    15.  
    16.     ;save real mode return point
    17.     mov word [ds:offset_r_mode], r_mode
    18.    
    19.     ;init code 32 descr
    20.     mov eax, cs
    21.     shl eax, 4
    22.     mov edi, descr8+2
    23.     mov [ds:edi], ax
    24.     bswap eax
    25.     inc edi
    26.     inc edi
    27.     mov [ds:edi], ah
    28.    
    29.     ;init code 16 descr
    30.     mov eax, dword [ds:descr8+2]
    31.     mov dword [ds:descr18+2], eax
    32.        
    33.     ;calculating linear address of GDT
    34.     mov eax, cs
    35.     shl eax, 4
    36.     mov [ds:GdtLinAdr], eax
    37.     add [ds:GdtLinAdr], descr0
    38.    
    39.     cli
    40.     lgdt fword [ds:GdtSize]
    41.     mov eax, cr0
    42.     or  al, 1
    43.     mov cr0, eax
    44.     jmp 08h:p_mode32
    45.  
    46. use32   ;32 bit protected mode
    47. p_mode32:
    48.     mov al, 1
    49.     out 80h, al
    50.    
    51.     mov cx, 10h ;32 bit data descr
    52.     mov ds, cx
    53.     mov es, cx
    54.     mov ss, cx
    55.    
    56.     call ClearFlash
    57.    
    58.     mov cx, 20h ;16 bit data decsr
    59.     mov ds, cx
    60.    
    61.     db 0eah
    62.     dd pm16
    63.     dw 18h  ;16 bit code descr
    64.  
    65. pm16:
    66. use16  
    67.     mov eax, cr0
    68.     btr eax, 0
    69.     mov cr0, eax
    70.     db 0eah
    71.     offset_r_mode  dw 11           ;jmp 08h:r_mode
    72.     old_cs    dw 0                
    73. r_mode:
    74.     sti
    75.     mov ax, cs
    76.     mov ds, ax
    77.     mov es, ax
    78.     mov ss, ax
    79.  
    80.     mov ax, 4c00h
    81.     int 21h
    82.  
    83. use32  
    84. GetPCIDword:
    85.     push edx
    86.     mov edx,0cf8h
    87.     out dx, eax
    88.    
    89.     mov edx,0cfch
    90.     in eax, dx
    91.     pop edx
    92.     ret
    93.  
    94. GetRCBA:
    95.     mov eax, 8000F8F0h
    96.     call GetPCIDword
    97.     ret
    98.  
    99. ReadBiosCntlReg:
    100.     push edx
    101.     mov eax, 8000F8DCh
    102.     mov edx,0cf8h
    103.     out dx, eax
    104.        
    105.     mov edx,0cfch
    106.     in al, dx
    107.     pop edx
    108.     ret
    109.  
    110. ScanOpcodeMenu:
    111.     push ecx
    112.     push edx
    113.     mov ecx,[ds:ebx+098h]   ; ECX=OpCode menu, bytes 0-3
    114.     mov edx,[ds:ebx+09Ch]   ; EDX=OpCode menu, bytes 4-7
    115.     mov ah,al           ; AH = Pattern for compare
    116.     mov al,0            ; Position counter = 0
    117. Scan_OpCode:   
    118.     cmp cl,ah
    119.     je  Exit_OpCode     ; Exit if match, also CF=0(NC)
    120.     shrd    ecx,edx,8
    121.     shr edx,8           ; Shift OpCodes
    122.     inc ax
    123.     cmp al,8
    124.     jb  Scan_OpCode
    125.     stc             ; CF=1(NC) if not found
    126. Exit_OpCode:   
    127.     pop edx
    128.     pop ecx
    129.     ret
    130.  
    131. ScanPrefixMenu:
    132.     push dx
    133.     mov dx,[ds:ebx+94h]     ; DX = Prefix Config. reg.
    134.     mov ah,al           ; AH = Pattern for compare
    135.     mov al,0
    136.     cmp dl,ah           ; Compare position [0]
    137.     db 66h
    138.     je  Exit_Prefix     ; Go if position [0] match
    139.     inc ax
    140.     cmp dh,ah           ; Compare position [1]
    141.     db 66h
    142.     je  Exit_Prefix     ; Go if position [1] match
    143.     stc             ; CF=1(NC) if not found
    144. Exit_Prefix:   
    145.     pop dx
    146.     ret
    147.  
    148.  
    149. ;-------------------------------------------------------------;
    150. ; Wait for Flash ROM ready, use BUSY bit in the status reg.   ;
    151. ; Input:   DS:EBX = Base address of RCBA\SPIBAR               ;
    152. ; Output:  CF = Error flag:                                   ;
    153. ;          0(NC) = Flash EPROM ready                          ;
    154. ;          1(C)  = Flash EPROM timeout or access error        ;
    155. ;-------------------------------------------------------------;
    156. Wait_Flash_Ready:
    157.         push ecx
    158.         push eax
    159.         xor cx,cx
    160. Wait_Erase:
    161.         push cx
    162.         mov al,05h      ; 05h = Read Status command
    163.         call ScanOpcodeMenu
    164.         jc  Ready_Error_1   ; Go if missing opcode error
    165.         and eax,7       ; Select bit field
    166.         shl eax,12      ; Positioning bit field
    167.         or  eax,00400200h   ; EAX = Command for ICH8 (Read Status)
    168.         xor ecx,ecx     ; ECX = Address = 0
    169.         call Read_SPI   ; Output EAX=Data
    170.         xchg ax,cx
    171. Ready_Error_1: 
    172.         pop cx
    173.         jc  Ready_Error
    174.         test    al,00000001b    ; Check BUSY bit
    175.         loopnz  Wait_Erase
    176.         jnz Ready_Error ; Exit if timeout error
    177. ;--- Exit points ---
    178.         clc         ; CF=0(NC) means no errors
    179.         pop eax
    180.         pop ecx
    181.         ret
    182. Ready_Error:   
    183.         stc         ; CF=1(C) means error
    184.         pop eax
    185.         pop ecx
    186.         ret
    187.  
    188. ;---------------------------------------------------------;
    189. ; Write Command to SPI EPROM (for Intel ICH8)             ;
    190. ; Input:   EAX = Operation code (status+control)          ;
    191. ;          ECX = Address in the SPI flash device          ;
    192. ;          EDX = Data pattern                             ;
    193. ;          DS:EBX = Base address of RCBA\SPIBAR           ;
    194. ; Output:  CF = Error flag: 0(NC)=OK, 1(C)=Error          ;
    195. ;---------------------------------------------------------;
    196. Write_SPI:
    197.         pushad
    198.         ;--- Pre-clear status ---
    199.         mov byte [ds:ebx+090h],00001100b
    200.         test byte [ds:ebx+090h],00001101b
    201.         jnz @@SPI_Wr_Error      ; Still active ?
    202. ;--- Prepare data pattern ---
    203.         mov [ds:ebx+010h],edx
    204.         cmp [ds:ebx+010h],edx
    205.         jne @@SPI_Wr_Error      ; Not writeable ?
    206. ;--- Set address for SPI ---
    207.         mov [ds:ebx+008h],ecx
    208. ;--- Start command ---
    209.         mov [ds:ebx+090h],eax
    210. ;--- Wait for operation complete ---
    211.         push    ecx
    212.         mov ecx,00200000h
    213. @@SPI_Wait_W:  
    214.         mov al,[ds:ebx+90h]     ; Read status
    215.         mov ah,al
    216.         and al,00000101b        ; D2=Done, D0=Progr.
    217.         cmp al,00000100b
    218.         loopne  @@SPI_Wait_W        ; Cycle for wait
    219.         pop ecx
    220.         jne @@SPI_Wr_Error      ; Timeout ?
    221. ;--- Check status ---
    222.         test    ah,00011000b        ; D4=AEL, D3=FCERR
    223.         jnz @@SPI_Wr_Error      ; Error flags set ?
    224. ;--- Post-clear status ---
    225.         mov BYTE [ds:ebx+090h],00001100b
    226.         test    BYTE [ds:ebx+090h],00001101b
    227.         jnz @@SPI_Wr_Error      ; Still active ?
    228. ;--- Exit points ---
    229. @@SPI_Wr_Ok:   
    230.         clc             ; CF=0(NC) means no errors
    231.         popad
    232.         ret
    233. @@SPI_Wr_Error:
    234.         stc             ; CF=1(C) means error
    235.         popad
    236.         ret
    237.  
    238. ;***********************************************************
    239. ; Процедура чтения двойного слова с использованием SPI
    240. ; Вход:  ebx - SPIBAR
    241. ;        ecx - смещение от начала чипа
    242. ;        eax - сформированная команда чтения
    243. ; Выход: eax - данные
    244. ;       в случае ошибки cf = 1
    245. ;***********************************************************
    246. Read_SPI:
    247.     push ecx
    248.     mov byte [ds:ebx+90h], 00001100b
    249.     test byte [ds:ebx+90h], 00001101b
    250.     jnz SPI_Rd_Err
    251.     mov dword [ds:ebx+08h], ecx ; set address
    252.     mov dword [ds:ebx+90h], eax ; start command
    253.     push cx
    254.     xor cx, cx
    255. SPI_Wait_R:
    256.     mov al, byte [ds:ebx+90h] ; get status register
    257.     mov ah, al
    258.     and al, 00000101b
    259.     cmp al, 00000100b
    260.     loopne SPI_Wait_R
    261.     pop cx
    262.     jne SPI_Rd_Err
    263.     test ah, 00011000b
    264.     jnz SPI_Rd_Err
    265.     mov byte [ds:ebx+90h], 00001100b
    266.     test byte [ds:ebx+90h], 00001101b
    267.     jnz SPI_Rd_Err
    268.     mov eax, dword [ds:ebx+10h]
    269.     pop ecx
    270.     clc
    271.     ret
    272. SPI_Rd_Err:
    273.     pop ecx
    274.     stc
    275.     ret
    276.  
    277. ClearFlash:
    278.     push edx
    279.     mov eax, 8000F8DCh
    280.     mov edx,0cf8h
    281.     out dx, eax
    282.     mov edx,0cfch
    283.     in al, dx
    284.     or al, 1
    285.     out dx, al
    286.     pop edx
    287.    
    288.  
    289.     call GetRCBA
    290.     test eax, 1
    291.     jz @@error
    292.     ;spibar
    293.     lea ebx, [eax+3020h-1]
    294.    
    295.     ;формируем команду
    296.     mov al, 20h ; erase sector
    297.     call ScanOpcodeMenu
    298.     jc @@error
    299.     and eax, 7
    300.     shl eax, 12
    301.     xchg ecx, eax
    302.     mov al, 06h
    303.     call ScanPrefixMenu
    304.     jc @@error
    305.     and eax, 1
    306.     shl eax, 11
    307.     or eax, ecx
    308.     or eax, 0600h
    309.    
    310.    
    311.     xor edx, edx
    312.     mov ecx, 180000h
    313.     call Write_SPI
    314.     jc @@error
    315.     call Wait_Flash_Ready
    316.     jc @@error
    317.     clc
    318.     ret
    319. @@error:
    320.     stc
    321.     ret
    322. ;   ////////////////////////////////////////////////////////////////////////   
    323.    
    324. descr0      db 0,0,0,0,0,0,0,0;
    325. descr8      db 0ffh,0ffh,0,0,0,09ah,04fh,0;32 code
    326. descr10     db 0ffh,0ffh,0,0,0,092h,0cfh,0;32  data
    327. descr18     db 0ffh,0ffh,0,0,0,09ah,0fh,0; 16 code
    328. descr20     db 0ffh,0ffh,0,0,0,092h,8fh,0; 16 data
    329. descr28     db 0ffh,0ffh,0,0,0,09ah,2fh,0 ; 64 code
    330. descr30     db 0ffh, 0ffh, 0h, 0h, 0h, 9fh, 4fh, 0h;    32-bit compatibility mode
    331.  
    332. GdtSize             dw  8*7
    333. GdtLinAdr           dd  0
    Но приходит ошибка, почему не понимаю. С помощью процедуры Read_SPI я читаю чип нормально, а записать никак не могу. Состояние регистра BIOS CONTROL (B0:lol: 31:F0:off 0DCh) 1h. Сделал дампы регистров до и после подачи команды. Может кто уже сталкивался с этой проблемой?
    Также не очень понимаю значения регистров защиты по смещению 50h. Просветите пожалуйста

    Не крепится архив, там дампы, их частичный анализ и даташит на чип. http://zalil.ru/32310187