summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/vsm_lib/regs.asm
blob: a61fd25e471cee215d46b4958f13e46b57a70729 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
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