summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm')
-rwxr-xr-xcpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm368
1 files changed, 368 insertions, 0 deletions
diff --git a/cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm b/cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm
new file mode 100755
index 0000000..a61fd25
--- /dev/null
+++ b/cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm
@@ -0,0 +1,368 @@
+;
+; Copyright (c) 2006-2008 Advanced Micro Devices,Inc. ("AMD").
+;
+; This library is free software; you can redistribute it and/or modify
+; it under the terms of the GNU Lesser General Public License as
+; published by the Free Software Foundation; either version 2.1 of the
+; License, or (at your option) any later version.
+;
+; This code is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+; Lesser General Public License for more details.
+;
+; You should have received a copy of the GNU Lesser General
+; Public License along with this library; if not, write to the
+; Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+; Boston, MA 02111-1307 USA
+;
+;* Function: *
+;* This file library functions for accessing registers & headers
+
+include SYSMGR.INC
+include VSA2.INC
+include SMIMAC.MAC
+
+
+
+.model tiny,c
+.586p
+.CODE
+
+
+
+public Function
+
+externdef Async_VSM: dword
+externdef sys_system_call:proc
+
+Function db 0, 0, 0, 0
+
+;***********************************************************************
+; Reports a parameter error
+;
+; EAX = parameter
+;***********************************************************************
+ParamError proc
+ ; SYS_REPORT_ERROR(ERR_BAD_PARAMETER, macro, param);
+ push word ptr ERR_BAD_PARAMETER
+ mov bh, [Function]
+ mov bl, 1 ; Parameter #1
+ push ebx ; Info1
+ push eax ; Info2
+ call sys_report_error
+ ret
+
+ParamError endp
+
+
+;***********************************************************************
+; Validates if a macro is valid for the current message.
+; Output: if "invalid macro usage"
+; sys_report_error(ERR_ILLEGAL_MACRO);
+; set CF
+; else
+; clear CF
+; EBX = ptr to relevant VSM's stack
+; ECX = ptr to relevant VSM's state
+; NOTE: Must preserve AX
+;***********************************************************************
+ValidateMacro proc
+ mov ebx, [Async_VSM]
+ test ebx, ebx
+ jz short NotSynchronous
+
+ ; Mark blocked VSM as 'Ready'
+ mov fs:(VSM_Header PTR [ebx]).SysStuff.RunFlag, RUN_FLAG_READY
+ jmp short Macro_OK
+
+
+
+NotSynchronous:
+ ; Always allow GET_REGISTER, GET_DESCRIPTOR & GET_HEADER
+ test byte ptr [Function], 1
+ jnz Async_Error
+
+ ; Get ptr to System Manager's VSM header
+ mov ebx, (VSM_Header PTR [bx]).SysStuff.SysMgr_Ptr
+ sub ebx, SPECIAL_LOC
+
+Macro_OK:
+ mov ecx, ebx
+ add ebx, fs:(VSM_Header PTR [ecx]).SysStuff.SavedESP
+ add ebx, EXTRA_SAVE
+
+ lea ecx, (VSM_Header PTR [ecx]).SysStuff.State
+ clc
+ ret
+
+Async_Error:
+
+ ; SYS_REPORT_ERROR(ERR_ILLEGAL_MACRO, macro, argument);
+ push word ptr ERR_ILLEGAL_MACRO
+ push dword ptr [Function]
+ movzx eax, ax
+ push eax
+ call sys_report_error
+
+ mov ax, 0FFFFh ; Return FFFFs
+ mov dx, ax
+ stc
+ ret
+
+ValidateMacro endp
+
+
+
+
+
+;***********************************************************************
+; Helper routine for SYS_SET_REGISTER and SYS_SET_HEADER_DATA macros.
+; Input:
+; AL = offset
+; EBX = base
+; ECX = data
+; DL = max field offset
+;************************************************************ ***********
+SetHeader:
+ mov dx, R_DR7 ; Max valid field
+SetField proc
+
+ cmp al, dl ; Valid field name ?
+ ja short Error ; No
+
+ mov dx, ax ; Save field size
+ xor ah, ah ; Extract offset
+ movzx eax, ax
+ mov fs:[ebx+eax], cl ; Store data as BYTE
+ test dx, (DWORD_SIZE OR WORD_SIZE)
+ jz Exit
+ test dx, DWORD_SIZE ; WORD or DWORD ?
+ jz Set_Word
+Set_Dword:
+ db 66h ; DWORD
+Set_Word:
+ mov fs:[ebx+eax], cx ; WORD
+ clc
+Exit: ret
+
+Error: call ParamError
+ ret
+
+SetField endp
+
+
+
+;***********************************************************************
+; Helper routine for SYS_GET_REGISTER and SYS_GET_HEADER_DATA macros.
+; Input:
+; EBX = base of structure
+; AX = offset
+; DX = maximum valid offset
+; Output:
+; DX:AX = data
+;***********************************************************************
+GetField proc
+
+ cmp al, dl ; Valid field name ?
+ ja short Error ; No, return FFFFs
+
+ mov cx, ax ; Save field size
+ xor ah, ah ; Extract offset
+ movzx eax, ax
+ mov eax, fs:[ebx+eax] ; Get requested value
+ test cx, DWORD_SIZE ; DWORD field ?
+ jz NotDword
+ mov edx, eax ; Put 16 MSBs into DX
+ shr edx, 16
+ ret
+
+NotDword:
+ xor dx, dx ; Zero 16 MSBs
+ test cx, WORD_SIZE ; WORD field ?
+ jnz Exit
+ xor ah, ah ; BYTE field
+Exit: ret
+
+Error: call ParamError
+ mov ax, 0FFFFh ; Return FFFFs
+ mov dx, ax
+ ret
+
+GetField endp
+
+
+
+
+
+;***********************************************************************
+; ULONG sys_get_register(USHORT register)
+;***********************************************************************
+sys_get_register proc pascal \
+ Register:WORD
+
+ mov ax, [Register] ; Get which register
+ mov [Function], GET_REG ; In case of error
+ call ValidateMacro ; Get ptr to registers
+ jc Exit
+
+ test ax, FROM_HEADER ; Is register in SMM header ?
+ jnz Get_Header
+
+ mov dx, R_GS
+ call GetField ; Get register from saved state buffer
+
+Exit: ret
+
+sys_get_register endp
+
+
+
+
+
+;***********************************************************************
+; void sys_set_register(USHORT register, ULONG Data)
+;***********************************************************************
+sys_set_register proc pascal \
+ Register: WORD, \
+ Data: DWORD
+
+ mov ax, [Register] ; Get register
+ mov [Function], SET_REG ; In case of error
+ call ValidateMacro ; Get ptr to registers
+ jc Exit
+
+ test ax, FROM_HEADER ; Is register in SMM header ?
+ jnz Set_Header
+
+ mov ecx, [Data]
+
+ mov dx, R_ESP ; Max valid register field
+ call SetField
+
+Exit: ret
+
+sys_set_register endp
+
+
+
+
+;***********************************************************************
+; Gets a field from the top-level SMM header
+; ULONG sys_get_header_data(USHORT SMM_Field)
+;***********************************************************************
+sys_get_header_data proc pascal \
+ SMM_Field: WORD
+
+ mov ax, [SMM_Field] ; Get SMM header field
+ mov [Function], GET_HDR ; In case of error
+ call ValidateMacro
+ jc short Exit
+
+ mov ax, [SMM_Field] ; Get SMM header field
+ test ax, FROM_HEADER ; Validate field
+ jnz short Get_Header
+ call ParamError
+ jmp short Exit
+
+Get_Header::
+ mov ebx, ecx
+ mov dx, R_DR7 ; Max valid field
+ call GetField
+Exit: ret
+
+sys_get_header_data endp
+
+
+
+;***********************************************************************
+; void sys_set_header_data(USHORT SMM_Field, ULONG Data)
+;***********************************************************************
+sys_set_header_data proc pascal \
+ SMM_Field: WORD, \
+ Data: DWORD
+
+ mov ax, [SMM_Field] ; Get SMM header field
+ mov [Function], SET_HDR ; In case of error
+ call ValidateMacro
+ jc short Exit
+
+ test ax, FROM_HEADER ; Validate field
+ jnz short Set_Header
+ call ParamError
+ jmp short Exit
+
+Set_Header::
+ mov ebx, ecx
+ mov ecx, [Data]
+ call SetHeader
+Exit: ret
+
+sys_set_header_data endp
+
+
+
+;***********************************************************************
+; Reports an error
+;***********************************************************************
+sys_report_error proc pascal uses di \
+ Error_Code: WORD, \
+ Info1: DWORD, \
+ Info2: DWORD
+
+ mov di, [Error_Code]
+ mov ebx, [Info1]
+ mov ecx, [Info2]
+
+ mov ax, SYS_CODE_ERROR
+ call sys_system_call
+ ret
+
+sys_report_error endp
+
+
+;***********************************************************************
+; void sys_return_result(ULONG Result);
+;
+; Implements the SYS_RETURN_RESULT macro
+; Returns a byte/word/dword result to the appropriate environment
+;
+;***********************************************************************
+sys_return_result proc pascal \
+ Result: DWORD
+
+
+ mov ebx, [Result]
+
+ ; Return to another VSM's environment ?
+ mov ecx, [Async_VSM]
+ mov eax, (VSM_Header PTR ds:[0]).SysStuff.SysMgr_Ptr
+ xor ax, ax
+ cmp ecx, eax
+ je RetToTopLevel
+
+ ; Yes, get the data size
+ mov dl, byte ptr fs:(VSM_Header PTR [ecx]).SysStuff.State.data_size
+ mov ax, R_AL
+ cmp dl, BYTE_IO
+ je SetReg
+ mov ax, R_AX
+ cmp dl, WORD_IO
+ je SetReg
+ mov ax, R_EAX
+SetReg:
+ push ax ; Register AL/AX/EAX
+ push ebx ; Data
+ call sys_set_register
+ jmp Exit
+
+RetToTopLevel:
+ mov ax, SYS_CODE_RESULT ; Let SysMgr return the result
+ call sys_system_call
+Exit: ret
+
+sys_return_result endp
+
+
+ END
+