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)
|