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

📄 startup.asm

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 ASM
字号:
;
; Copyright (c) Microsoft Corporation.  All rights reserved.
;
;
; Use of this source code is subject to the terms of the Microsoft end-user
; license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
; If you did not accept the terms of the EULA, you are not authorized to use
; this source code. For a copy of the EULA, please see the LICENSE.RTF on your
; install media.
;
;-------------------------------------------------------------------------------
;
;   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
;   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
;   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
;   PARTICULAR PURPOSE.
;
;-------------------------------------------------------------------------------
.486p

PAGE_SIZE EQU 1000h
PAGE_ATTRIB_RW      EQU 000001100011b
PAGE_ATTRIB_RW_NOCACHE  EQU 000001111011b
PAGE_ATTRIB_RO_USER EQU 000000100101b
PAGE_ATTRIB_RW_USER EQU 000001100111b

PageRange MACRO Start, NumPages, Attrib
        LOCAL CurPhys
        .ERRNZ Start AND (PAGE_SIZE-1)
        CurPhys = Start
        REPEAT NumPages
            dd  CurPhys OR Attrib
            CurPhys = CurPhys + PAGE_SIZE
        ENDM
        ENDM

LIN_TO_PHYS_OFFSET EQU 80000000h

OFFSET32 EQU <OFFSET FLAT:>


;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

; This GDT is only used by _RebootHandler to set the correct GDT during the warm reboot path

GDT_Data LABEL DWORD
        db      0,    0,   0,   0,   0,         0,         0,   0 ; First GDT entry always unused
CS_FLAT_SEL EQU ($-GDT_Data)
        db      0FFh, 0FFh, 00h, 00h, 00h, 10011010b, 11001111b, 00h ; Code
DS_FLAT_SEL EQU ($-GDT_Data)
        db      0FFh, 0FFh, 00h, 00h, 00h, 10010010b, 11001111b, 00h ; Data
GDT_TABLE_SIZE = $ - OFFSET GDT_Data

GDTPtr LABEL FWORD
        dw      GDT_TABLE_SIZE - 1  ; Limit of 0 = 1 byte
        dd      OFFSET GDT_Data
_DATA ENDS

        ASSUME  CS: FLAT, DS: FLAT, SS: FLAT



;vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
_TEXT SEGMENT para public 'TEXT'
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

        public      _OEMAddressTable
        public      _IdentifyCpu


;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_IdentifyCpu PROC NEAR                  ; COMDAT
        push    ebx
        cli

        xor     edx, edx                ; initialize return value to 0

        pushfd                          ; Save EFLAGS to stack
        pop     eax                     ; Store EFLAGS in EAX
        mov     ecx, eax                ; Save in ECX for testing later
        xor     eax, 00200000h          ; Switch bit 21
        push    eax                     ; Copy changed value to stack
        popfd                           ; Save changed EAX to EFLAGS
        pushfd                          ; Push EFLAGS to top of stack
        pop     eax                     ; Store EFLAGS in EAX
        cmp     eax, ecx                ; See if bit 21 has changed
        jz      cpuid_ret               ; If no change,no CPUID

        ; call cpuid with eax == 1 to get capability info
        mov     eax, 1
        DB      00fH
        DB      0a2H

cpuid_ret:
        mov     eax, edx
        pop     ebx
        ret     0
_IdentifyCpu ENDP



;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------




LIN_TO_PHYS_MASK        EQU     7FFFFFFFh
PG_MASK                 EQU     80000000h
CD_MASK                 EQU     40000000h

extrn _dwRebootAddress:near
extrn _KernelInitialize:near
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_RebootHandler PROC NEAR PUBLIC

        cli
        ;
        ; Get the linear address of the page directory.
        ;
        mov     ebx, cr3
        or      ebx, LIN_TO_PHYS_OFFSET

        ;
        ; Create the identity-mapped addresses (physical = linear)
        ;

        mov     ecx, OFFSET32 IdentityMapped
        mov     edx, ecx
        and     edx, LIN_TO_PHYS_MASK
        ;
        ; ECX = current linear addr, EDX = current physical addr.
        ;
        shr     ecx, 22                 ; Which 4MB?
        shl     ecx, 2                  ; DWORD index
        shr     edx, 22                 ; Which 4MB?
        shl     edx, 2                  ; DWORD index

        ;
        ; Copy the page directory entry for the current linear
        ; address to the physical address.
        ;
        mov     eax, DWORD PTR [ebx][ecx]
        mov     DWORD PTR [ebx][edx], eax

        ;
        ; Move execution to the identity-mapped physical address.
        ;
        mov     edx, OFFSET32 IdentityMapped
        and     edx, LIN_TO_PHYS_MASK
        jmp     edx

