nasm 汇编写的微码程序
[bits 32]
;Nasm Microcode Update 工具
;
;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
;
; vL isqjIi rs rIXjsIk iigviiiiVdii SJJsZLJsV iijvr E U Yi i
; uBBs bQ B B XQ Bi viBqvrJiVqii BRi iBi iQg YUBSi ukiiB iSBB sSjBBkXr iBB BB vB
; KP B B Bid Vv BQv g Ii Qiiii BgiiiBiiiQM viBiu i B Bi Bv dq BBQBB
; sgBi iYiEBi XBr BB iQ B Pr iiiiv iUi iBi iI diZ B ii B Bv uDiurMB ii i i i
; is Bi Bi B ZI Bvg gi vidYiEdEgv vYvPSBuDjvv BiR B ii B JQD dv Qi
; kBiE B B Rrv vQ iBB B B Q B MB B UBv B B B sYvPBs B KBB
; BMBQiikBBQBq ivvsiB Vg vB JB iQ iB Br UQL B RD B B B iB iB uZk gM
; irriiiiii ii i virrrrrirrrr v r r i Ji r ii
;
;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
;
;
;=============================
; **** 微码升级函数说明 ****
;=============================
; 微码升级函数
; 00h 返回函数支持信息
; 01h 写一个升级数据区
; 02h 全面控制读取升级
; 03h 读一个升级数据区
; int 15h 函数
;=============================
; 函数00H 测试
;=============================
; 入口
; AX 0D042H 函数代码
; BL 00H 子函数
; 出口
; CF 进位
; AH 返回代码
; AL 加OEM信息
; EBX INTE 部分
; ECX LPEP 部分
; EDX 读入版本
; SI 升级计数
; 返回代码
; SUCCESS 函数已经完成
; NOT_IMPLEMENTED 函数不可用
;=============================
;函数01H 写微码升级数据
;=============================
; 入口
; AX 0D042H 函数代码
; BL 01 写升级
; ES:DI 读指针模式到intel升级结构,缓冲2048字节长
; 处理器支持仅适合尺寸的微码升级
; CX 实模式64K字节RAM块1
; DX 实模式64K字节RAM块2
; SI 实模式64K字节RAM块3
; SS:SP 32k最小堆栈空间
; 出口
; CF 进位设置和清除
; AH 结构调用
; AL 加oem信息
; 返回代码
; SUCCESS 函数正确完成
; NOT_IMPLEMENTED 函数不可用
; WRITE_FAILURE 写入存储设备错
; ERASE_FAILURE 擦除存储设备错
; READ_FAILURE 读取存储设备错
; STORAGE_FULL 那是因为从BIOS系统中不能读取升级数据块
; CPU_NOT_PRESENT 当前单步处理在系统中不存在
; INVALID_HEADER BIOS 升级头或读入版本错
; INVALID_HEADER_CS 升级求和中断
; SECURITY_FAILURE 处理弹出升级
; INVALID_REVISION
;函数02H 微码升级控制
;================================
; 入口
; AX 0D042H 函数代码
; BL 02 控制升级
; BH Task 看描述
; CX 实模式64K字节RAM块1
; DX 实模式64K字节RAM块2
; SI 实模式64K字节RAM块3
; SS:SP 32k最小堆栈空间
; 出口
; CF 进位设置和清除
; AH 结构调用
; AL 加oem信息
; BL 打开或关闭结构
; 返回代码
; SUCCESS 函数正确完成
; READ_FAILURE 读储存设备特性
;函数03H 读微码升级数据
;================================
; 入口
; AX 0D042H 函数代码
; BL 03 读取升级
; ES:DI 实模式指针到intel升级结构写二进制数据
; ECX 实模式64K字节RAM块1
; ECX 实模式64K字节RAM块2
; DX 实模式64K字节RAM块3
; SI 读取升级索引块,这值基值0,必须测试函数后升级计数
; SS:SP 32k最小堆栈空间
; 出口
; CF 进位设置和清除
; AH 结构调用
; AL 加oem信息
; BL 打开或关闭结构
; 返回代码
; SUCCESS 函数正确完成
; READ_FAILURE 读储存设备特性
; UPDATE_NUM_INVALID 升级最大数不可用
; NOT_EMPTY 指定升级块子块储存一个微码升级值
; 这指定块不是一个头块和不为空
;返回代码值
;====================================================================
;SUCCESS 00h 这函数正确完成
;NOT_IMPLEMENTED 86h 这函数不可用
;ERASE_FAILURE 90h 擦除储存设备特性
;WRITE_FAILURE 91h 写入储存设备特性
;READ_FAILURE 92h 读取储存设备特性
;STORAGE_FULL 93h 在BIOS系统中不能记录,因为可用升级块填充需要处理
;CPU_NOT_PRESENT 94h 当前单步处理在系统里不存在
;INVALID_HEADER 95h 升级头或读入版本没记录在BIOS
;INVALID_HEADER_CS 96h 升级求和值不正确
;NOT_EMPTY 9ah 指定升块记录一个升级微码块在多块
; 指定块没有头和不为空
;
;=============================
; **** 说明结束 ****
;=============================
;===================
;功能函数返回代码值
;===================
SUCCESS eq 00h ;这函数正确完成
NOT_IMPLEMENTED eq 86h ;这函数不可用
ERASE_FAILURE eq 90h ;擦除储存设备特性
WRITE_FAILURE eq 91h ;写入储存设备特性
READ_FAILURE eq 92h ;读取储存设备特性
STORAGE_FULL eq 93h ;在BIOS系统中不能记录,因为可用升级块填充需要处理
CPU_NOT_PRESENT eq 94h ;当前单步处理在系统里不存在
INVALID_HEADER eq 95h ;升级头或读入版本没记录在BIOS
INVALID_HEADER_CS eq 96h ;升级求和值不正确
NOT_EMPTY eq 9ah ;指定升块记录一个升级微码块在多块
;==================
; 实模式下执行工具
;==================
datasize db 00000000h
header db 48 dup (?)
mdata db 2000 dup (?)
%define totalsize (TotalS - DataS + 48)
ISTRUC Update
HeaderVersion dw 0
UpdateRevislon dw 0
Date dw 0
ProcessorSign dw 0
Checksum dw 0
LoaderRevison dw 0
ProcessorFlags dw 0
DataSize dw 0
TotalSize dw 0
Reserved dw 0,0,0
UpdateData db 2000 dup (?)
ExtSignCount dw 0
ExtChecksum dw 0
Reserved1 dw 0,0,0
ProcessorSign dw 0
ProcessorFlags dw 0
Checksum dw 0
IEND
; 处理信号值
;====================================
procSign:
mov eax,01
cpuid
mov ProcessorSign,eax
%if (Update.HeaderVersion == 00000001h)
; 首先检查处理信号段
%if (ProcessorSign == Update.ProcessorSign)
call Success
;如果有扩展信号
%else if (Updte.TotalSize > (Update.DataSize + 48)
;
;指定数据尺寸,用于计算 Update.ProcessorSign[0] 地址
;
%for (n=0,((N < Update.ExtSignCount) and (ProcessorSign != Update.ProcessorSign), n++)
;
; 如果循环计数结束,那么数字进处理信号表
;
%if (N < Update.ExtSignCount)
call success
%else
call Fail
%endif
%endif
%else
call Fail
%endif
%else
Fail
%endif
ret
Success:
ret
Fail:
ret
; 64 位模式
; r0 模式
;
; 处理标志测试
;======================================
procFlag:
mov rcx,017h
rdmsr
shl edx,11
shr edx,11 + 8
mov Flag,edx
; 处理标志 Flag 可能值
; 000 处理标志 0
; 001 处理标志 1
; 010 处理标志 2
; 011 处理标志 3
; 100 处理标志 4
; 101 处理标志 5
; 110 处理标志 6
; 111 处理标志 7
%if (Update.HeaderVersion == 00000001h)
%if (Update.ProcessorFlags & Flag)
LoadUpdate
%else
;
; 数据尺寸用于计算升级地址,为 Update.ProcessorSignature[N]
; 和 Update.ProcessorSignature[N]已经正确
;
%if (Update.ProcessorFlags[0] & Flag)
LoadUpdate
%endif
%endif
%endif
ret
; 求和测试
;==================================
micrcodeSum:
mov N,512
%if (Update.DataSize != 00000000h)
div Update.TotalSize,4
mov N,eax
mov ChkSum,0
for (I==0,I<N,I++)
add ChkSum + MicrocodeUpdate[I]
%if (ChkSum == 00000000h)
call Success
%else
call Fail
%endif
%endif
ret
; Loader EAX 为升级数据地址
; EDX 为0
; ECX 为79h (IA32_BIOS_UPDT_TRIG 地址)
; 简单的微码升级器
;====================================
MicroCodeUpLoader:
mov ecx,79h
xor eax,eax
xor ebx,ebx
mov ax,cs
shl eax,4
mov bx,offset Update
add eax,ebx
add eax,48d
xor edx,edx
wrmsr
ret
; 升级保留接收汇编代码
;======================================
UpdateSign:
mov ecx,08bh ;IA32_BIOS_SIGN_ID
xor eax,eax ;清除 EAX
xor edx,edx ;清除 EDX
wrmsr ;在地址8bh读入0到MSR
mov eax,1
cpuid
mov ecx,08bh ;IA32_BIOS_SIGN_ID
rdmsr ;读指定寄存器模式
ret
mov z,Update.UpdateRevislon
call UpdateSign
mov x,edx
ret
; 编码升级
;======================================
micrcodeUpdate:
%if (z > x)
;读入升级
call UpdateSign
mov y,edx
%if (z == y)
call Success
%else
call Fail
%endif
%else
call Fail
%endif
ret