📄 a16utils.asm
字号:
PUBLIC vRealEsDsvRealEsDs PROC C ; TBD: verify this on an AMD K6-2 266 MHz ; Assert A20M# via system control port A (This is a ; system dependent feature). in al, 92h and al, 0fdh out 92h, al ; re-assert A20M# GOPROT mov ax, 8 mov gs, ax GOREAL mov ax, [_old_es] ; restore original mov es, ax mov ax, [_old_gs] ; restore original mov gs, ax sti retvRealEsDs ENDP;--------------------------------------------------------------------PUBLIC vFlatEsDsvFlatEsDs PROC C cli mov ax, es mov [_old_es], ax ; save original mov ax, gs mov [_old_gs], ax ; save original ; Deassert A20M# via system control port A (This is a ; system dependent feature) in al, 92h or al, 2 out 92h, al ; de-assert A20M# GOPROT mov ax, 10h mov es, ax mov gs, ax GOREAL retvFlatEsDs ENDPPUBLIC printprint PROC PASCAL Seq:DWORD pushad mov eax, Seq push eax call cprint popad retprint ENDPPUBLIC DoMoveDoMove PROC push edx; GOPROT pop edx mov ecx, edx shr ecx, 2 ; byte count / 4 = dword count cmp ecx, 0 je DoBytes NextDword: xor eax, eax lock or eax, gs:[esi]; mov eax, gs:[esi] mov gs:[edi], eax add esi, 4 add edi, 4 loop NextDwordDoBytes: mov ecx, edx and ecx, 3 cmp ecx, 0 je Exit ; no extra bytes to moveNextByte: mov al, byte ptr gs:[esi] mov byte ptr gs:[edi], al inc esi inc edi loop NextByteExit:; GOREAL ret DoMove ENDP .586 ;--------------------------------------------------------------------PUBLIC _WriteApic_WriteApic PROC C call vFlatFsGs xor ecx, ecx xor edx, edx mov cx, [esp+6] ; high word of apic address shl ecx, 16 mov cx, [esp+4] ; low word of apic address mov dx, [esp+10] ; high word of apic command shl edx, 16 mov dx, [esp+8] ; low word of apic command mov gs:[ecx], edx call vRealFsGs ret_WriteApic ENDP;--------------------------------------------------------------------PUBLIC _ReadApic_ReadApic PROC C call vFlatFsGs xor ecx, ecx mov cx, [esp+6] ; low word of apic address shl ecx, 16 mov cx, [esp+4] ; high word of apic address mov eax, gs:[ecx] push eax ; save eax call vRealFsGs pop eax ; restore eax mov edx, eax shr edx, 16 ret_ReadApic ENDP;--------------------------------------------------------------------; Since the AP shares the BSP's stack, coordination is needed to avoid; simultaneous usage by both processors, which would cause corruption.;; While the AP is executing here, the BSP is executing the code; which follows the call to vAPStartupAll() or vAPStartupOne(); in bu_apic.c:vExecuteOnAPs(). After disabling interrupts,; the BSP stores the sp value in _wCSegSP, sets _bSPValid to 1,; and spins while _dAPDone != _dAPAwake. (Both are initially zero;; the code below increments _dAPAwake before spinning on _bSPValid.);; XXX - There is a race condition here: if the BSP makes it all; XXX - the way to its spin loop on _dAPDone != _dAPAwake before; XXX - the AP increments _dAPAwake, the BSP will exit the spin; XXX - loop without actually having waited for the AP to finish.PUBLIC _vSetupAP_vSetupAP PROC C cli mov ax, @data mov ds, ax mov esp, 0 lock inc dword ptr [_dAPAwake]spin1: mov al, [_bSPValid] cmp al, 1 jne spin1; XXX - The following line is supposed to provide some validity checking,; XXX - but it does not entirely succeed. It is possible for > 1 AP to; XXX - see _bSPValid == 1, and exit the spin1 loop just above, before; XXX - the first one out has had time to decrement _bSPValid; this race; XXX - defeats the purpose of decrementing it. The decrement is likely; XXX - not needed anyway due to the exclusion provided by the spin2 loop; XXX - below. lock dec byte ptr[_bSPValid] mov ax, [_wCSegSS] mov ss, ax mov sp, [_wCSegSP]; critical section - determining unique cpu signaturesspin2: mov eax, 1; XXX - Should the following line have a 'lock' prefix? xchg word ptr [_block], ax test ax, ax jne spin2 mov ax, ds ; Save ASM DS and ES in global vars mov [_wASegDS], ax mov ax, es mov [_wASegES], ax mov ax, [_wCSegES] mov es, ax mov ax, [_wCSegDS] ; Restore C DS and ES from global vars mov ds, ax; Update Current Processor Number. Mutual exclusion from other AP's is; guaranteed by the spin2 loop above.; Note that the "processor number" determined here represents the order; in which the processors happened to get through the spin2 lock, and; has nothing to do with APIC numbers. A system having > 1 AP will not; necessarily number the AP's consistently from one run to the next. mov eax, [_dAPDone] inc eax mov [_wProcNumber], ax call [_dAPFuncPtr] ; _dAPFuncPtr needs to point to a void function mov ax, [_wASegDS] ; Restore ASM DS and ES from global vars mov ds, ax mov ax, [_wASegES] mov es, ax lock inc dword ptr [_dAPDone] lock inc byte ptr [_bSPValid] xor eax, eax; A simple 'mov' would serve as well as the following 'xchg'. xchg word ptr [_block], ax wbinvd mov si, offset _dAPHltJmp jmp dword ptr [si] ; Jump to HLT, JMP $-1 in F000 segment hlt ; Should never get here_vSetupAP ENDP;--------------------------------------------------------------------PUBLIC bIn8bIn8 PROC C wPort:WORD xor ax, ax mov dx, wPort in al, dx retbIn8 ENDP;--------------------------------------------------------------------PUBLIC wIn16wIn16 PROC C wPort:WORD mov dx, wPort in ax, dx retwIn16 ENDP;--------------------------------------------------------------------PUBLIC dIn32dIn32 PROC C wPort:WORD mov dx, wPort in eax, dx mov edx, eax shr edx, 16 retdIn32 ENDP;--------------------------------------------------------------------PUBLIC vOut8vOut8 PROC C wPort:WORD, bValue:BYTE mov dx, wPort mov al, bValue out dx, al retvOut8 ENDP;--------------------------------------------------------------------PUBLIC vOut16vOut16 PROC C wPort:WORD, wValue:WORD mov dx, wPort mov ax, wValue out dx, ax retvOut16 ENDP;--------------------------------------------------------------------PUBLIC vOut32vOut32 PROC C wPort:WORD, dValue:DWORD mov dx, wPort mov eax, dValue out dx, eax retvOut32 ENDP;--------------------------------------------------------------------; int FlatMove (DWORD dPhysicalDestination, DWORD dPhysicalSource, size_t sSize)PUBLIC FlatMoveXFlatMoveX PROC C dDest:DWORD, dSrc:DWORD, sSize:WORD call vm86 ; check if VM86 mode cmp ax, 0 jne NotRealMode ; skip memory move if not in real mode call vFlatFsGs ; set up FS and GS as 4GB limit selectors with ; base 0:0 and de-assert A20M# movzx ecx, sSize cmp ecx, 0 je SKipMemoryMove ; skip memory move if 0==sSize mov eax, dDest cmp eax, 400h jbe SkipMemoryMove ; skip memory move if destination is 40:0 ; BIOS Data Area or less (IVT) mov ebx, dSrcNextByte: mov dl, gs:[ebx][ecx - 1] mov gs:[eax][ecx - 1], dl loop NextByte call vRealFsGs xor ax, axNotRealMode: retSkipMemoryMove: mov ax, 1 ; return error code retFlatMoveX ENDP; int FlatMove32 (DWORD dPhysicalDestination, DWORD dPhysicalSource, size_t sSize)PUBLIC FlatMove32FlatMove32 PROC C dDest:DWORD, dSrc:DWORD, sSize:WORD call vm86 ; check if VM86 mode cmp ax, 0 jne NotRealMode ; skip memory move if not in real mode call vFlatFsGs ; set up FS and GS as 4GB limit selectors with ; base 0:0 and de-assert A20M# movzx edx, sSize mov esi, dSrc mov edi, dDest push edx call print push esi call print push edi call print cmp edx, 0 je SkipMemoryMove ; skip memory move if 0==sSize cmp edi, 400h jbe SkipMemoryMove ; skip memory move if destination is 40:0 ; BIOS Data Area or less (IVT) call DoMove ; edx=Count, esi=src, edi=dst movzx ecx, sSize shr ecx, 2 mov edi, dDestPrintLoop: mov eax, gs:[edi] push eax call print add edi, 4 loop PrintLoop call vRealFsGs xor ax, axNotRealMode: retSkipMemoryMove: call print call vRealEsDs mov ax, 1 ; return error code ret FlatMove32 ENDP; int FlatMove32 (DWORD dPhysicalDestination, DWORD dPhysicalSource, size_t sSize)PUBLIC FlatMove32xFlatMove32x PROC C dDest:DWORD, dSrc:DWORD, sSize:WORD call vm86 ; check if VM86 mode cmp ax, 0 jne NotRealMode ; skip memory move if not in real mode call vFlatFsGs ; set up FS and GS as 4GB limit selectors with ; base 0:0 and de-assert A20M# movzx ecx, sSize cmp ecx, 0 je SKipMemoryMove ; skip memory move if 0==sSize mov eax, dDest cmp eax, 400h jbe SkipMemoryMove ; skip memory move if destination is 40:0 ; BIOS Data Area or less (IVT) mov ebx, dSrc mov esi, 0 push ecx call print push ebx call print push eax call print shr ecx, 2 ; byte count / 4 = dword count cmp ecx, 0 je DoBytesNextDword: mov edx, dword ptr gs:[ebx][esi] mov dword ptr gs:[eax][esi], edx push edx call print add esi, 4 loop NextDwordDoBytes: movzx ecx, sSize and ecx, 3 cmp ecx, 0 je Exit ; no extra bytes to moveNextByte: mov dl, gs:[ebx][esi] mov gs:[eax][esi], dl inc esi loop NextByteExit: call vRealFsGs xor ax, axNotRealMode: retSkipMemoryMove: mov ax, 1 ; return error code retFlatMove32x ENDPEND
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -