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

📄 _vflat.asm

📁 uboot在arm处理器s3c2410的移植代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************;*;*                  SciTech OS Portability Manager Library;*;*  ========================================================================;*;*    The contents of this file are subject to the SciTech MGL Public;*    License Version 1.0 (the "License"); you may not use this file;*    except in compliance with the License. You may obtain a copy of;*    the License at http://www.scitechsoft.com/mgl-license.txt;*;*    Software distributed under the License is distributed on an;*    "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or;*    implied. See the License for the specific language governing;*    rights and limitations under the License.;*;*    The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.;*;*    The Initial Developer of the Original Code is SciTech Software, Inc.;*    All Rights Reserved.;*;*  ========================================================================;*;*            Based on original code Copyright 1994 Otto Chrons;*;* Language:    80386 Assembler, TASM 4.0 or later;* Environment: IBM PC 32 bit protected mode;*;* Description: Low level page fault handler for virtual linear framebuffers.;*;****************************************************************************        IDEAL        JUMPSinclude "scitech.mac"           ; Memory model macrosheader      _vflat              ; Set up memory modelVFLAT_START     EQU 0F0000000hVFLAT_END       EQU 0F03FFFFFhPAGE_PRESENT    EQU 1PAGE_NOTPRESENT EQU 0PAGE_READ       EQU 0PAGE_WRITE      EQU 2ifdef   DOS4GW;----------------------------------------------------------------------------; DOS4G/W flat linear framebuffer emulation.;----------------------------------------------------------------------------begdataseg  _vflat; Near pointers to the page directory base and our page tables. All of; this memory is always located in the first Mb of DOS memory.PDBR            dd  0               ; Page directory base register (CR3)accessPageAddr  dd  0accessPageTable dd  0; CauseWay page directory & 1st page table linear addresses.CauseWayDIRLinear dd 0CauseWay1stLinear dd 0; Place to store a copy of the original Page Table Directory before we; intialised our virtual buffer code.pageDirectory:  resd 1024           ; Saved page table directoryValidCS         dw  0               ; Valid CS for page faultsRing0CS         dw  0               ; Our ring 0 code selectorLastPage        dd  0               ; Last page we mapped inBankFuncBuf:    resb 101            ; Place to store bank switch codeBankFuncPtr     dd  offset BankFuncBufINT14Gate:INT14Offset     dd      0           ; eip of original vectorINT14Selector   dw      0           ; cs of original vector        cextern _PM_savedDS,USHORT        cextern VF_haveCauseWay,BOOLenddataseg  _vflatbegcodeseg  _vflat              ; Start of code segment        cextern VF_malloc,FPTR;----------------------------------------------------------------------------; PF_handler64k - Page fault handler for 64k banks;----------------------------------------------------------------------------; The handler below is a 32 bit ring 0 page fault handler.  It receives; control immediately after any page fault or after an IRQ6 (hardware; interrupt). This provides the fastest possible handling of page faults; since it jump directly here.  If this is a page fault, the number; immediately on the stack will be an error code, at offset 4 will be; the eip of the faulting instruction, at offset 8 will be the cs of the; faulting instruction.  If it is a hardware interrupt, it will not have; the error code and the eflags will be at offset 8.;----------------------------------------------------------------------------cprocfar    PF_handler64k; Check if this is a processor exeception or a page fault        push    eax        mov     ax,[cs:ValidCS]     ; Use CS override to access data        cmp     [ss:esp+12],ax      ; Is this a page fault?        jne     @@ToOldHandler      ; Nope, jump to the previous handler; Get address of page fault and check if within our handlers range        mov     eax,cr2             ; EBX has page fault linear address        cmp     eax,VFLAT_START     ; Is the fault less than ours?        jb      @@ToOldHandler      ; Yep, go to previous handler        cmp     eax,VFLAT_END       ; Is the fault more than ours?        jae     @@ToOldHandler      ; Yep, go to previous handler; This is our page fault, so we need to handle it        pushad        push    ds        push    es        mov     ebx,eax             ; EBX := page fault address        and     ebx,invert 0FFFFh   ; Mask to 64k bank boundary        mov     ds,[cs:_PM_savedDS]; Load segment registers        mov     es,[cs:_PM_savedDS]; Map in the page table for our virtual framebuffer area for modification        mov     edi,[PDBR]          ; EDI points to page directory        mov     edx,ebx             ; EDX = linear address        shr     edx,22              ; EDX = offset to page directory        mov     edx,[edx*4+edi]     ; EDX = physical page table address        mov     eax,edx        mov     edx,[accessPageTable]        or      eax,7        mov     [edx],eax        mov     eax,cr3        mov     cr3,eax             ; Update page table cache; Mark all pages valid for the new page fault area        mov     esi,ebx             ; ESI := linear address for page        shr     esi,10        and     esi,0FFFh           ; Offset into page table        add     esi,[accessPageAddr]ifdef   USE_NASM%assign off 0%rep 16        or      [DWORD esi+off],0000000001h ; Enable pages%assign off off+4%endrepelseoff = 0REPT    16        or      [DWORD esi+off],0000000001h ; Enable pagesoff = off+4ENDMendif; Mark all pages invalid for the previously mapped area        xchg    esi,[LastPage]      ; Save last page for next page fault        test    esi,esi        jz      @@DoneMapping       ; Dont update if first time roundifdef   USE_NASM%assign off 0%rep 16        or      [DWORD esi+off],0FFFFFFFEh  ; Disable pages%assign off off+4%endrepelseoff = 0REPT    16        and     [DWORD esi+off],0FFFFFFFEh  ; Disable pagesoff = off+4ENDMendif@@DoneMapping:        mov     eax,cr3        mov     cr3,eax             ; Flush the TLB; Now program the new SuperVGA starting bank address        mov     eax,ebx             ; EAX := page fault address        shr     eax,16        and     eax,0FFh            ; Mask to 0-255        call    [BankFuncPtr]       ; Call the bank switch function        pop     es        pop     ds        popad        pop     eax        add     esp,4               ; Pop the error code from stack        iretd                       ; Return to faulting instruction@@ToOldHandler:        pop     eaxifdef   USE_NASM        jmp far dword [cs:INT14Gate]; Chain to previous handlerelse        jmp     [FWORD cs:INT14Gate]; Chain to previous handlerendifcprocend;----------------------------------------------------------------------------; PF_handler4k  - Page fault handler for 4k banks;----------------------------------------------------------------------------; The handler below is a 32 bit ring 0 page fault handler.  It receives; control immediately after any page fault or after an IRQ6 (hardware; interrupt). This provides the fastest possible handling of page faults; since it jump directly here.  If this is a page fault, the number; immediately on the stack will be an error code, at offset 4 will be; the eip of the faulting instruction, at offset 8 will be the cs of the; faulting instruction.  If it is a hardware interrupt, it will not have; the error code and the eflags will be at offset 8.;----------------------------------------------------------------------------cprocfar    PF_handler4k; Fill in when we have tested all the 64Kb codeifdef   USE_NASM        jmp far dword [cs:INT14Gate]; Chain to previous handlerelse        jmp     [FWORD cs:INT14Gate]; Chain to previous handlerendifcprocend;----------------------------------------------------------------------------; void InstallFaultHandler(void *baseAddr,int bankSize);----------------------------------------------------------------------------; Installes the page fault handler directly int the interrupt descriptor; table for maximum performance. This of course requires ring 0 access,; but none of this stuff will run without ring 0!;----------------------------------------------------------------------------cprocstart  InstallFaultHandler        ARG     baseAddr:ULONG, bankSize:UINT        enter_c        mov     [DWORD LastPage],0  ; No pages have been mapped        mov     ax,cs        mov     [ValidCS],ax        ; Save CS value for page faults; Put address of our page fault handler into the IDT directly        sub     esp,6               ; Allocate space on stackifdef   USE_NASM        sidt    [ss:esp]            ; Store pointer to IDTelse        sidt    [FWORD ss:esp]      ; Store pointer to IDTendif        pop     ax                  ; add esp,2        pop     eax                 ; Absolute address of IDT        add     eax,14*8            ; Point to Int #14; Note that Interrupt gates do not have the high and low word of the; offset in adjacent words in memory, there are 4 bytes separating them.        mov     ecx,[eax]           ; Get cs and low 16 bits of offset        mov     edx,[eax+6]         ; Get high 16 bits of offset in dx        shl     edx,16        mov     dx,cx               ; edx has offset        mov     [INT14Offset],edx   ; Save offset        shr     ecx,16        mov     [INT14Selector],cx  ; Save original cs        mov     [eax+2],cs          ; Install new cs        mov     edx,offset PF_handler64k        cmp     [UINT bankSize],4        jne     @@1        mov     edx,offset PF_handler4k@@1:    mov     [eax],dx            ; Install low word of offset        shr     edx,16        mov     [eax+6],dx          ; Install high word of offset        leave_c        retcprocend;----------------------------------------------------------------------------; void RemoveFaultHandler(void);----------------------------------------------------------------------------; Closes down the virtual framebuffer services and restores the previous; page fault handler.;----------------------------------------------------------------------------cprocstart  RemoveFaultHandler        enter_c; Remove page fault handler from IDT        sub     esp,6               ; Allocate space on stackifdef   USE_NASM        sidt    [ss:esp]            ; Store pointer to IDTelse        sidt    [FWORD ss:esp]      ; Store pointer to IDTendif        pop     ax                  ; add esp,2        pop     eax                 ; Absolute address of IDT        add     eax,14*8            ; Point to Int #14        mov     cx,[INT14Selector]        mov     [eax+2],cx          ; Restore original CS        mov     edx,[INT14Offset]        mov     [eax],dx            ; Install low word of offset        shr     edx,16        mov     [eax+6],dx          ; Install high word of offset        leave_c        retcprocend;----------------------------------------------------------------------------; void InstallBankFunc(int codeLen,void *bankFunc);----------------------------------------------------------------------------; Installs the bank switch function by relocating it into our data segment; and making it into a callable function. We do it this way to make the; code identical to the way that the VflatD devices work under Windows.;----------------------------------------------------------------------------

⌨️ 快捷键说明

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