summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halfire/ppc/fpcpu.s
blob: c052c9787eaf1836480b2df9279768998e019482 (plain) (blame)
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
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
//++
//
// Copyright (c) 1994 MOTOROLA, INC.  All Rights Reserved.  This file
// contains copyrighted material.  Use of this file is restricted
// by the provisions of a Motorola Software License Agreement.
//
// Module Name:
//
//    pxsystem.s
//
// Abstract:
//
//	This module implements the routines to handle system functions:
//	Provides system specific info.
//		Currently provides processor version type
//
// Author:
//	breeze@firepower.com
//
// Environment:
//
//    Kernel mode only.
//
// Revision History:
//
//--

/*
 * Copyright (c) 1995 FirePower Systems, Inc.
 * DO NOT DISTRIBUTE without permission
 *
 * $RCSfile: fpcpu.s $
 * $Revision: 1.12 $
 * $Date: 1996/01/11 07:05:51 $
 * $Locker:  $
 */

#include "kxppc.h"
#include "fpcpu.h"

	.set	BatValue,	r.3
//++
//
//  Routine Description:
//
//
//  Arguments:
//	None
//
//
//  Return Value:
//	Processor Version register value
//
//
//--


	LEAF_ENTRY(HalpReadProcessorRev)
	mfpvr	r.3			// get processor version
	LEAF_EXIT(HalpReadProcessorRev)



//++
//
//  Routine Description:
//
//
//  Arguments:
//	None
//
//
//  Return Value:
//	Machine State register value
//
//
//--


	LEAF_ENTRY(HalpGetStack)
		or r3, r1, r1	// get stack value
	LEAF_EXIT(HalpGetStack)


//++
//
//  Routine Description:
//
//
//  Arguments:
//	None
//
//
//  Return Value:
//	Machine State register value
//
//
//--


	LEAF_ENTRY(HalpReadMSR)
	mfmsr	r.3			// get processor version
	LEAF_EXIT(HalpReadMSR)

/*****************************************************************************
    Synopsis:
	ULONG HalpReadIbatUpper(ULONG BatNumber) 	[ged]

    Purpose:
	Supplies the 32-bit upper instruction BAT value
				for a given <BatNumber>.

    Returns:
	Returns the 32-bit upper BAT value.
*****************************************************************************/

	.set	BatNumber,	r.3

	LEAF_ENTRY(HalpReadIbatUpper)

	cmpli	0,0,BatNumber,0
	bne	NotUI0
	mfibatu	BatNumber,0
	b	ExitUI
NotUI0:
	cmpli	0,0,BatNumber,1
	bne	NotUI1
	mfibatu	BatNumber,1
	b	ExitUI
NotUI1:
	cmpli	0,0,BatNumber,2
	bne	NotUI2
	mfibatu	BatNumber,2
	b	ExitUI
NotUI2:
	mfibatu	BatNumber,3		// OK, it's three by default

ExitUI:
	
	LEAF_EXIT(HalpReadIbatUpper)

/*****************************************************************************
    Synopsis:
	ULONG HalpReadIbatLower(ULONG BatNumber)		[ged]

    Purpose:
	Supplies the 32-bit lower instruction BAT value for given <BatNumber>.

    Returns:
	Returns the 32-bit lower BAT value.
*****************************************************************************/

	LEAF_ENTRY(HalpReadIbatLower)

	cmpli	0,0,BatNumber,0
	bne	NotLI0
	mfibatl	BatNumber,0
	b	ExitLI
NotLI0:
	cmpli	0,0,BatNumber,1
	bne	NotLI1
	mfibatl	BatNumber,1
	b	ExitLI
NotLI1:
	cmpli	0,0,BatNumber,2
	bne	NotLI2
	mfibatl	BatNumber,2
	b	ExitLI
NotLI2:
	mfibatl	BatNumber,3		// OK, it's three by default

ExitLI:
	
	LEAF_EXIT(HalpReadIbatLower)

/*****************************************************************************
    Synopsis:
	ULONG HalpReadDbatUpper(ULONG BatNumber) 	[ged]

    Purpose:
	Supplies the 32-bit upper data BAT value for a given <BatNumber>.

    Returns:
	Returns the 32-bit upper BAT value.
*****************************************************************************/

	LEAF_ENTRY(HalpReadDbatUpper)

	cmpli	0,0,BatNumber,0
	bne	NotUD0
	mfdbatu	BatNumber,0
	b	ExitUD
NotUD0:
	cmpli	0,0,BatNumber,1
	bne	NotUD1
	mfdbatu	BatNumber,1
	b	ExitUD
NotUD1:
	cmpli	0,0,BatNumber,2
	bne	NotUD2
	mfdbatu	BatNumber,2
	b	ExitUD
NotUD2:
	mfdbatu	BatNumber,3		// OK, it's three by default

ExitUD:
	
	LEAF_EXIT(HalpReadDbatUpper)

/*****************************************************************************
    Synopsis:
	ULONG HalpReadDbatLower(ULONG BatNumber)		[ged]

    Purpose:
	Supplies the 32-bit lower data BAT value for a given <BatNumber>.

    Returns:
	Returns the 32-bit lower BAT value.
*****************************************************************************/

	LEAF_ENTRY(HalpReadDbatLower)

	cmpli	0,0,BatNumber,0
	bne	NotLD0
	mfdbatl	BatNumber,0
	b	ExitLD
NotLD0:
	cmpli	0,0,BatNumber,1
	bne	NotLD1
	mfdbatl	BatNumber,1
	b	ExitLD
NotLD1:
	cmpli	0,0,BatNumber,2
	bne	NotLD2
	mfdbatl	BatNumber,2
	b	ExitLD
NotLD2:
	mfdbatl	BatNumber,3		// OK, it's three by default

ExitLD:
	
	LEAF_EXIT(HalpReadDbatLower)

/*****************************************************************************
    Synopsis:
	VOID HalpSetDbat3Lower(ULONG BatValue)		[ged]

    Purpose:
	Writes the 32-bit lower data BAT value <BatValue> to DBAT3.

    Returns:
	Nothing
*****************************************************************************/


	LEAF_ENTRY(HalpSetDbat3Lower)

	mtdbatl	3,BatValue
	
	LEAF_EXIT(HalpSetDbat3Lower)

/*****************************************************************************
    Synopsis:
	VOID HalpSetDbat3Lower(ULONG BatValue)		[ged]

    Purpose:
	Writes the 32-bit lower data BAT value <BatValue> to DBAT1.

    Returns:
	Nothing
*****************************************************************************/

	LEAF_ENTRY(HalpSetDbat2Lower)

	mtdbatl	2,BatValue
	
	LEAF_EXIT(HalpSetDbat2Lower)

/*****************************************************************************
    Synopsis:
	VOID HalpSetDbat3Lower(ULONG BatValue)		[ged]

    Purpose:
	Writes the 32-bit lower data BAT value <BatValue> to DBAT1.

    Returns:
	Nothing
*****************************************************************************/

	LEAF_ENTRY(HalpSetDbat1Lower)

	mtdbatl	1,BatValue
	
	LEAF_EXIT(HalpSetDbat1Lower)

/*****************************************************************************
    Synopsis:
	VOID HalpSetDbat3Lower(ULONG BatValue)		[ged]

    Purpose:
	Writes the 32-bit lower data BAT value <BatValue> to DBAT1.

    Returns:
	Nothing
*****************************************************************************/

	LEAF_ENTRY(HalpSetDbat0Lower)

	mtdbatl	0,BatValue
	
	LEAF_EXIT(HalpSetDbat0Lower)


/*****************************************************************************
	Synopsis:
	VOID  HalpGetInstructionTimes()

	Purpose:
		run a 1024 instructions measure how long the cpu needs to
		execute them ( measured by time base value which is 1/4 bus speed )

	Algorithm:
		string together 8 instructions so that they are dependent on their
		preceding neighbor and loop through this set of 8 instructions 128
		times.  Compare the lower time base register's value before and after
		this instruction run.

		To guarentee correct timing, this routine waits for the lower time base
		register to 'flip' to the new value and then start running the test
		instructions.  The run is done three times to make sure the entire
		sequence is in L1 cache.

		The Time Base runs at 1/4 bus speed so the number of instructions
		that the cpu executes for a given amount of time is measured as
		the amount of time required to run 1024 instructions.  If the time
		base changes by 256 'ticks' then the cpu is running at bus speed.

	Returns:	the	incremental change in the time base lower register
	
*****************************************************************************/

	//.set LOOPCOUNT,  0x400	// 8 * real loop count (8 * 0x80 ).
	.set LOOPCOUNT,  0x780	// 8 * real loop count (8 * 0x80 ).
	LEAF_ENTRY(HalpGetInstructionTimes)

		sync
		andi.	r10,r9,0	// zero r10: holds the current loop count
		andi.   r8,r9,0     // zero r8: holds the do again flag.
		andi.	r7,r9,0		// zero r7:	 execution time within each loop through
		andi.   r3,r9,0     // zero r3:	 maintain summation of execution times
		andi.	r9,r9,0		// zero r9: holds the current loop count
		sync
START:	mftb r6				// save off the starting value of lower time
							// base register
CHECK:	mftb r5				// check the time base again and see if it's just
							// changed....
		cmp		0,0,r5,r6
		beq		CHECK		// wait for a new time period to start...

		//
		// Run through some single cycle instructions.  In order to defeat
		// the double issue pipes of the ppc, create a dependency between
		// an instruction and the preceding instruction.  This will more
		// accurately reflect the amount of time the cpu uses to execute
		// an instruction in a stream relative to the bus frequency.
		//
TIMES:	addi    r9,r9,1
		addi	r9,r9,1
		addi    r9,r9,1
		addi	r9,r9,1
		addi	r9,r9,1
		addi	r9,r9,1
		addi	r9,r9,1
		addi	r9,r9,1	

		cmpi	0,0,r9,LOOPCOUNT
		bne		TIMES		// bc 4,2,TIMES
		mftb 	r6			// save off ending value of lower time base register
		sync
		andi.	r9,r9,0		// zero r9: in preparation for another pass
		addi	r8,r8,1		// increment the flag
		cmpli	0,0,r8,2	// compare the flag to '2'.  Ensure the last pass
							// through is fully out of L1 cache.
		blt     START       // to make sure we're in cache, branch back.
		subf    r3,r5,r6    // subtract r5 from r6 and store in r3 and return.
	
	LEAF_EXIT(HalpGetInstructionTimes)