summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/sysmgr/cpu_init.asm
blob: 21e6c9ba9aa32d95b1def2d045750c8c2d68d844 (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
; 
; 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 contains code specific to the processor core.

include vsa2.inc
include gx2.inc
include sysmgr.inc
include init.inc
include chipset.inc
  	
.model small,c
.586

.CODE


externdef BIOS_ECX: dword
externdef BIOS_EDX: dword
externdef VSA_Image:byte

SMM_Size	dd	0
FooGlue		dd	54000000h

;***********************************************************************
; Sets CPU dependent fields in the SMM header
; On entry:
;   SI = pointer to VSM header
;***********************************************************************
Set_CPU_Fields proc

SMM_CONTROL  equ EXTL_SMI_EN + INTL_SMI_EN + SMM_INST_EN + NEST_SMI_EN

	mov	(VSM_Header PTR [si]).SysStuff.State.SMM_CTL_MSR, SMM_CONTROL
	ret
	
Set_CPU_Fields endp





;***********************************************************************
; - Sets the SMM entry point to the location in EBX
; - Sets the SMM header location
; - Write protects the SMM regions
;***********************************************************************
Init_SMM_Region proc

	; Set the SMM entry point
	mov	ecx, MSR_SMM_LOC
	mov	eax, ebx
	mov	edx, [SMM_Size]		; SMM Code Limit
	wrmsr

	; Set the SMM header location
	lea	eax, (VSM_Header PTR [eax]).SysStuff.State + sizeof(SmiHeader)
	mov	ecx, MSR_SMM_HDR
	xor	edx, edx
	wrmsr


	; Write protect the SMM memory
	mov	ecx, MSR_RCONF_SMM
	rdmsr	
	or	al, REGION_WP
	wrmsr

	ret
	
Init_SMM_Region endp






;***********************************************************************
; Returns information about the LX CPU
; On exit:
;  AX = CPU Revision
;  SI = CPU ID
;  BX = PCI MHz
;  CX = CPU MHz
;  DX = DRAM MHz
;***********************************************************************
Get_CPU_Info proc

	mov	ecx, 4C000014h 					; GLCP_SYS_RSTPLL
	rdmsr

	; PCI Speed
	mov	bx, 33
	test al, 1 SHL 7					; RSTPPL_LOWER_PCISPEED_SHIFT
	jz	not66
	mov	bx, 66
not66:	
	push bx								; save PCI speed

	; CPU Speed
	mov	ax, 333							; 33.3MHZ * 10

	ror	dx, 1							; RSTPLL_UPPER_CPUMULT_SHIFT
	mov	bx, dx
	rol	dx, 1							; RSTPLL_UPPER_CPUMULT_SHIFT
	push dx								; save RSTPLL
	and	bx, 1Fh
	inc	bx								; 0 = multiply by 1....
	mul	bx								; ax=PCI * bl=Mul

	; Rounding divide
	mov	bx, 10
	xor	dx, dx
	div	bx								; ax= quotent and dx=remainder
	cmp	dx, 5
	jb	NoRound							; can round because of /10
	inc	ax								; round up
NoRound:
	pop dx								; restore RSTPLL
	pop bx								; restore PCI * 10
	push ax								; save CPU speed


	; DRAM speed
	mov	ax, 333							; 33.3MHZ * 10
	
	ror	dx, 7							; RSTPLL_UPPER_GLMULT_SHIFT
	mov	bx, dx
	rol	dx, 7							; RSTPLL_UPPER_GLMULT_SHIFT
	push dx								; save RSTPLL
	and	bx, 1Fh
	inc	bx								; 0 = multiply by 1....
	mul	bx								; ax=PCI * bl=Mul

	; Rounding divide
	mov	bx, 10
	xor	dx, dx
	div	bx								; ax= quotent and dx=remainder
	cmp	dx, 5
	jb	NoRoundmem						; can round because of /10
	inc	ax								; round up
NoRoundmem:

	; DDR is 1/2 GeodeLink speed.
	xor	dx, dx
	mov bx, 2
	div	bx
	push ax								; save mem speed

	; Get CPU Revision
	mov	cx, 0017h
	rdmsr
	push	ax
	
	mov	ecx, 10002000h	; Read MBIU0 Capabilities MSR
	rdmsr
	and	ah, 0Fh			; Extract 4 LSBs of DEVID
	cmp	ah, 04h			; Is it LX ?
	mov	si, DEVICE_ID_GX2
	jne	RestoreInfo
	mov	si, DEVICE_ID_LX	; Yes
	mov	[FooGlue], 4C000020h	; FooGlue is at Northbridge MCP + 20h
RestoreInfo:
	pop	ax			; Restore CPU Revision
	pop	dx			; Restore DRAM MHz	
	pop	cx			; Restore CPU MHz
	pop	bx			; Restore PCI MHz
	ret

Get_CPU_Info endp



;***********************************************************************
; Returns the SMM information
; On Exit:
;    EAX = SMM entry point
;     BX = Size of SMM memory in KB
;***********************************************************************
Get_SMM_Region proc 
	Local Attributes: byte

	mov	ecx, MSR_RCONF_DEFAULT
	rdmsr
	mov	[Attributes], al


	mov	ecx, [BIOS_ECX]		; Descriptor for SMM memory
	rdmsr
	cmp	cl, 27h			; P2D_BMO or P2D_RO ?
	jbe	BaseMaskOffset
	mov	ebx, eax	      	; P2D_RO
	shl	eax, 12			; EAX = SMM base
	shrd	ebx, edx, 8		; EBX = end of SMM range
	and	bx, 0F000h
	sub	ebx, eax		; Compute length of range
	add	ebx, 1000h		; Adjust for 4KB granularity
	shr	ebx, 10			; Convert to KB
	jmp	short Save_SMM_Base

BaseMaskOffset:       
	mov	ebx, eax		; BX = length of SMM memory in KB
	shrd	eax, edx, 8		; EAX = Base
	and	ax, 0F000h

	or	ebx, 0FFF00000h
	neg	ebx
	shl	ebx, 2			; Adjust for 4KB granularity

Save_SMM_Base:
	push	eax			; Save SMM base
	push	bx			; Save SMM size in KB

	shl	ebx, 10			; Convert KB to bytes
	dec	ebx
	mov	[SMM_Size], ebx		; Save size for MSR_SMM_LOC

	; Set SMM RCONF
	and	bx, 0F000h
	mov	edx, ebx		; SMM_TOP = SMM_BASE + sizeof(SMM region)
	add	edx, eax
	mov	dl, [Attributes]	; SMM active properties mirror RCONF_DEFAULT
	or	ah, 1 			; Set Enable
	mov	al, dl			; SMM inactive properties (R/W for now)
	and	al, NOT REGION_WP
	mov	ecx, MSR_RCONF_SMM
	wrmsr

	pop	bx			; BX = size of SMM region in KB
	pop	eax			; EAX = base of SMM region

	ret
	
Get_SMM_Region endp


;****************************************************************
; Enables SMIs
;****************************************************************
Enable_SMIs proc

	; Enable internal and external SMIs
	mov	ecx, MSR_SMM_CTRL
	rdmsr
	or	eax, INTL_SMI_EN + EXTL_SMI_EN
	wrmsr

	ret

Enable_SMIs endp	




;***********************************************************************
; Enables the SMM instructions
;***********************************************************************
Enable_SMM_Instr proc
	
	mov	ecx, MSR_SMM_CTRL
	rdmsr
	or	eax, SMM_INST_EN
	wrmsr
	ret

Enable_SMM_Instr endp




;***********************************************************************
; Disables the A20 masking at the processor.
;***********************************************************************
Disable_A20 proc

	mov	ecx, [FooGlue]
	add	cx, FG_A20M
	rdmsr
	and	al, NOT A20M		; A20M = 0
	wrmsr
	ret
	
Disable_A20 endp





;***********************************************************************
; Gets the size of physical memory
; On Exit:
;  EAX = physical memory size in bytes
;***********************************************************************
Get_Memory_Size proc	

	mov	ecx, [BIOS_EDX]		; P2D_R descriptor of physical memory
	jecxz	Exit
	rdmsr
; EDX = 2000001F
; EAX = FDF00100
; 1MB thru <512MB-192K)
	
	shrd	eax, edx, 20		; Extract PMAX field
	shl	eax, 12			; Convert units from 4KB to bytes
Exit:	ret
	
Get_Memory_Size endp






; The linker won't allow code to be put in a PARA aligned segment.
; The following will align the next module to a paragraph boundary.
TEXT	SEGMENT PARA 'CODE'

	db	16 dup (0)

TEXT	ENDS

	END