diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Chipset/eM/Ahci/AHCIACC.ASM | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Chipset/eM/Ahci/AHCIACC.ASM')
-rw-r--r-- | Chipset/eM/Ahci/AHCIACC.ASM | 1181 |
1 files changed, 1181 insertions, 0 deletions
diff --git a/Chipset/eM/Ahci/AHCIACC.ASM b/Chipset/eM/Ahci/AHCIACC.ASM new file mode 100644 index 0000000..1f93536 --- /dev/null +++ b/Chipset/eM/Ahci/AHCIACC.ASM @@ -0,0 +1,1181 @@ + + TITLE AHCIACC.ASM - AHCI Register/Memory Acccess Routines + +;**************************************************************************** +;**************************************************************************** +;** ** +;** (C)Copyright 1985-2014, American Megatrends, Inc. ** +;** ** +;** All Rights Reserved. ** +;** ** +;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +;** ** +;** Phone (770)-246-8600 ** +;** ** +;**************************************************************************** +;**************************************************************************** + +;**************************************************************************** +; $Header: /Alaska/SOURCE/Modules/AHCI/INT13/CSP/AHCIACC.ASM 14 12/08/14 5:58a Anbuprakashp $ +; +; $Revision: 14 $ +; +; $Date: 12/08/14 5:58a $ +;**************************************************************************** +; Revision History +; ---------------- +; $Log: /Alaska/SOURCE/Modules/AHCI/INT13/CSP/AHCIACC.ASM $ +; +; 14 12/08/14 5:58a Anbuprakashp +; [TAG] EIP192297 +; [Category] Improvement +; [Description] Replacing SmmGetMemoryType usage in AHCI driver with +; AmiBufferValidationLib +; [Files] AhciInt13Smm.c, AhciInt13Smm.mak, AHCIACC.ASM +; +; 13 11/24/14 11:54p Kapilporwal +; [TAG] EIP191939 +; [Category] Improvement +; [Description] Issue about BIG_REAL_MODE_MMIO_ACCESS of AHCI module +; [Files] AI13.bin +; AHCIACC.ASM +; AhciInt13Dxe.c +; AhciInt13Dxe.dxs +; AhciInt13Smm.c +; AhciInt13Smm.cif +; AhciInt13Smm.dxs +; AhciInt13Smm.h +; AhciInt13Smm.mak +; AhciInt13Smm.sdl +; AInt13.c +; Aint13.cif +; AInt13.h +; AhciSmm.c +; AhciSmm.h +; AhciSmmProtocol.h +; +; 12 7/01/14 2:23a Nagadineshk +; [TAG] EIP172162 +; [Category] Bug Fix +; [Severity] Important +; [Symptom] Can't install legacy windows if achiacc.obj is not first +; one of CSM_OEM16_OBJS elink +; [RootCause] Wrong offset of Newly Hooked Interrupt(CPU Exception +; Interrupt) address loaded in Interrupt vector table. +; [Solution] Stored Correct Offset value in IVT +; [Files] AHCIACC.ASM +; +; 11 6/20/14 6:54a Nimishsv +; Recheck-in +; +; 10 12/17/13 7:06a Nimishsv +; [TAG] EIP131322 +; [Category] Improvement +; [Description] Improve S4 resume time with PCIE SSD +; under Win7, reported that if enable AHCIMMIOSMM_SUPPORT, +; and then S4 resume time is very long(about 50s) with win 7. +; (Add support for accessing MMIO region using BIG real mode) +; [Files] AhciMmioSmm.sdl, AHCIACC.asm +; +; 9 8/02/12 8:14a Deepthins +; [TAG] EIP93480 +; [Category] Bug Fix +; [Symptom] AHCI legacy support module is corrupting the memory. +; [RootCause] AHCI legacy support module is corrupting the memory as it +; was using wrong offset for storing the base address. +; [Solution] Properly calculating offset for storing the base address. +; [Files] AINT13.EQU, AInt13.c, AInt13.h and AHCIACC.ASM +; +; 8 1/13/12 12:20a Deepthins +; [TAG] EIP78099 +; [Category] Improvement +; [Description] Handle multiple AHCI controller in legacy. +; [Files] Aint13.sdl , AInt13.c , AInt13.h , AHCIACC.ASM , AHCI.EQU , +; AINT13.bin (AHCIACC.ASM , AINT13.EQU) +; +; 7 2/10/11 10:52a Rameshr +; [TAG] EIP53704 +; [Category] Improvement +; [Description] AMI headers update for Alaska Ahci Driver +; [Files] AHCIACC.ASM +; HACCESS.EQU +; AHCI.EQU +; AINT13.EQU +; AInt13Csp.c +; +; 6 6/21/10 5:34a Rameshr +; AHCI Legacy booting through MMIO reg. +; EIP 38444 +; +; 5 5/28/08 9:43a Rameshraju +; Updated the AMI Address. +; +; 4 3/28/08 10:03a Olegi +; +; 3 3/27/08 5:33p Olegi +; +; 2 19/12/07 4:28p Anandakrishnanl +; Modified the relative offsets to be absolute. +; +; 1 12/07/07 11:17a Olegi +; +;**************************************************************************** + +;---------------------------------------------------------------------------- +; INCLUDE FILES +;---------------------------------------------------------------------------- + include ahci.equ + include haccess.equ + include aint13.equ + include token.equ + + FLAT_MODE_INDEX equ 08h + REAL_MODE_INDEX equ 10h +;---------------------------------------------------------------------------- +; EXTERNS USED +;---------------------------------------------------------------------------- +.586p +OEM16_CSEG SEGMENT PARA PUBLIC 'CODE' USE16 + ASSUME cs:OEM16_CSEG, ds:OEM16_CSEG +;------------------------------------------------------------------------- + PUBLIC AhciApiModuleStart +AhciApiModuleStart LABEL BYTE + jmp SHORT AhciCsm16Api + dw AhciDataStart - AhciApiModuleStart + + +;---------------------------------------------------------------------------- +; IMPORTANT: Do not put any OEM/CHIPSET code above this, the above code and +; and data are at fixed locations. +;---------------------------------------------------------------------------- + +;------------------------------------------------------------------------- +; AHCI_CSM16_API_Start +;---------------------------------------------------------------------------- +; This routine is implementation of the CSM16 API #7. +; Input: CX 80h - ReadRegisterDword call +; 00h - WriteRegisterDword call +; 01h - WaitForFisRecRun call +; For read/write functions: +; SS:SP+3Eh (originally ESI) HBA Base Address +; SS:SP+42h (originally EBX) Port#, Register Offset +; Bit31-16 = Port# (0-based) +; FFFF for Generic Host Control Register +; Bit15-0 = Register offset +; SS:SP+46h (originally EAX) Data to be written +; For WaitForFisRecRun function: +; No input +; Output: NC Successful +; EAX Data read +; CY Error +; Register Usage: Do not destroy any register except EAX +; +;---------------------------------------------------------------------------- +; +AhciCsm16Api PROC FAR PUBLIC +; Adjust current IP so that the data offsets are valid + call $+3 ; Push curent IP + pop bx ; Get current IP in BX + shr bx, 4 + mov ax, cs ; Always x000h + add ax, bx ; New CS + push ax + push newOffset-AhciApiModuleStart + retf ; Execute from new CS:IP + +newOffset: + push bp + mov bp, sp + mov eax, ss:[bp+48h] ; Data to be written (ignored for Read function) + mov ebx, ss:[bp+44h] ; Port# + mov esi, ss:[bp+40h] ; HBA Base Address + + cmp cx, 0 + jz aca_WriteCall + cmp cx, 80h + jnz aca_WaitForFisRecRun + call ReadRegisterDword + jmp SHORT aca_Exit +aca_WaitForFisRecRun: + call WaitForFisRecRun + jmp SHORT aca_Exit +aca_WriteCall: + call WriteRegisterDword + +aca_Exit: + pop bp + +; Adjust sp as if we returned to csm16_func_ret + add sp, 4 ; cs:ip of F000:csm16_func_ret + +; Save EAX, restore it after popad + push eax + pop ds + pop gs +;csm16_func_ret: + popad + push gs + push ds + pop eax + + pop gs + pop fs + pop es + pop ds + +;csm16_exit: + popf + pop ds + pop si + + add sp, 2 ; Do not "pop ax", preserving return code + +; Prepare for FAR return - fetch the CS and patch the segment for RETF + mov cx, WORD PTR ss:[bp+1ah] + mov WORD PTR ss:[bp+06h], cx +; Restore CX + mov cx, WORD PTR ss:[bp+18h] + mov dx, WORD PTR ss:[bp+16h] ;Restore Dx + + pop bp + add sp, 4 + clc + retf 18 + +AhciCsm16Api ENDP + +; +;------------------------------------------------------------------------- +; ReadRegisterDword +;---------------------------------------------------------------------------- +; This routine reads the register. +; Input: ESI HBA Base Address +; EBX Port#, Register Offset +; Bit31-16 = Port# (0-based) +; FFFF for Generic Host Control Register +; Bit15-0 = Register offset +; Output: NC Successful +; EAX Data read +; CY Error +; Register Usage: Do not destroy any register except EAX +; +;---------------------------------------------------------------------------- +; +ReadRegisterDword_FAR PROC FAR PUBLIC + call ReadRegisterDword ; EAX = data read if read + ret +ReadRegisterDword_FAR ENDP + +ReadRegisterDword PROC NEAR PUBLIC + push esi + call CalculateRegisterOffset ; ESI = register offset from base + + push dx ; Dx has the controller number + cli + push bx ; Save bx value in stack + push ax ; Save ax value in stack + mov ax, 0 + mov al, dl ; Move the controller no into al + mov bl, 8 + mul bl ; Multiply it with 8 as AHCI_ACCESS\ + ; structure size is 8 + mov bx, ax ; Move the offset into bx + pop ax ; Restore ax +IF (MKF_AHCI_INT13_SMM_SUPPORT) + push ebx + push ecx + mov ebx, dword ptr cs:[AhciDataStart - AhciApiModuleStart +4+bx] ;ebx=Data + add esi,ebx +IF (MKF_BIG_REAL_MODE_MMIO_ACCESS) + call ReadDWORD +ELSE + mov cx,1 ;Read Function + call AhciGenerateSwSMI + cmp ecx, 0 ; if ECX == 0, MMIO read is Success + jz Read_Success + stc + jmp Read_Return +Read_Success: + clc +Read_Return: +ENDIF + pop ecx + pop ebx + jmp Read_done +ENDIF + mov dx, cs:[AhciDataStart - AhciApiModuleStart +bx] ; DX = Index Port + push eax + mov eax, esi ; EAX = register address + out dx, eax ; Write Address + pop eax + + mov dx, cs:[AhciDataStart - AhciApiModuleStart +2+bx] ; DX = Data Port + in eax, dx ; EAX = adat + + clc ; NC, Successful +Read_done: + pop bx + pop dx + + pop esi + ret +ReadRegisterDword ENDP +; +;---------------------------------------------------------------------------- +; WriteRegisterDword +;---------------------------------------------------------------------------- +; This routine writes the register. +; Input: ESI HBA Base Address +; EBX Port#, Register Offset +; Bit31-16 = Port# (0-based) +; FFFF for Generic Host Control Register +; Bit15-0 = Register offset +; EAX Data to be written +; Output: NC Successful +; CY Error +; Register Usage: Do not destroy any register +; +;---------------------------------------------------------------------------- +; +WriteRegisterDword_FAR PROC FAR PUBLIC + call WriteRegisterDword + ret +WriteRegisterDword_FAR ENDP + +WriteRegisterDword PROC NEAR PUBLIC + push esi + call CalculateRegisterOffset ; ESI = register offset from base + + push dx ; Dx has the controller number + cli + push bx ; Save bx value in stack + push ax ; Save ax value in stack + mov ax, 0 + mov al, dl ; Move the controller no into al + mov bl, 8 + mul bl ; Multiply it with 8 as AHCI_ACCESS\ + ; structure size is 8 + mov bx, ax ; Move the offset into bx + pop ax ; Restore ax + +IF (MKF_AHCI_INT13_SMM_SUPPORT) + push ebx + push ecx + mov ebx, dword ptr cs:[AhciDataStart - AhciApiModuleStart +4+bx] + add esi,ebx +IF (MKF_BIG_REAL_MODE_MMIO_ACCESS) + call WriteDWORD +ELSE + mov ebx,eax ;Write Value + mov cx,2 ;Write Function + call AhciGenerateSwSMI + cmp ecx, 0 ; if ECX == 0, MMIO write is Success + jz Write_Success + stc + jmp Write_Return +Write_Success: + clc +Write_Return: +ENDIF + pop ecx + pop ebx + jmp Write_done +ENDIF + mov dx, cs:[AhciDataStart - AhciApiModuleStart +bx] ; DX = Index Port + push eax + mov eax, esi ; EAX = register address + out dx, eax ; Write Address + pop eax + + mov dx, cs:[AhciDataStart - AhciApiModuleStart +2+bx] ; DX = Data Port + out dx, eax ; Write dword data + clc ; NC, Successful +Write_done: + pop bx + pop dx + + pop esi + ret +WriteRegisterDword ENDP +; +;---------------------------------------------------------------------------- +; CalculateRegisterOffset +;---------------------------------------------------------------------------- +; This routine calculates the register offset from HBA Base. +; Input: EBX Port#, Register Offset within Port +; Bit31-16 = Port# (0-based) +; FFFF for Generic Host Control Register +; Bit15-0 = Register offset +; Output: ESI Register Offset from HBA Base +; Register Usage: Do not destroy any register except ESI +; +;---------------------------------------------------------------------------- +; +CalculateRegisterOffset PROC NEAR PRIVATE + push cx + push ebx + mov cx, bx ; CX = register offset + shr ebx, 16 ; BX = Port# (0-based) + inc bx ; Port# valid? + jz short cro_00 ; No + dec bx ; BX = Port# (0-based) + shl bx, PORT_REGISTER_SET_SIZE_N + add bx, PORT_REGISTER_START +cro_00: + add bx, cx ; BX = Port register offset from HBA base address + movzx esi, bx ; ESI = Port register offset from HBA base address + pop ebx + pop cx + ret +CalculateRegisterOffset ENDP + +; +;---------------------------------------------------------------------------- +; WaitForFisRecRun +;---------------------------------------------------------------------------- +; This routine executes HBA wait for FIS rec run code. If not +; implemented (just ret), AHCI INT13 code will execute the default routine. +; Implement this routine for different OEM/Chipset vendor and return 0 in AL +; to override the default routine execution. +; +; Output: AH 0 if implemented +; +;---------------------------------------------------------------------------- +; +WaitForFisRecRun PROC NEAR PUBLIC + ret +WaitForFisRecRun ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: AhciGenerateSwSMI +; +; Description: Generate the Sw SMI to read the MMIO space. +; if the system is in big real mode, read/write the MMIO space without +; SwSMI +; +; Input: Cx = 1 - Read MMIO +; Cx= 2 - Write MMIO +; Eax= Value to write in MMIO for write MMIO +; +; Output: Eax- for Read MMIO +; +; Modified: Ds +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +IF (MKF_AHCI_INT13_SMM_SUPPORT) +AhciGenerateSwSMI PROC NEAR PUBLIC + call Check_Big_Real_mode + jc NotBigReadMode + push es + push 0 + pop es + + cmp cx,1 + je ReadMmio + mov dword ptr es:[esi],eax ;Write MMIO + pop es + ret +ReadMmio: + mov eax,dword ptr es:[esi] ;Read MMIO + pop es + ret +NotBigReadMode: + + mov dx,MKF_SW_SMI_IO_ADDRESS + mov al,MKF_AHCI_INT13_SMM_SWSMI_VALUE + out dx,al ;Generate Sw SMI to Read/Write MMIO + jmp $+2 + ret +AhciGenerateSwSMI ENDP + +;------------------------------------------------------------------------- +; ReadDWORD +;------------------------------------------------------------------------- +; This routine reads DWORD from MMIO. +; Input: ESI HBA Base Address +; +; Output: NC Successful +; EAX Data read +; CY Error +; Register Usage: Do not destroy any register except EAX +; +;------------------------------------------------------------------------- +ReadDWORD PROC NEAR PUBLIC + + push ds + + push 0 + pop ds + + push esi + +; Save original values of registers in stack + push ebx + push es + push di + +; Save a dword from 5000h + mov bx, 5000h + mov es, bx + mov di, 00h + mov ebx, dword ptr es:[di] + + push ebx + + mov byte ptr es:[di], 00h +; Switching to Big Real Mode + call Switch_Big_Real_Mode + +; Reading DWORD from Hba_base_address and store in EAX + mov eax, dword ptr ds:[esi] + + push eax + movzx eax, byte ptr es:[di] + and eax, 01h + jz rdw_done +; Switch back from Big Real mode + call Switch_Original_Mode + +rdw_done: + pop eax + + push eax + movzx eax, byte ptr es:[di] + and eax, 10b + jz org_g20 + call DisblGateA20 +org_g20: + pop eax + + pop ebx +; Restore the original values stored in stack + mov dword ptr es:[di], ebx + + pop di + pop es + pop ebx + + pop esi + + pop ds + clc + + ret +ReadDWORD ENDP + +;------------------------------------------------------------------------- +; WriteDWORD +;------------------------------------------------------------------------- +; This routine writes DWORD in MMIO space. +; Input: EAX Data to be written +; +; Output: ESI HBA Base Address +; NC Successful +; CY Error +; +; Register Usage: Do not destroy any register except EAX +; +;------------------------------------------------------------------------- +WriteDWORD PROC NEAR PUBLIC + push ds + + push 0 + pop ds + + push esi + +; Save original values of registers in stack + push ebx + push es + push di + +; Save a dword from 5000h + mov bx, 5000h + mov es, bx + mov di, 00h + mov ebx, dword ptr es:[di] + + push ebx + + mov byte ptr es:[di], 00h +; Switching to Big Real Mode + call Switch_Big_Real_Mode + +; Writing DWORD stored in EAX into Hba_base_address + mov dword ptr ds:[esi],eax + + push eax + movzx eax, byte ptr es:[di] + and eax, 01h + jz wdw_done + +; Switch back from Big Real mode + call Switch_Original_Mode + +wdw_done: + pop eax + + push eax + movzx eax, byte ptr es:[di] + and eax, 10b + jz org_g201 + call DisblGateA20 +org_g201: + pop eax + pop ebx + +; Restore the original values stored in stack + mov dword ptr es:[di], ebx + + pop di + pop es + pop ebx + + pop esi + + pop ds + clc + + ret +WriteDWORD ENDP + +;---------------------------------------------------------------------------- +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: Switch_Big_Real_Mode +; +; Description: Switch to Big real Mode. +; +; Input: None +; +; Output: +; +; Modified: DS, ES +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +;---------------------------------------------------------------------------- +Switch_Big_Real_Mode PROC NEAR PUBLIC + + push di + call Check_Big_Real_mode + jnc InBigRealMode + mov byte ptr es:[di], 01h + +InBigRealMode: + + mov di, FLAT_MODE_INDEX ;Index for flat mode + call GotoProtectedMode + + pop di + ret + +Switch_Big_Real_Mode ENDP + +;---------------------------------------------------------------------------- +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: Switch_Original_Mode +; +; Description: Switch to Original Mode. +; +; Input: None +; +; Output: +; +; Modified: DS, ES +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +;---------------------------------------------------------------------------- +Switch_Original_Mode PROC NEAR PUBLIC + + push di + mov di, REAL_MODE_INDEX ;Real mode index + call GotoProtectedMode + pop di + + ret + +Switch_Original_Mode ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: GotoProtectedMode +; +; Description: This function jumps to protected mode for 4GB limit access +; +; Input: None +; +; Output: None +; +; Modified: None +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> + +GotoProtectedMode PROC NEAR PUBLIC + push es + pusha + cli ; Disable interrupts. +; Check the GA20 status.. +; Compare 256bytes at 0:0 with FFFF:10 +; If match, GA20 is disabled else GA20 is enabled. + push di + push es + push ds + push 0000h + pop ds ; DS = 0000. + push 0FFFFh + pop es ; ES = FFFF. + mov cx, 100h / 4 ; Number of Dwords in 256bytes. + xor si, si + mov di, 0010h + repz cmpsd + pop ds + pop es + pop di ;Descriptor table index in di + + pushf ; Save GA20 status + ; ZR/NZ = disabled/enabled. + jnz short gtbrm_00 ; GA20 is already enabled. + + push di + mov di, 00h + or byte ptr es:[di], 10b + pop di + call EnblGateA20 ; Enable GateA20. + +gtbrm_00: + call go_big_mode ; Go to protected mode and comeback + ; to real mode. + popf ; ZR/NZ = GA20 status. + stc ; Routine went to big real mode. + +gtbrm_01: + popa + pop es + ret ; Return to caller. +GotoProtectedMode ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: EnblGateA20 +; +; Description: This function enables GateA20 +; +; Input: None +; +; Output: None +; +; Modified: None +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> + +EnblGateA20 PROC NEAR PUBLIC + + push ax + mov al,02h + out 92h, al + +; Check the GA20 status.. +; Compare 256bytes at 0:0 with FFFF:10 +; If match, GA20 is disabled else GA20 is enabled. + push di + push es + push ds + push 0000h + pop ds ; DS = 0000. + push 0FFFFh + pop es ; ES = FFFF. + mov cx, 100h / 4 ; Number of Dwords in 256bytes. + xor si, si + mov di, 0010h + repz cmpsd + pop ds + pop es + pop di ;Descriptor table index in di + + jnz eg20_end + + mov al, 0DFh ; Data for output port to enable A20. + out 60h, al + mov al, 0D1h + out 64h, al + +eg20_end: + pop ax + + ret +EnblGateA20 ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: go_big_mode +; +; Description: This routine goes to protected mode, sets the DS, ES to the +; given selector, comes back to real mode and sets DS, ES to 0000. +; +; Input: DX - Selector. +; +; Output: Selector 00 can be used to access 4GB. +; +; Modified: EAX. +; +; Referrals: big_gdt. +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> + +go_big_mode PROC NEAR PRIVATE + + jmp Executable_code + +;<AMI_SHDR_START> +;---------------------------------------------------------------------------- +; Name: big_gdt +; +; Type: BYTE Array +; +; Description: Global Descriptor Table to switch the system to/from FLAT Mode. +; Since these routines will be called from non-shadowed system +; ROM, the GDT must be on a QWORD boundary or else the bytes +; will get CORRUPTED! +; +;---------------------------------------------------------------------------- +;<AMI_SHDR_END> + +ALIGN 8 +big_gdt LABEL WORD + db 8 dup (0) ;00 - Null descriptor + db 0FFh,0FFh,000h,000h,000h,093h,08Fh,000h ; 08h - DS descriptor for flat mode +big_gdt_end LABEL WORD + +big_gdt_real LABEL WORD + db 8 dup (0) ;00 - Null descriptor + db 0FFh,0FFh,000h,000h,000h,093h,000h,000h ; 08h - DS descriptor for real mode +big_gdt_real_end LABEL WORD + +GDT_DESC LABEL BYTE + dw 010h ; Length of GDT + db 00,00h ; ptr to GDT + db 05h,00h +GDT_DESC_END LABEL BYTE + +Executable_code: + + push ds + push es + push eax + push ebx + push ecx + push edx + push si + push di + +; Changed for CSM - need to save SS, reload SS Limit to 64K selector and restore it + push bp + mov bp, ss + + mov al, 8Dh ; Disable NMI + out 70h, al + +;;; Copy contents from 5000:00(16 bytes) into registers + mov ax, 5000h + mov es, ax + mov si, 00h + mov eax, dword ptr es:[si] + add si, 4 + mov ebx, dword ptr es:[si] + add si, 4 + mov ecx, dword ptr es:[si] + add si, 4 + mov edx, dword ptr es:[si] + push eax + push ebx + push ecx + push edx + +;;; Copy GDT to 5000h:00h + mov ax, cs + mov ds, ax + cmp di, 08h + jne gbm_real + mov si, offset cs:big_gdt + jmp gbm_flat +gbm_real: + mov si, offset cs:big_gdt_real +gbm_flat: + mov ax, 5000h + mov es, ax + mov di, 00h + xor cx, cx + mov cx, 08h + rep movsw + + lgdt fword ptr cs:GDT_DESC + mov eax, cr0 + or al, 01h + mov cr0, eax ; In protected mode. + jmp gbm_00 ; Flush instruction queue - JMP (NEAR) + ; to next instruction. + +gbm_00: + mov ax, 08h ; Selector + mov ds, ax ; DS = selector. + mov es, ax ; ES = selector. + + mov eax, cr0 ; Come back into real mode with DS,ES + and al, 0FEh + mov cr0, eax + jmp gbm_01 ; Flush instruction queue - JMP (NEAR) + ; to next instruction. +gbm_01: + + xor ax, ax + mov ds, ax + mov es, ax + + pop edx + pop ecx + pop ebx +;;; Restore contents of 5000:00h(16 bytes) from registers + mov ax, 5000h + mov es, ax + mov si, 00h + pop eax + mov dword ptr es:[si], eax + add si, 4 + mov dword ptr es:[si], ebx + add si, 4 + mov dword ptr es:[si], ecx + add si, 4 + mov dword ptr es:[si], edx + + pop bp + pop di + pop si + pop edx + pop ecx + pop ebx + pop eax + pop es + pop ds + ret +go_big_mode ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: DisblGateA20 +; +; Description: This function disables GateA20 +; +; Input: None +; +; Output: None +; +; Modified: None +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> + +DisblGateA20 PROC NEAR PUBLIC + + push ax + mov al,00h + out 92h, al + +; Check the GA20 status.. +; Compare 256bytes at 0:0 with FFFF:10 +; If match, GA20 is disabled else GA20 is enabled. + push di + push es + push ds + push 0000h + pop ds ; DS = 0000. + push 0FFFFh + pop es ; ES = FFFF. + mov cx, 100h / 4 ; Number of Dwords in 256bytes. + xor si, si + mov di, 0010h + repz cmpsd + pop ds + pop es + pop di ;Descriptor table index in di + + jz dg20_end + + mov al, 0DDh ; Data for output port to disables A20. + out 60h, al + mov al, 0D1h + out 64h, al + +dg20_end: + pop ax + + ret + +DisblGateA20 ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: Get_EBDA +; +; Description: Get the EBDA Segment Address +; +; Input: None +; +; Output: DS: Ebda Segment +; +; Modified: Ds +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +Get_EBDA PROC NEAR PUBLIC + + push 40h + pop ds + mov ds, ds:[0Eh] ; DS - EBDA segment. + ret + +get_EBDA ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: Int0DHandler +; +; Description: Exception 0D handler +; +; Input: None +; +; Output: Exception_flag Set +; +; Modified: None +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +Int0DHandler PROC NEAR PUBLIC + push ds + call Get_EBDA + mov byte ptr ds:[102h],1 ;Set the Flag in Ebda:102 + pop ds + pop ax + add ax, 5 ; Go to Next instruction that doesn't + ; cause Exception + push ax + iret +Int0DHandler ENDP + +;<AMI_PHDR_START> +;---------------------------------------------------------------------------- +; +; Procedure: Check_Big_Real_mode +; +; Description: This function checks wheather system is in Big real mode +; +; Input: None +; +; Output: Carry Set - Not in Big Real mode +; Carry Not Set- System is in Big Real mode +; +; Modified: None +; +;---------------------------------------------------------------------------- +;<AMI_PHDR_END> +Check_Big_Real_mode PROC NEAR PUBLIC + push eax + push edi + push ebx + push es + push ds + pushf + cli + + call Get_EBDA + + mov byte ptr ds:[102h],0 ;EBDA:102 + + push 0 + pop es + + mov eax, dword ptr es:[0Dh*4] + push eax + + push cs ; Runtime segment + push offset cs:Int0DHandler-AhciApiModuleStart + pop eax + mov dword ptr es:[0Dh*4], eax + + + mov edi,0100000h + mov eax,dword ptr es:[edi] + cmp byte ptr ds:[102h],1 ;Check the exception + je Real_mode + + mov edi,0 + mov ebx,dword ptr es:[edi] + cmp eax,ebx + je Real_mode + + ;Read ,Write test for above 1Mb area + mov edi,0100000h + mov ebx,dword ptr es:[edi] + mov eax,055AA55AAh + mov dword ptr es:[edi],eax + mov eax,dword ptr es:[edi] + mov dword ptr es:[edi],ebx + cmp eax,055AA55AAh + jne Real_mode + pop eax + mov dword ptr es:[0Dh*4], eax + popf + clc ;System is in Big Real Mode + jmp Exit_Ret + +Real_mode: + pop eax + mov dword ptr es:[0Dh*4], eax + popf + stc ;System is in Real Mode +Exit_Ret: + pop ds + pop es + pop ebx + pop edi + pop eax + ret +Check_Big_Real_mode ENDP + +ENDIF + +AhciDataStart label word +AhciAccess AHCI_ACCESS (MKF_AHCI_CONTROLLER_COUNT) dup (<>) + +OEM16_CSEG ENDS + +END +;**************************************************************************** +;**************************************************************************** +;** ** +;** (C)Copyright 1985-2014, American Megatrends, Inc. ** +;** ** +;** All Rights Reserved. ** +;** ** +;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 ** +;** ** +;** Phone (770)-246-8600 ** +;** ** +;**************************************************************************** +;**************************************************************************** |