⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _cpuinfo.asm

📁 AT91RM9200-U-Boot at91rm9200u-boot移植源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

        enter_c

        xor     eax, eax            ; Set up for CPUID instruction
        mCPU_ID                     ; Get and save vendor ID
        cmp     eax, 1              ; Make sure 1 is valid input for CPUID
        jl      @@Fail              ; We dont have the CPUID instruction
        xor     eax, eax
        inc     eax
        mCPU_ID                     ; Get family/model/stepping/features
        and     eax, 0F0h
        shr     eax, 4              ; Isolate model
@@Done: leave_c
        ret

@@Fail: xor     eax,eax
        jmp     @@Done

cprocend

;----------------------------------------------------------------------------
; uint _CPU_getCPUIDStepping(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart  _CPU_getCPUIDStepping

        enter_c

        xor     eax, eax            ; Set up for CPUID instruction
        mCPU_ID                     ; Get and save vendor ID
        cmp     eax, 1              ; Make sure 1 is valid input for CPUID
        jl      @@Fail              ; We dont have the CPUID instruction
        xor     eax, eax
        inc     eax
        mCPU_ID                     ; Get family/model/stepping/features
        and     eax, 00Fh           ; Isolate stepping
@@Done: leave_c
        ret

@@Fail: xor     eax,eax
        jmp     @@Done

cprocend

;----------------------------------------------------------------------------
; uint _CPU_getCPUIDFeatures(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart  _CPU_getCPUIDFeatures

        enter_c

        xor     eax, eax            ; Set up for CPUID instruction
        mCPU_ID                     ; Get and save vendor ID
        cmp     eax, 1              ; Make sure 1 is valid input for CPUID
        jl      @@Fail              ; We dont have the CPUID instruction
        xor     eax, eax
        inc     eax
        mCPU_ID                     ; Get family/model/stepping/features
        mov     eax, edx
@@Done: leave_c
        ret

@@Fail: xor     eax,eax
        jmp     @@Done

cprocend

;----------------------------------------------------------------------------
; uint _CPU_getCacheSize(void)
;----------------------------------------------------------------------------
; Determines the CPU cache size for Intel processors
;----------------------------------------------------------------------------
cprocstart  _CPU_getCacheSize

        enter_c
        xor     eax, eax            ; Set up for CPUID instruction
        mCPU_ID                     ; Get and save vendor ID
        cmp     eax,2               ; Make sure 2 is valid input for CPUID
        jl      @@Fail              ; We dont have the CPUID instruction
        mov     eax,2
        mCPU_ID                     ; Get cache descriptors
        LEA_L   esi,cache_id        ; Get address of cache ID (-fPIC aware)
        shr     eax,8
        mov     [esi+0],eax
        mov     [esi+3],ebx
        mov     [esi+7],ecx
        mov     [esi+11],edx
        xor     eax,eax
        LEA_L   esi,cache_id        ; Get address of cache ID (-fPIC aware)
        mov     edi,15
@@ScanLoop:
        cmp     [BYTE esi],41h
        mov     eax,128
        je      @@Done
        cmp     [BYTE esi],42h
        mov     eax,256
        je      @@Done
        cmp     [BYTE esi],43h
        mov     eax,512
        je      @@Done
        cmp     [BYTE esi],44h
        mov     eax,1024
        je      @@Done
        cmp     [BYTE esi],45h
        mov     eax,2048
        je      @@Done
        inc     esi
        dec     edi
        jnz     @@ScanLoop

@@Done: leave_c
        ret

@@Fail: xor     eax,eax
        jmp     @@Done

cprocend

;----------------------------------------------------------------------------
; uint _CPU_have3DNow(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart  _CPU_have3DNow

        enter_c

        mov     eax,80000000h       ; Query for extended functions
        mCPU_ID                     ; Get extended function limit
        cmp     eax,80000001h
        jbe     @@Fail              ; Nope, we dont have function 800000001h
        mov     eax,80000001h       ; Setup extended function 800000001h
        mCPU_ID                     ; and get the information
        test    edx,80000000h       ; Bit 31 is set if 3DNow! present
        jz      @@Fail              ; Nope, we dont have 3DNow support
        mov     eax,1               ; Yep, we have 3DNow! support!
@@Done: leave_c
        ret

@@Fail: xor     eax,eax
        jmp     @@Done

cprocend

;----------------------------------------------------------------------------
; ulong _CPU_quickRDTSC(void)
;----------------------------------------------------------------------------
; Reads the time stamp counter and returns the low order 32-bits
;----------------------------------------------------------------------------
cprocstart  _CPU_quickRDTSC

        mRDTSC
        ret

cprocend

;----------------------------------------------------------------------------
; void _CPU_runBSFLoop(ulong interations)
;----------------------------------------------------------------------------
; Runs a loop of BSF instructions for the specified number of iterations
;----------------------------------------------------------------------------
cprocstart  _CPU_runBSFLoop

        ARG     iterations:ULONG

        push    _bp
        mov     _bp,_sp
        push    _bx

        mov     edx,[iterations]
        mov     eax,80000000h
        mov     ebx,edx

        ALIGN   4

@@loop: bsf     ecx,eax
        dec     ebx
        jnz     @@loop

        pop     _bx
        pop     _bp
        ret

cprocend

;----------------------------------------------------------------------------
; void  _CPU_readTimeStamp(CPU_largeInteger *time);
;----------------------------------------------------------------------------
; Reads the time stamp counter and returns the 64-bit result.
;----------------------------------------------------------------------------
cprocstart  _CPU_readTimeStamp

        mRDTSC
        mov     ecx,[esp+4]     ; Access directly without stack frame
        mov     [ecx],eax
        mov     [ecx+4],edx
        ret

cprocend

;----------------------------------------------------------------------------
; ulong _CPU_diffTime64(CPU_largeInteger *t1,CPU_largeInteger *t2,CPU_largeInteger *t)
;----------------------------------------------------------------------------
; Computes the difference between two 64-bit numbers.
;----------------------------------------------------------------------------
cprocstart  _CPU_diffTime64

        ARG     t1:DPTR, t2:DPTR, t:DPTR

        enter_c

        mov     ecx,[t2]
        mov     eax,[ecx]       ; EAX := t2.low
        mov     ecx,[t1]
        sub     eax,[ecx]
        mov     edx,eax         ; EDX := low difference
        mov     ecx,[t2]
        mov     eax,[ecx+4]     ; ECX := t2.high
        mov     ecx,[t1]
        sbb     eax,[ecx+4]     ; EAX := high difference

        mov     ebx,[t]         ; Store the result
        mov     [ebx],edx       ; Store low part
        mov     [ebx+4],eax     ; Store high part
        mov     eax,edx         ; Return low part
ifndef flatmodel
        shld    edx,eax,16      ; Return in DX:AX
endif
        leave_c
        ret

cprocend

;----------------------------------------------------------------------------
; ulong _CPU_calcMicroSec(CPU_largeInteger *count,ulong freq);
;----------------------------------------------------------------------------
; Computes the value in microseconds for the elapsed time with maximum
; precision. The formula we use is:
;
;   us = (((diff * 0x100000) / freq) * 1000000) / 0x100000)
;
; The power of two multiple before the first divide allows us to scale the
; 64-bit difference using simple shifts, and then the divide brings the
; final result into the range to fit into a 32-bit integer.
;----------------------------------------------------------------------------
cprocstart  _CPU_calcMicroSec

        ARG     count:DPTR, freq:ULONG

        enter_c

        mov     ecx,[count]
        mov     eax,[ecx]       ; EAX := low part
        mov     edx,[ecx+4]     ; EDX := high part
        shld    edx,eax,20
        shl     eax,20          ; diff * 0x100000
        div     [DWORD freq]    ; (diff * 0x100000) / freq
        mov     ecx,1000000
        xor     edx,edx
        mul     ecx             ; ((diff * 0x100000) / freq) * 1000000)
        shrd    eax,edx,20      ; ((diff * 0x100000) / freq) * 1000000) / 0x100000
ifndef flatmodel
        shld    edx,eax,16      ; Return in DX:AX
endif
        leave_c
        ret

cprocend

;----------------------------------------------------------------------------
; ulong _CPU_mulDiv(ulong a,ulong b,ulong c);
;----------------------------------------------------------------------------
; Computes the following with 64-bit integer precision:
;
;   result = (a * b) / c
;
;----------------------------------------------------------------------------
cprocstart  _CPU_mulDiv

        ARG     a:ULONG, b:ULONG, c:ULONG

        enter_c
        mov     eax,[a]
        imul    [ULONG b]
        idiv    [ULONG c]
ifndef flatmodel
        shld    edx,eax,16      ; Return in DX:AX
endif
        leave_c
        ret

cprocend

endcodeseg  _cpuinfo

        END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -