DOS下读取spd信息的汇编程序(通过SMBus)

汇编程序编写的读取spd信息的代码:

  1 ;-----------------------------------------------------------
  2 ;功能: 通过SMbus 读取内存的SPD 信息
  3 ;时间: 2015/09
  4 ;环境: DOS + MASM5
  5 ;说明: 代码中涉及的smbus规范是基于Intel平台
  6 ;---------------------------------------------------------
  7 ;功能: 显示ascii 表示的字符
  8 echoch macro ascii
  9     mov ah,2
 10     mov dl,ascii
 11     int 21h
 12     endm
 13 ;---------------------------------------------------------
 14     .386P
 15 ;-------------------- data segment ---------------------------------
 16 dseg segment use16
 17     busnum dw 0000h  ;总线号0 - 00FFh
 18     devnum dw 001fh  ;设备号0 - 001Fh
 19     funnum dw 0007h  ;功能号0 - 0007h
 20     regnum dw 00ffh  ;寄存器0 - 00FFh
 21     ; 
 22     sm_base   dw 0000h ;存放smbus 基地址
 23     sm_devnum dw 0000h   ;a0/a2/a4/a6
 24     sm_regnum dw 0000h   ;
 25     ;
 26     bufferlen = 128
 27     buffer db bufferlen dup(0) ;存放spd  128-byte的信息
 28     buffer1 db 'smbus base address :'
 29     buffer2 db 'device index :'
 30 dseg ends
 31 ;-------------------- data segment end ----------------------------------
 32 ;-------------------- code segment ---------------------------------
 33 cseg segment use16
 34     assume cs:cseg, ds:dseg
 35 start:
 36     mov ax,dseg
 37     mov ds,ax
 38     ;----------------------扫描PCI ---------------------
 39     mov busnum,0000h
 40     mov devnum,0000h
 41     mov funnum,0000h
 42     mov regnum,0000h
 43 nextreg:    
 44     call pci_read     ;读取pci 配置空间的前4 个字节
 45     cmp ax,0ffffh     ;判断设备是否存在
 46     jz nextfun        ;不存在,跳到下一个fun
 47     ;
 48     add regnum,08h    ;读class code
 49     call pci_read
 50     and eax,0ffffff00h
 51     cmp eax,0c050000h ;根据class code 判断SMbus Controller( 0c0500 )
 52     jz find           ;是SMbus Controller
 53 nextfun:
 54     mov regnum,0000h
 55     inc funnum
 56     cmp funnum,0007h
 57     ja nextdev        ;funnum 大于 7,跳到下一个dev        
 58     jmp nextreg    
 59 nextdev:
 60     mov regnum,0000h
 61     mov funnum,0000h
 62     inc devnum
 63     cmp devnum,001fh 
 64     ja nextbus      ;devnum 大于 1fh,跳到下一个bus    
 65     jmp nextreg
 66 nextbus:
 67     mov regnum,0000h
 68     mov funnum,0000h
 69     mov devnum,0000h
 70     inc busnum
 71     cmp busnum,0005h
 72     ja notfind        ;busnum 大于5,没找到SMbus Controller --结束
 73     jmp nextreg
 74 
 75     ;--------------------找到SMbus  Controller-------------------
 76 find:
 77     sub regnum,08h
 78     add regnum,20h  ;SMbus 的基地址在pci 配置空间中的偏移地址
 79     call pci_read   ;读取SMbus 的基地址
 80     and ax,0fffeh   ;1111_1111_1111_1110,最后一位1 :表示端口方式
 81     mov sm_base,ax  ;把基地址保存到sm_base
 82     ;
 83     ;-----------------------打印smbus 的基地址------------
 84     mov dx,offset buffer1
 85     mov cx,20
 86     mov ah,40h    
 87     int 21h
 88     ;
 89     mov ax,sm_base
 90     shr ax,8
 91     push ax
 92     shr al,4     
 93     call toascii 
 94     echoch al
 95     pop ax
 96     call toascii  
 97     echoch al
 98     ;
 99     mov ax,sm_base
100     push ax
101     shr al,4 
102     call toascii 
103     echoch al
104     pop ax
105     call toascii  
106     echoch al
107     echoch 0dh  ;换行
108         echoch 0ah
109     ;--------------------读smbus  设备的SPD ----------------
110     mov sm_devnum,00a0h   ;设备a0
111     ;
112 nextd:
113     mov sm_regnum,0000h
114     mov dx,offset buffer2
115     mov cx,14
116     mov ah,40h    
117     int 21h
118     ;
119     mov ax,sm_devnum
120     push ax
121     shr al,4 
122     call toascii
123     echoch al
124     pop ax
125     call toascii 
126     echoch al    
127     echoch ' '
128     ;
129     call sm_read      ;读128-byte 的spd,存入buffer , 并显示buffer
130     echoch 0dh        ;换行
131         echoch 0ah
132         add sm_devnum,2   ;设备号a0/a2/a4/a6
133         cmp sm_devnum,0a8h
134         jl nextd          ;小于,循环
135         ;----------------------------------------
136     ;--------------结束,返回DOS -------------
137 notfind:
138     mov ah,4ch
139     int 21h
140 ;---------------------------------------------
141 ;------------------子程序----------------
142 ;----------------------------------------
143 ;功能: 通过smbus IO registers 读取spd 信息,并存入buffer
144 ;入口: 
145 ;
146 sm_read proc
147     push dx
148     push ax
149     ;
150     mov ax,dseg           ;设置目的地址(buffer 的地址)
151     mov es,ax             ;段地址为数据段地址
152     mov di,offset buffer  ;偏移地址为缓冲区的偏移地址
153 nextch:
154     ;----------smbus 访问规范--------
155     call iodelay
156     mov dx,sm_base  ;SMbus 的基地址
157     add dx,00h      ;status register
158     mov al,0feh     ;
159     out dx,al
160     call iodelay    ;延时
161     ;
162     mov dx,sm_base
163     add dx,04h       ;slave address register
164     mov ax,sm_devnum ;从设备地址:a0/a2/a4/a6  ,
165     or al,01h        ;末位:1 - 表示读
166     out dx,al
167     call iodelay
168     ;
169     mov dx,sm_base
170     add dx,03h       ;command register
171     mov ax,sm_regnum ;寄存器索引
172     out dx,al  
173     call iodelay
174     inc sm_regnum
175     ;
176     mov dx,sm_base
177     add dx,02h       ;control register
178     mov al,48h       ;设置读写模式:字节(48h)、字(4ch)、块(54h)
179     out dx,al
180     call iodelay
181     call iodelay
182     ;
183     mov dx,sm_base
184     add dx,00h
185     in al,dx
186     cmp al,04h       ;判断读结果
187     jz enderr        ;读出错,设备不存在,返回
188     ;
189     mov dx,sm_base
190     add dx,05h      ;data0 register
191     in al,dx        ;回读数据
192     mov es:[di],al  ;数据保存到buffer 中
193     inc di
194     cmp sm_regnum,7fh
195     ja endsm        ;128-byte  读完
196     jmp nextch
197 endsm:                    ;读完结束,打印buffer 后,结束
198     call print_buffer
199     pop ax
200     pop dx
201     ret
202 enderr:                 ;读出错结束,直接退出
203     pop ax
204     pop dx          
205     ret
206 sm_read endp
207 ;--------------------------------------------------
208 ;功能:延时,等待外设把数据准备好
209 ;
210 iodelay proc
211     push cx
212     mov cx,0ffffh
213 delay:
214     loop delay
215     mov cx,0ffffh
216 delay1:
217     loop delay1
218     pop cx
219     ret
220 iodelay    endp
221 ;---------------------------------------------
222 ;功能: 根据eax中的地址读取pci的配置空间,并存入eax
223 ;入口: busnum、devnum、funnum、regnum
224 ;出口: eax
225 ;
226 pci_read proc
227     ;protect register
228     push ebx     
229     push dx
230     ;clear
231     xor eax,eax
232     xor ebx,ebx
233     ;enable
234     add eax,1h
235     shl eax,31
236     ;bus number
237     mov ebx,ds:[00]
238     and ebx,0ffh
239     shl ebx,16
240     add eax,ebx
241     ;device number
242     xor ebx,ebx
243     mov ebx,ds:[02]
244     and ebx,0ffh
245     shl ebx,11
246     add eax,ebx
247     ;function number
248     xor ebx,ebx
249     mov ebx,ds:[04]
250     and ebx,0ffh
251     shl ebx,8
252     add eax,ebx
253     ;register
254     xor ebx,ebx
255     mov ebx,ds:[06]
256     and ebx,0ffh
257     add eax,ebx
258     ;read IO
259     mov dx,0cf8h
260     out dx,eax
261     mov dx,0cfch
262     in eax,dx
263     ;resume register
264     pop dx
265     pop ebx    
266     ret
267 pci_read endp
268 ;----------------------------------------------
269 ;功能:打印buffer的内容(以ascii 形式)
270 ;
271 print_buffer proc
272     push ax
273     push ds
274     push si
275     push cx
276     push bp
277     ;
278     mov ax,dseg      ;设置源地址(buffer 的地址)
279     mov ds,ax
280     mov si,offset buffer
281         mov cx,bufferlen
282         cld
283 nextline3:
284     dec cx
285         echoch 0dh  
286         echoch 0ah
287         mov bp,16  
288 nextch3:    
289     lodsb            ;加载一个字节到al
290     ;
291     push ax
292     shr al,4 
293     call toascii
294     echoch al
295     pop ax
296     call toascii 
297     echoch al    
298     echoch ' '
299     ;
300     dec bp
301         jz nextline3
302     loop nextch3
303     ;
304     pop bp     ;出栈顺序与入栈顺序相反
305     pop cx
306     pop si
307     pop ds
308     pop ax
309     ret
310 print_buffer endp
311 ;----------------------------------------
312 ;功能:把al 的低4位转成ascii码,并存入al
313 ;入口: al
314 ;出口: al
315 toascii proc
316     and al,0fh  ;高四位清零
317     add al,90h  ;1001_xxxx
318     daa
319     adc al,40h
320     daa
321     ret
322 toascii endp
323 ;-------------------------------------------
324 cseg ends
325 ;------------- code segment end --------------------------
326     end start

 

posted @ 2017-09-21 20:11  zhuqingzhu  阅读(1514)  评论(0编辑  收藏  举报