IdentityMapped:
        mov     edx, OFFSET32 PagingDisabled
        and     edx, LIN_TO_PHYS_MASK

        mov     eax, cr0
        and     eax, not PG_MASK        ; Disable paging
        or      eax, CD_MASK            ; Disable cache
        mov     cr0, eax                ; Apply new system settings

        wbinvd                          ; Flush the cache

        mov     ebx, cr3
        mov     cr3, ebx                ; Flush the TLB

        and     eax, not CD_MASK        ; Re-enable cache
        mov     cr0, eax                ; Apply new system settings

        jmp     edx                     ; Far jump to purge any prefetch state.

        align   4
PagingDisabled:
        ;
        ; Move the stack pointer to the physical address.
        ;
        mov     eax, esp
        and     eax, LIN_TO_PHYS_MASK
        mov     esp, eax

INITIAL_CR0     EQU     00000011h
INITIAL_CR3     EQU     00000000h
INITIAL_CR4     EQU     00000000h
INITIAL_EFLAGS  EQU     00007046h

        mov     eax, INITIAL_CR0
        mov     cr0, eax
        mov     eax, INITIAL_CR3
        mov     cr3, eax
.586p
        mov     eax, INITIAL_CR4
        mov     cr4, eax
.486p
        mov     eax, INITIAL_EFLAGS

        lgdt    FWORD PTR [GDTPtr]      ; Load the GDTR

        push    eax
        popfd

        ;
        ; Read from RAM the address we are jumping to.
        ;
        mov     edx, _dwRebootAddress
        and     edx, LIN_TO_PHYS_MASK
        mov     ebx, dword ptr [edx]
        and     ebx, LIN_TO_PHYS_MASK
        ;
        ; Jump to the first instruction.
        ;
        jmp     ebx


_RebootHandler ENDP

;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_StartUp PROC NEAR PUBLIC
        cli

        ;
        ; The following strange code is used to get the Physical Address of _PAOfStart.
        ; The trick is that "call" will pushed the return address onto stack, which will
        ; be the the Physical address of _PaStart. We then pop the stack to get the Physical
        ; address.
        ;
        call    _IdentifyCpu
        mov     edi, eax    ; argument to _KernelInitialize, edi = cpu capability bits

        call    _PAOfStart
_PAOfStart:
        pop     esi         ; (esi) = PA of _PAStart

        add     esi, OFFSET32 _OEMAddressTable
        sub     esi, OFFSET32 _PAOfStart         ; (esi) = PA of OEMAddressTable

        ; argument to KernelInitialize:
        ; (esi) = Physical Address of OEMAddressTable
        ; (edi) = CPU capability bits
        ;
        jmp  _KernelInitialize

        align 4
_OEMAddressTable:
        ; 
        ; OEMAddressTable defines the mapping between Physical and Virtual Address
        ;   o MUST be in a READONLY Section
        ;   o First Entry MUST be RAM, mapping from 0x80000000 -> 0x00000000
        ;   o each entry is of the format ( VA, PA, cbSize )
        ;   o cbSize must be multiple of 4M
        ;   o last entry must be (0, 0, 0)
        ;   o must have at least one non-zero entry

        ; RAM 0x80000000 -> 0x00000000, size 64M
        dd  80000000h,     0,           04000000h

        ; FLASH and other memory, if any
        ; dd  FlashVA,      FlashPA,    FlashSize

        ; Last entry, all zeros
        dd  0,              0,          0
_StartUp ENDP

;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_CallBios32 PROC NEAR PUBLIC
RegisterArray 	equ  8
CallingAddress 	equ  12
		push	ebp
		mov		ebp,esp
		push 	ebx
		push	ecx
		push	edx
		push	esi
		push	edi
		; Load Register.
		mov		ebx,DWORD PTR RegisterArray[ebp]
		mov		eax,DWORD PTR [ebx]
		mov		ecx,DWORD PTR [ebx+8]
		mov		edx,DWORD PTR [ebx+12]
		mov		esi,DWORD PTR [ebx+16]
		mov		edi,DWORD PTR [ebx+20]
		mov		ebx,DWORD PTR [ebx+4]
		; Calling into BIOS32
		push	ebp
		mov		ebp,DWORD PTR CallingAddress[ebp]
		push	cs
		call	ebp
		pop		ebp
		;Save Register
		push	ebx
		mov		ebx,DWORD PTR RegisterArray[ebp]
		mov		DWORD PTR [ebx],eax
		mov		DWORD PTR [ebx+8],ecx
		mov		DWORD PTR [ebx+12],edx
		mov		DWORD PTR [ebx+16],esi
		mov		DWORD PTR [ebx+20],edi
		pop		eax
		mov		DWORD PTR [ebx+4],eax
		; returning
		pop		edi
		pop		esi
		pop		edx
		pop		ecx
		pop		ebx

		pop		ebp
		jc		CallBios32_Fails
		xor		eax,eax
		inc		eax
		ret		0
CallBios32_Fails:
		xor		eax,eax
		ret		0

_CallBios32 ENDP


;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
_GetDS PROC NEAR PUBLIC
		push ds
		pop  eax
		ret 0
_GetDS ENDP

_TEXT ENDS


        END

⌨️ 快捷键说明

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