]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ppc/Firmware.s
xnu-1228.12.14.tar.gz
[apple/xnu.git] / osfmk / ppc / Firmware.s
1 /*
2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * @OSF_FREE_COPYRIGHT@
30 */
31 /*
32 * @APPLE_FREE_COPYRIGHT@
33 */
34
35 /*
36 Firmware.s
37
38 Handle things that should be treated as an extension of the hardware
39
40 Lovingly crafted by Bill Angell using traditional methods and only natural or recycled materials.
41 No animal products are used other than rendered otter bile and deep fried pork lard.
42
43 */
44
45 #include <ppc/asm.h>
46 #include <ppc/proc_reg.h>
47 #include <ppc/spec_reg.h>
48 #include <ppc/exception.h>
49 #include <mach/machine/vm_param.h>
50 #include <assym.s>
51
52
53 /*
54 * Here we generate the table of supported firmware calls
55 */
56
57
58
59 .data
60 .align 5 /* Line up on cache line */
61
62 .globl EXT(FWtable)
63
64 EXT(FWtable):
65
66 .globl CutTrace /* Let everyone know 'bout it */
67 .set CutTrace,(.-EXT(FWtable))/4|0x80000000 /* Call number for CutTrace */
68 .long callUnimp /* This was already handled in lowmem_vectors */
69
70 #include <ppc/FirmwareCalls.h>
71
72 .set EXT(FirmwareCnt), (.-EXT(FWtable))/4 /* Get the top number */
73
74 .text
75
76 #define SIMPLESCC 1
77 #define NOTQUITEASSIMPLE 1
78 /*
79 * This routine handles the firmware call routine. It must be entered with IR and DR off,
80 * interruptions disabled, and in supervisor state.
81 *
82 * When we enter, we expect R0 to have call number, and LR
83 * to point to the return. Also, all registers saved in savearea in R13.
84 * R3 is as passed in by the user. All others must be gotten from the save area
85 */
86
87
88 .align 5
89 .globl EXT(FirmwareCall)
90
91 LEXT(FirmwareCall)
92
93 rlwinm r1,r0,2,1,29 /* Clear out bit 0 and multiply by 4 */
94 lis r12,HIGH_ADDR(EXT(FWtable)) /* Get the high part of the firmware call table */
95 cmplwi r1,EXT(FirmwareCnt)*4 /* Is it a valid firmware call number */
96 ori r12,r12,LOW_ADDR(EXT(FWtable)) /* Now the low part */
97 ble+ goodCall /* Yeah, it is... */
98
99 li r3,T_SYSTEM_CALL /* Tell the vector handler that we know nothing */
100 b EXT(FCReturn) ; Bye dudes...
101
102 goodCall: mfsprg r10,0 /* Make sure about the per_proc block */
103 lwzx r1,r1,r12 /* Pick up the address of the routine */
104 lwz r4,saver4+4(r13) /* Pass in caller's R4 */
105 lwz r5,saver5+4(r13) /* Pass in caller's R5 */
106 rlwinm. r1,r1,0,0,29 /* Make sure the flag bits are clear */
107
108 mtlr r1 /* Put it in the LR */
109 beq- callUnimp /* This one was unimplimented... */
110
111 blrl /* Call the routine... */
112
113 stw r3,saver3+4(r13) /* Pass back the return code to caller */
114 li r3,T_IN_VAIN /* Tell the vector handler that we took care of it */
115 b EXT(FCReturn) ; Bye dudes...
116
117 callUnimp: li r3,T_SYSTEM_CALL /* Tell the vector handler that we know nothing */
118 b EXT(FCReturn) ; Bye dudes...
119
120 /*
121 * This routine is used to store using a real address. It stores parmeter1 at parameter2.
122 */
123
124 .align 5
125 .globl EXT(StoreReal)
126
127 LEXT(StoreReal)
128
129 lis r0,HIGH_ADDR(StoreRealCall) /* Get the top part of the SC number */
130 ori r0,r0,LOW_ADDR(StoreRealCall) /* and the bottom part */
131 sc /* Do it to it */
132 blr /* Bye bye, Birdie... */
133
134 .align 5
135 .globl EXT(StoreRealLL)
136
137 LEXT(StoreRealLL)
138
139 stw r3,0(r4) /* Store the word */
140 blr /* Leave... */
141
142 /*
143 * This routine is used to clear a range of physical pages.
144 */
145
146 .align 5
147 .globl EXT(ClearReal)
148
149 LEXT(ClearReal)
150
151 lis r0,HIGH_ADDR(ClearRealCall) /* Get the top part of the SC number */
152 ori r0,r0,LOW_ADDR(ClearRealCall) /* and the bottom part */
153 sc /* Do it to it */
154 blr /* Bye bye, Birdie... */
155
156
157 .align 5
158 .globl EXT(ClearRealLL)
159
160 LEXT(ClearRealLL)
161
162 /*
163 * We take the first parameter as a physical address. The second is the length in bytes.
164 * Being crazy, I'll round the address down, and the length up. We could end up clearing
165 * an extra page at the start and one at the end, but we don't really care. If someone
166 * is stupid enough to give me unaligned addresses and lengths, I am just arrogant enough
167 * to take them at their word and to hell with them.
168 */
169
170 neg r5,r3 /* Negate the address */
171 addi r4,r4,4095 /* Round length up */
172 rlwinm r5,r5,0,20,31 /* Save extra length */
173 rlwinm r3,r3,0,0,19 /* Round the page on down */
174 add r4,r4,r5 /* Add up all extra lengths */
175 li r6,32 /* Get a displacement */
176 rlwinm r4,r4,0,0,19 /* Round the length back down */
177
178 clrloop: subi r4,r4,32 /* Back off a cache line */
179 dcbz 0,r3 /* Do the even line */
180 sub. r4,r4,r6 /* Back off a second time (we only do this to generate a CR */
181 dcbz r6,r3 /* Clear the even line */
182 addi r3,r3,64 /* Move up to every other line */
183 bgt+ clrloop /* Go until we've done it all... */
184
185 blr /* Leave... */
186 /*
187 * This routine will read in 32 byte of real storage.
188 */
189
190 .align 5
191 .globl EXT(ReadReal)
192
193 LEXT(ReadReal)
194
195 mfsprg r9,2 ; Get the features
196 mfmsr r0 ; Get the MSR
197 li r8,lo16(MASK(MSR_DR)) ; Get the DR bit
198 rlwinm. r9,r9,0,pf64Bitb,pf64Bitb ; Are we 64-bit?
199 ori r8,r8,lo16(MASK(MSR_EE)) ; Add in the EE bit
200 li r7,1 ; Get set for it
201 andc r8,r0,r8 ; Turn off EE and DR
202 bt-- cr0_eq,rr32a ; Yes, we are...
203
204 rldimi r8,r7,63,MSR_SF_BIT ; Set SF bit (bit 0)
205 sldi r3,r3,32 ; Slide on over for true 64-bit address
206 mtmsrd r8
207 isync
208 or r3,r3,r4 ; Join top and bottom of address
209 mr r4,r5 ; Set destination address
210 b rrJoina ; Join on up...
211
212 rr32a: mr r3,r4 ; Position bottom of long long
213 mr r4,r5 ; Set destination address
214 mtmsr r8 /* Disable EE and DR */
215 isync /* Just make sure about it */
216
217 rrJoina: lwz r5,0(r3) /* Get word 0 */
218 lwz r6,4(r3) /* Get word 1 */
219 lwz r7,8(r3) /* Get word 2 */
220 lwz r8,12(r3) /* Get word 3 */
221 lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
222 lwz r9,16(r3) /* Get word 4 */
223 ori r2,r2,lo16(MASK(MSR_FP)) ; Get the FP enable
224 lwz r10,20(r3) /* Get word 5 */
225 andc r0,r0,r2 ; Clear VEC and FP enables
226 lwz r11,24(r3) /* Get word 6 */
227 lwz r12,28(r3) /* Get word 7 */
228
229 bt-- cr0_eq,rr32b ; We are not 64-bit...
230
231 mtmsrd r0
232 isync
233 b rrJoinb ; Join on up...
234
235 rr32b: mtmsr r0 /* Restore original machine state */
236 isync /* Insure goodness */
237
238 rrJoinb: stw r5,0(r4) /* Set word 0 */
239 stw r6,4(r4) /* Set word 1 */
240 stw r7,8(r4) /* Set word 2 */
241 stw r8,12(r4) /* Set word 3 */
242 stw r9,16(r4) /* Set word 4 */
243 stw r10,20(r4) /* Set word 5 */
244 stw r11,24(r4) /* Set word 6 */
245 stw r12,28(r4) /* Set word 7 */
246
247 blr
248
249
250 /*
251 * This routine is used to load all 4 DBATs.
252 */
253
254 .align 5
255 .globl EXT(LoadDBATs)
256
257 LEXT(LoadDBATs)
258
259
260 lis r0,HIGH_ADDR(LoadDBATsCall) /* Top half of LoadDBATsCall firmware call number */
261 ori r0,r0,LOW_ADDR(LoadDBATsCall) /* Bottom half */
262 sc /* Do it to it */
263
264 blr /* Bye bye, Birdie... */
265
266
267 .align 5
268 .globl EXT(xLoadDBATsLL)
269
270 LEXT(xLoadDBATsLL)
271
272 lwz r4,0(r3) /* Get DBAT 0 high */
273 lwz r5,4(r3) /* Get DBAT 0 low */
274 lwz r6,8(r3) /* Get DBAT 1 high */
275 lwz r7,12(r3) /* Get DBAT 1 low */
276 lwz r8,16(r3) /* Get DBAT 2 high */
277 lwz r9,20(r3) /* Get DBAT 2 low */
278 lwz r10,24(r3) /* Get DBAT 3 high */
279 lwz r11,28(r3) /* Get DBAT 3 low */
280
281 sync /* Common decency and the state law require that you wash your hands */
282 mtdbatu 0,r4 /* Load DBAT 0 high */
283 mtdbatl 0,r5 /* Load DBAT 0 low */
284 mtdbatu 1,r6 /* Load DBAT 1 high */
285 mtdbatl 1,r7 /* Load DBAT 1 low */
286 mtdbatu 2,r8 /* Load DBAT 2 high */
287 mtdbatl 2,r9 /* Load DBAT 2 low */
288 mtdbatu 3,r10 /* Load DBAT 3 high */
289 mtdbatl 3,r11 /* Load DBAT 3 low */
290 sync /* Make sure it's done */
291 isync /* Toss out anything new */
292
293 blr /* Leave... */
294
295 /*
296 * This routine is used to load all 4 IBATs.
297 */
298
299 .align 5
300 .globl EXT(LoadIBATs)
301
302 LEXT(LoadIBATs)
303
304
305 lis r0,HIGH_ADDR(LoadIBATsCall) /* Top half of LoadIBATsCall firmware call number */
306 ori r0,r0,LOW_ADDR(LoadIBATsCall) /* Bottom half */
307 sc /* Do it to it */
308 blr /* Bye bye, Birdie... */
309
310 .align 5
311 .globl EXT(xLoadIBATsLL)
312
313 LEXT(xLoadIBATsLL)
314
315 lwz r4,0(r3) /* Get IBAT 0 high */
316 lwz r5,4(r3) /* Get IBAT 0 low */
317 lwz r6,8(r3) /* Get IBAT 1 high */
318 lwz r7,12(r3) /* Get IBAT 1 low */
319 lwz r8,16(r3) /* Get IBAT 2 high */
320 lwz r9,20(r3) /* Get IBAT 2 low */
321 lwz r10,24(r3) /* Get IBAT 3 high */
322 lwz r11,28(r3) /* Get IBAT 3 low */
323
324 sync /* Common decency and the state law require that you wash your hands */
325 mtibatu 0,r4 /* Load IBAT 0 high */
326 mtibatl 0,r5 /* Load IBAT 0 low */
327 mtibatu 1,r6 /* Load IBAT 1 high */
328 mtibatl 1,r7 /* Load IBAT 1 low */
329 mtibatu 2,r8 /* Load IBAT 2 high */
330 mtibatl 2,r9 /* Load IBAT 2 low */
331 mtibatu 3,r10 /* Load IBAT 3 high */
332 mtibatl 3,r11 /* Load IBAT 3 low */
333 sync /* Make sure it's done */
334 isync /* Toss out anything new */
335
336 blr /* Leave... */
337
338
339 /*
340 * This is the glue to call the CutTrace firmware call
341 * dbgTrace(id, p1, p2, p3, p4)
342 */
343
344 .align 5
345 .globl EXT(dbgTrace)
346
347 LEXT(dbgTrace)
348
349 mr r2,r3
350 mr r3,r4
351 lis r0,HIGH_ADDR(CutTrace) /* Top half of CreateFakeIO firmware call number */
352 mr r4,r5
353 mr r5,r6
354 ori r0,r0,LOW_ADDR(CutTrace) /* Bottom half */
355 mr r6,r7
356 sc /* Do it to it */
357 blr /* Bye bye, Birdie... */
358
359 /*
360 * This is the glue to create a fake I/O interruption
361 */
362
363 .align 5
364 .globl EXT(CreateFakeIO)
365
366 LEXT(CreateFakeIO)
367
368 lis r0,HIGH_ADDR(CreateFakeIOCall) /* Top half of CreateFakeIO firmware call number */
369 ori r0,r0,LOW_ADDR(CreateFakeIOCall) /* Bottom half */
370 sc /* Do it to it */
371 blr /* Bye bye, Birdie... */
372
373 /*
374 * This is the glue to create a fake Dec interruption
375 */
376
377 .align 5
378 .globl EXT(CreateFakeDEC)
379
380 LEXT(CreateFakeDEC)
381
382 #if 0
383 mflr r4 ; (TEST/DEBUG)
384 bl EXT(ml_sense_nmi) ; (TEST/DEBUG)
385 mtlr r4 ; (TEST/DEBUG)
386 #endif
387
388 lis r0,HIGH_ADDR(CreateFakeDECCall) /* Top half of CreateFakeDEC firmware call number */
389 ori r0,r0,LOW_ADDR(CreateFakeDECCall) /* Bottom half */
390 sc /* Do it to it */
391 blr /* Bye bye, Birdie... */
392
393
394 /*
395 * This is the glue to create a shutdown context
396 */
397
398 .align 5
399 .globl EXT(CreateShutdownCTX)
400
401 LEXT(CreateShutdownCTX)
402
403 lis r0,HIGH_ADDR(CreateShutdownCTXCall) /* Top half of CreateFakeIO firmware call number */
404 ori r0,r0,LOW_ADDR(CreateShutdownCTXCall) /* Bottom half */
405 sc /* Do it to it */
406 blr /* Bye bye, Birdie... */
407
408 /*
409 * This is the glue to choke system
410 */
411
412 .align 5
413 .globl EXT(ChokeSys)
414
415 LEXT(ChokeSys)
416
417 lis r0,HIGH_ADDR(Choke) /* Top half of Choke firmware call number */
418 ori r0,r0,LOW_ADDR(Choke) /* Bottom half */
419 sc /* Do it to it */
420 blr /* Bye bye, Birdie... */
421
422 /*
423 * Used to initialize the SCC for debugging output
424 */
425
426
427 .align 5
428 .globl EXT(fwSCCinit)
429
430 LEXT(fwSCCinit)
431
432 mfmsr r8 /* Save the MSR */
433 mr. r3,r3 /* See if printer or modem */
434 rlwinm r12,r8,0,28,25 /* Turn off translation */
435 lis r10,0xF301 /* Set the top part */
436 rlwinm r12,r12,0,17,15 /* Turn off interruptions */
437 #if 0
438 mtmsr r12 /* Smash the MSR */
439 isync /* Make it clean */
440 #endif
441
442 ori r10,r10,0x2000 /* Assume the printer (this is the normal one) */
443 beq+ fwSCCprnt /* It sure are... */
444 ori r10,r10,0x0002 /* Move it over to the modem port */
445
446 fwSCCprnt: dcbf 0,r10 /* Insure it is out */
447 sync
448 eieio
449 dcbi 0,r10 /* Toss it */
450 sync
451
452
453 li r7,0x09 /* Set the register */
454 stb r7,0(r10) /* Set the register */
455 dcbf 0,r10 /* Force it out */
456 sync /* Make sure it's out there */
457 dcbi 0,r10
458 eieio
459
460 li r7,0x80 /* Reset channel A */
461 stb r7,0(r10) /* Set the register */
462 dcbf 0,r10 /* Force it out */
463 sync /* Make sure it's out there */
464 dcbi 0,r10
465 eieio
466
467 li r7,0x04 /* Set the register */
468 stb r7,0(r10) /* Set the register */
469 dcbf 0,r10 /* Force it out */
470 sync /* Make sure it's out there */
471 dcbi 0,r10
472 eieio
473
474 li r7,0x44 /* x16 clock, 1 stop bit */
475 stb r7,0(r10) /* Set the register */
476 dcbf 0,r10 /* Force it out */
477 sync /* Make sure it's out there */
478 dcbi 0,r10
479 eieio
480
481 li r7,0x03 /* Set the register */
482 stb r7,0(r10) /* Set the register */
483 dcbf 0,r10 /* Force it out */
484 sync /* Make sure it's out there */
485 dcbi 0,r10
486 eieio
487
488 li r7,0xC0 /* 8 bits per char */
489 stb r7,0(r10) /* Set the register */
490 dcbf 0,r10 /* Force it out */
491 sync /* Make sure it's out there */
492 dcbi 0,r10
493 eieio
494
495 li r7,0x05 /* Set the register */
496 stb r7,0(r10) /* Set the register */
497 dcbf 0,r10 /* Force it out */
498 sync /* Make sure it's out there */
499 dcbi 0,r10
500 eieio
501
502 li r7,0xE2 /* DTR mode, 8bit/char */
503 stb r7,0(r10) /* Set the register */
504 dcbf 0,r10 /* Force it out */
505 sync /* Make sure it's out there */
506 dcbi 0,r10
507 eieio
508
509 li r7,0x02 /* Set the register */
510 stb r7,0(r10) /* Set the register */
511 dcbf 0,r10 /* Force it out */
512 sync /* Make sure it's out there */
513 dcbi 0,r10
514 eieio
515
516 li r7,0x00 /* Vector 0 */
517 stb r7,0(r10) /* Set the register */
518 dcbf 0,r10 /* Force it out */
519 sync /* Make sure it's out there */
520 dcbi 0,r10
521 eieio
522
523 li r7,0x0A /* Set the register */
524 stb r7,0(r10) /* Set the register */
525 dcbf 0,r10 /* Force it out */
526 sync /* Make sure it's out there */
527 dcbi 0,r10
528 eieio
529
530 li r7,0x00 /* Clear misc controls */
531 stb r7,0(r10) /* Set the register */
532 dcbf 0,r10 /* Force it out */
533 sync /* Make sure it's out there */
534 dcbi 0,r10
535 eieio
536
537 li r7,0x0B /* Set the register */
538 stb r7,0(r10) /* Set the register */
539 dcbf 0,r10 /* Force it out */
540 sync /* Make sure it's out there */
541 dcbi 0,r10
542 eieio
543
544 li r7,0x50 /* B/R gen T/R */
545 stb r7,0(r10) /* Set the register */
546 dcbf 0,r10 /* Force it out */
547 sync /* Make sure it's out there */
548 dcbi 0,r10
549 eieio
550
551 li r7,0x0C /* Set the register */
552 stb r7,0(r10) /* Set the register */
553 dcbf 0,r10 /* Force it out */
554 sync /* Make sure it's out there */
555 dcbi 0,r10
556 eieio
557
558 li r7,0x0A /* 9600 baud low */
559 stb r7,0(r10) /* Set the register */
560 dcbf 0,r10 /* Force it out */
561 sync /* Make sure it's out there */
562 dcbi 0,r10
563 eieio
564
565 li r7,0x0D /* Set the register */
566 stb r7,0(r10) /* Set the register */
567 dcbf 0,r10 /* Force it out */
568 sync /* Make sure it's out there */
569 dcbi 0,r10
570 eieio
571
572 li r7,0x00 /* 9600 baud high */
573 stb r7,0(r10) /* Set the register */
574 dcbf 0,r10 /* Force it out */
575 sync /* Make sure it's out there */
576 dcbi 0,r10
577 eieio
578
579 li r7,0x03 /* Set the register */
580 stb r7,0(r10) /* Set the register */
581 dcbf 0,r10 /* Force it out */
582 sync /* Make sure it's out there */
583 dcbi 0,r10
584 eieio
585
586 li r7,0xC1 /* 8 bits/char, Rx enable */
587 stb r7,0(r10) /* Set the register */
588 dcbf 0,r10 /* Force it out */
589 sync /* Make sure it's out there */
590 dcbi 0,r10
591 eieio
592
593 li r7,0x05 /* Set the register */
594 stb r7,0(r10) /* Set the register */
595 dcbf 0,r10 /* Force it out */
596 sync /* Make sure it's out there */
597 dcbi 0,r10
598 eieio
599
600 li r7,0xEA /* 8 bits/char, Tx enable */
601 stb r7,0(r10) /* Set the register */
602 dcbf 0,r10 /* Force it out */
603 sync /* Make sure it's out there */
604 dcbi 0,r10
605 eieio
606
607 li r7,0x0E /* Set the register */
608 stb r7,0(r10) /* Set the register */
609 dcbf 0,r10 /* Force it out */
610 sync /* Make sure it's out there */
611 dcbi 0,r10
612 eieio
613
614 li r7,0x01 /* BR rate gen enable */
615 stb r7,0(r10) /* Set the register */
616 dcbf 0,r10 /* Force it out */
617 sync /* Make sure it's out there */
618 dcbi 0,r10
619 eieio
620
621 li r7,0x0F /* Set the register */
622 stb r7,0(r10) /* Set the register */
623 dcbf 0,r10 /* Force it out */
624 sync /* Make sure it's out there */
625 dcbi 0,r10
626 eieio
627
628 li r7,0x00 /* ints off */
629 stb r7,0(r10) /* Set the register */
630 dcbf 0,r10 /* Force it out */
631 sync /* Make sure it's out there */
632 dcbi 0,r10
633 eieio
634
635 li r7,0x10 /* Reset ext/stat ints */
636 stb r7,0(r10) /* Set the register */
637 dcbf 0,r10 /* Force it out */
638 sync /* Make sure it's out there */
639 dcbi 0,r10
640 eieio
641
642 li r7,0x10 /* Reset ext/stat ints */
643 stb r7,0(r10) /* Set the register */
644 dcbf 0,r10 /* Force it out */
645 sync /* Make sure it's out there */
646 dcbi 0,r10
647 eieio
648
649 li r7,0x01 /* Set the register */
650 stb r7,0(r10) /* Set the register */
651 dcbf 0,r10 /* Force it out */
652 sync /* Make sure it's out there */
653 dcbi 0,r10
654 eieio
655
656 li r7,0x10 /* int on Rx, no Tx int enable */
657 stb r7,0(r10) /* Set the register */
658 dcbf 0,r10 /* Force it out */
659 sync /* Make sure it's out there */
660 dcbi 0,r10
661 eieio
662
663 li r7,0x09 /* Set the register */
664 stb r7,0(r10) /* Set the register */
665 dcbf 0,r10 /* Force it out */
666 sync /* Make sure it's out there */
667 dcbi 0,r10
668 eieio
669
670 li r7,0x0A /* int on Rx, Tx int enable */
671 stb r7,0(r10) /* Set the register */
672 dcbf 0,r10 /* Force it out */
673 sync /* Master enable, no vector */
674 dcbi 0,r10
675 eieio
676
677 li r7,0x09 /* Set the register */
678 stb r7,0(r10) /* Set the register */
679 dcbf 0,r10 /* Force it out */
680 sync /* Make sure it's out there */
681 dcbi 0,r10
682 eieio
683
684 li r7,0x02 /* No vector */
685 stb r7,0(r10) /* Set the register */
686 dcbf 0,r10 /* Force it out */
687 sync /* Master enable, no vector */
688 dcbi 0,r10
689 eieio
690
691 lbz r7,0(r10) /* Clear interrupts */
692 sync /* Master enable, no vector */
693 dcbi 0,r10
694 eieio
695
696 wSCCrdy: eieio /* Barricade it */
697 lbz r7,0(r10) /* Get current status */
698 dcbi 0,r10
699 sync
700 andi. r7,r7,0x04 /* Is transmitter empty? */
701 beq wSCCrdy /* Nope... */
702
703 eieio
704
705 #if 0
706 mtmsr r8 /* Restore 'rupts and TR */
707 isync
708 #endif
709 blr /* Leave... */
710
711 /*
712 * This routine is used to write debug output to either the modem or printer port.
713 * parm 1 is printer (0) or modem (1); parm 2 is ID (printed directly); parm 3 converted to hex
714 */
715
716 .align 5
717 .globl EXT(dbgDisp)
718
719 LEXT(dbgDisp)
720
721 mr r12,r0 /* Keep R0 pristene */
722 lis r0,HIGH_ADDR(dbgDispCall) /* Top half of dbgDispCall firmware call number */
723 ori r0,r0,LOW_ADDR(dbgDispCall) /* Bottom half */
724
725 sc /* Go display the stuff */
726
727 mr r0,r12 /* Restore R0 */
728 blr /* Return... */
729
730 /* Here's the low-level part of dbgDisp */
731
732 .align 5
733 .globl EXT(dbgDispLL)
734
735 LEXT(dbgDispLL)
736
737 dbgDispInt: mfmsr r8 /* Save the MSR */
738
739 #if 0
740 lis r10,0xF301 /* (TEST/DEBUG) */
741 ori r10,r10,0x2002 /* (TEST/DEBUG) */
742 dcbf 0,r10 /* (TEST/DEBUG) */
743 sync /* (TEST/DEBUG) */
744 dcbi 0,r10 /* (TEST/DEBUG) */
745 eieio /* (TEST/DEBUG) */
746 li r7,0x35 /* (TEST/DEBUG) */
747 stb r7,4(r10) /* (TEST/DEBUG) */
748
749 lis r7,10 /* (TEST/DEBUG) */
750 spw6: addi r7,r7,-1 /* (TEST/DEBUG) */
751 mr. r7,r7 /* (TEST/DEBUG) */
752 bne- spw6 /* (TEST/DEBUG) */
753 dcbf 0,r10 /* (TEST/DEBUG) */
754 sync /* (TEST/DEBUG) */
755 dcbi 0,r10 /* (TEST/DEBUG) */
756 eieio /* (TEST/DEBUG) */
757 #endif
758
759 rlwinm r12,r8,0,28,25 /* Turn off translation */
760 rlwinm r12,r12,0,17,15 /* Turn off interruptions */
761
762 mflr r11 /* Save the link register */
763
764 #if 0
765 mr r7,r12 /* (TEST/DEBUG) */
766 bl dumpr7 /* (TEST/DEBUG) */
767 #endif
768
769 mr. r3,r3 /* See if printer or modem */
770 lis r10,0xF301 /* Set the top part */
771 mr r3,r4 /* Copy the ID parameter */
772
773 #if 0
774 mr r9,r12 /* (TEST/DEBUG) */
775
776 mtmsr r12 /* (TEST/DEBUG) */
777 isync /* (TEST/DEBUG) */
778
779 #if 0
780 mtmsr r8 /* (TEST/DEBUG) */
781 isync /* (TEST/DEBUG) */
782 #endif
783
784 lis r12,0xF301 /* (TEST/DEBUG) */
785 ori r12,r12,0x2002 /* (TEST/DEBUG) */
786 #if 1
787 dcbf 0,r12 /* (TEST/DEBUG) */
788 sync /* (TEST/DEBUG) */
789 dcbi 0,r12 /* (TEST/DEBUG) */
790 #endif
791
792 xqrw1: eieio /* (TEST/DEBUG) */
793 lbz r7,0(r12) /* (TEST/DEBUG) */
794 dcbi 0,r12 /* (TEST/DEBUG) */
795 sync /* (TEST/DEBUG) */
796 andi. r7,r7,0x04 /* (TEST/DEBUG) */
797 beq xqrw1 /* (TEST/DEBUG) */
798
799 eieio /* (TEST/DEBUG) */
800 li r7,0x36 /* (TEST/DEBUG) */
801 stb r7,4(r12) /* (TEST/DEBUG) */
802 eieio
803 dcbf 0,r12 /* (TEST/DEBUG) */
804 sync /* (TEST/DEBUG) */
805 dcbi 0,r12 /* (TEST/DEBUG) */
806 eieio /* (TEST/DEBUG) */
807
808
809 lis r7,10 /* (TEST/DEBUG) */
810 spw7: addi r7,r7,-1 /* (TEST/DEBUG) */
811 mr. r7,r7 /* (TEST/DEBUG) */
812 bne- spw7 /* (TEST/DEBUG) */
813 dcbf 0,r12 /* (TEST/DEBUG) */
814 sync /* (TEST/DEBUG) */
815 dcbi 0,r12 /* (TEST/DEBUG) */
816 eieio /* (TEST/DEBUG) */
817 mr r12,r9 /* (TEST/DEBUG) */
818 #endif
819
820 mtmsr r12 /* Smash the MSR */
821 isync /* Make it clean */
822
823
824 #if SIMPLESCC && !NOTQUITEASSIMPLE
825 ori r10,r10,0x3010 /* Assume the printer (this is the normal one) */
826 #else
827 ori r10,r10,0x2000 /* Assume the printer (this is the normal one) */
828 #endif
829 beq+ dbgDprintr /* It sure are... */
830 #if SIMPLESCC && !NOTQUITEASSIMPLE
831 ori r10,r10,0x0020 /* Move it over to the modem port */
832 #else
833 ori r10,r10,0x0002 /* Move it over to the modem port */
834
835 #if !NOTQUITEASSIMPLE
836 lis r7,0xF300 /* Address of SCC rounded to 128k */
837 ori r7,r7,0x0032 /* Make it cache inhibited */
838 mtdbatl 3,r7 /* Load DBAT 3 low */
839 lis r7,0xF300 /* Address of SCC rounded to 128k */
840 ori r7,r7,0x0002 /* Make it supervisor only */
841 mtdbatu 3,r7 /* Load DBAT 3 high */
842 ori r12,r12,0x0010 /* Turn on DR */
843 mtmsr r12 /* Smash the MSR */
844 isync /* Make it clean */
845
846 #endif
847 #endif
848
849 dbgDprintr: sync
850 #if 0
851 mr r7,r10 /* (TEST/DEBUG) */
852 bl dumpr7 /* (TEST/DEBUG) */
853 #endif
854
855 dcbi 0,r10 /* Toss it */
856 eieio
857
858 #if 0
859 lis r12,0xF301 /* (TEST/DEBUG) */
860 ori r12,r12,0x2002 /* (TEST/DEBUG) */
861 dcbf 0,r12 /* (TEST/DEBUG) */
862 sync /* (TEST/DEBUG) */
863 dcbi 0,r12 /* (TEST/DEBUG) */
864 eieio /* (TEST/DEBUG) */
865 li r7,0x37 /* (TEST/DEBUG) */
866 stb r7,4(r12) /* (TEST/DEBUG) */
867
868 lis r7,12 /* (TEST/DEBUG) */
869 spw8: addi r7,r7,-1 /* (TEST/DEBUG) */
870 mr. r7,r7 /* (TEST/DEBUG) */
871 bne- spw8 /* (TEST/DEBUG) */
872 dcbf 0,r12 /* (TEST/DEBUG) */
873 sync /* (TEST/DEBUG) */
874 dcbi 0,r12 /* (TEST/DEBUG) */
875 eieio /* (TEST/DEBUG) */
876 #endif
877
878
879 /* Print the ID parameter */
880
881 lis r12,HIGH_ADDR(fwdisplock) /* Get the display locker outer */
882 ori r12,r12,LOW_ADDR(fwdisplock) /* Last part */
883
884 lwarx r7,0,r12 ; ?
885
886 ddwait0: lwarx r7,0,r12 /* Get the lock */
887 mr. r7,r7 /* Is it locked? */
888 bne- ddwait0 /* Yup... */
889 stwcx. r12,0,r12 /* Try to get it */
890 bne- ddwait0 /* Nope, start all over... */
891
892 #if 0
893 dcbf 0,r10 /* (TEST/DEBUG) */
894 sync /* (TEST/DEBUG) */
895 dcbi 0,r10 /* (TEST/DEBUG) */
896 eieio /* (TEST/DEBUG) */
897 li r7,0x38 /* (TEST/DEBUG) */
898 stb r7,6(r10) /* (TEST/DEBUG) */
899
900 lis r7,10 /* (TEST/DEBUG) */
901 spwa: addi r7,r7,-1 /* (TEST/DEBUG) */
902 mr. r7,r7 /* (TEST/DEBUG) */
903 bne- spwa /* (TEST/DEBUG) */
904 dcbf 0,r10 /* (TEST/DEBUG) */
905 sync /* (TEST/DEBUG) */
906 dcbi 0,r10 /* (TEST/DEBUG) */
907 eieio /* (TEST/DEBUG) */
908 #endif
909
910 rlwinm r3,r3,8,0,31 /* Get the first character */
911 bl dbgDchar /* Print it */
912 rlwinm r3,r3,8,0,31 /* Get the second character */
913 bl dbgDchar /* Print it */
914 rlwinm r3,r3,8,0,31 /* Get the third character */
915 bl dbgDchar /* Print it */
916 rlwinm r3,r3,8,0,31 /* Get the fourth character */
917 bl dbgDchar /* Print it */
918
919 li r3,0x20 /* Get a space for a separator */
920 bl dbgDchar /* Print it */
921 bl dbg4byte /* Print register 5 in hex */
922
923 li r3,0x0A /* Linefeed */
924 bl dbgDchar /* Send it */
925 li r3,0x0D /* Carriage return */
926 bl dbgDchar /* Send it */
927
928 mtlr r11 /* Get back the return */
929 #if !SIMPLESCC && !NOTQUITEASSIMPLE
930 li r7,0 /* Get a zero */
931 mtdbatu 3,r7 /* Invalidate DBAT 3 upper */
932 mtdbatl 3,r7 /* Invalidate DBAT 3 lower */
933 #endif
934 lis r12,HIGH_ADDR(fwdisplock) /* Get the display locker outer */
935 li r7,0 /* Get a zero */
936 ori r12,r12,LOW_ADDR(fwdisplock) /* Last part */
937 dcbi 0,r10 /* ? */
938 stw r7,0(r12) /* Release the display lock */
939 mtmsr r8 /* Restore the MSR */
940 isync /* Wait for it */
941 blr /* Leave... */
942
943
944 dbg4byte: mflr r12 /* Save the return */
945
946 lis r4,HIGH_ADDR(hexTab) /* Point to the top of table */
947 li r6,8 /* Set number of hex digits to dump */
948 ori r4,r4,LOW_ADDR(hexTab) /* Point to the bottom of table */
949
950 dbgDnext: rlwinm r5,r5,4,0,31 /* Rotate a nybble */
951 subi r6,r6,1 /* Back down the count */
952 rlwinm r3,r5,0,28,31 /* Isolate the last nybble */
953 lbzx r3,r4,r3 /* Convert to ascii */
954 bl dbgDchar /* Print it */
955 mr. r6,r6 /* Any more? */
956 bne+ dbgDnext /* Convert 'em all... */
957
958 li r3,0x20 /* Space */
959 bl dbgDchar /* Send it */
960 mtlr r12 /* Restore LR */
961 blr /* Return... */
962
963 /* Write to whichever serial port. Try to leave it clean, but not too hard (this is a hack) */
964
965 dbgDchar:
966 #if SIMPLESCC && !NOTQUITEASSIMPLE
967 stb r3,0(r10) /* ? */
968 dcbf 0,r10 /* Force it out */
969 sync /* Make sure it's out there */
970
971 lis r7,3 /* Get enough for about 1ms */
972
973 dbgDchar0: addi r7,r7,-1 /* Count down */
974 mr. r7,r7 /* Waited long enough? */
975 bgt+ dbgDchar0 /* Nope... */
976 #endif
977 #if NOTQUITEASSIMPLE
978 #if 0
979 li r7,0x01 /* ? */
980 stb r7,0(r10) /* ? */
981 dcbf 0,r10 /* Force it out */
982 sync /* Make sure it's out there */
983 dcbi 0,r10
984 eieio
985
986 lbz r7,0(r10) /* ? */
987 dcbi 0,r10 /* Force it out */
988 sync /* kill it off */
989 eieio
990
991 li r7,0x00 /* ? */
992 stb r7,0(r10) /* ? */
993 dcbf 0,r10 /* Force it out */
994 sync /* Make sure it's out there */
995 dcbi 0,r10
996 eieio
997
998 lbz r7,0(r10) /* ? */
999 dcbi 0,r10 /* Force it out */
1000 sync /* kill it off */
1001 eieio
1002 #endif
1003
1004 qrw1: eieio /* Barricade it */
1005 lbz r7,0(r10) /* ? */
1006 dcbi 0,r10
1007 sync
1008 andi. r7,r7,0x04 /* ? */
1009 beq qrw1 /* Nope... */
1010
1011 eieio
1012
1013 stb r3,4(r10) /* ? */
1014 dcbf 0,r10 /* Force it out */
1015 sync /* Make sure it's out there */
1016 dcbi 0,r10
1017 eieio
1018
1019 qrw2: eieio /* Barricade it */
1020 lbz r7,0(r10) /* ? */
1021 dcbi 0,r10
1022 sync
1023 andi. r7,r7,0x04 /* ? */
1024 beq qrw2 /* Nope... */
1025
1026 #if 0
1027 eieio
1028 li r7,0x10 /* ? */
1029 stb r7,0(r10) /* ? */
1030 dcbf 0,r10 /* Force it out */
1031 sync /* Make sure it's out there */
1032 dcbi 0,r10
1033 eieio
1034
1035 lbz r7,0(r10) /* ? */
1036 dcbi 0,r10 /* Force it out */
1037 sync /* kill it off */
1038 eieio
1039 #endif
1040
1041 lis r7,0x0080 /* ? */
1042 lis r9,0xF300 /* ? */
1043 ori r7,r7,0x010F /* ? */
1044 stw r7,0x28(r9) /* ? */
1045 dcbf 0,r10 /* Force it out */
1046 sync /* Make sure it's out there */
1047 dcbi 0,r10
1048 eieio
1049
1050 #endif
1051 #if !SIMPLESCC && !NOTQUITEASSIMPLE
1052 rlwinm r9,r10,0,0,29 /* Get channel a */
1053 eieio /* Barricade it */
1054
1055 li r7,0x03 /* ? */
1056 stb r7,0(r9) /* ? */
1057 eieio /* Barricade it */
1058
1059 lbz r7,0(r9) /* ? */
1060
1061 eieio /* Barricade it */
1062 lbz r7,0(r9) /* ? */
1063
1064 dchrw1: eieio /* Barricade it */
1065 lbz r7,0(r10) /* ? */
1066 andi. r7,r7,0x04 /* ? */
1067 beq dchrw1 /* Nope... */
1068
1069 stb r3,4(r10) /* ? */
1070 sync /* Make sure it's there */
1071 eieio /* Don't get confused */
1072
1073 dchrw2: eieio /* Barricade it */
1074 lbz r7,0(r10) /* ? */
1075 andi. r7,r7,0x04 /* ? */
1076 beq dchrw2 /* Nope... */
1077
1078 eieio /* Avoid confusion */
1079 lbz r7,0(r10) /* ? */
1080 andi. r7,r7,0x40 /* ? */
1081 beq+ nounder /* Nope... */
1082
1083 eieio /* Avoid confusion */
1084 li r7,0xC0 /* ? */
1085 stb r7,0(r10) /* ? */
1086
1087 nounder: eieio /* Avoid confusion */
1088 li r7,0x10 /* ? */
1089 stb r7,0(r10) /* ? */
1090
1091 eieio /* Avoid confusion */
1092 li r7,0x38 /* ? */
1093 stb r7,0(r9) /* ? */
1094
1095 eieio /* Avoid confusion */
1096 li r7,0x30 /* ? */
1097 stb r7,0(r10) /* ? */
1098
1099 eieio /* Avoid confusion */
1100 li r7,0x20 /* ? */
1101 stb r7,0(r10) /* ? */
1102 eieio /* Avoid confusion */
1103 sync
1104
1105 #endif
1106 blr /* Return */
1107
1108 .globl hexTab
1109
1110 hexTab: STRINGD "0123456789ABCDEF" /* Convert hex numbers to printable hex */
1111
1112
1113 /*
1114 * Dumps all the registers in the savearea in R13
1115 */
1116
1117
1118 .align 5
1119 .globl EXT(dbgRegsLL)
1120
1121 LEXT(dbgRegsLL)
1122
1123 b EXT(FCReturn) ; Bye dudes...
1124 #if 0
1125 li r3,0 /* ? */
1126 bl dbgRegsCm /* Join on up... */
1127 b EXT(FCReturn) ; Bye dudes...
1128
1129
1130 .align 5
1131 .globl EXT(dbgRegs)
1132
1133 LEXT(dbgRegs)
1134
1135 dbgRegsCm: mfmsr r8 /* Save the MSR */
1136 mr. r3,r3 /* ? */
1137 rlwinm r12,r8,0,28,25 /* Turn off translation */
1138 lis r10,0xF301 /* Set the top part */
1139 rlwinm r12,r12,0,17,15 /* Turn off interruptions */
1140 mtmsr r12 /* Smash the MSR */
1141 isync /* Make it clean */
1142 #if SIMPLESCC && !NOTQUITEASSIMPLE
1143 ori r10,r10,0x3010 /* ? */
1144 #else
1145 ori r10,r10,0x2000 /* ? */
1146 #endif
1147 mflr r11 /* Save the link register */
1148 beq+ dbgDprints /* It sure are... */
1149 #if SIMPLESCC && !NOTQUITEASSIMPLE
1150 ori r10,r10,0x0020 /* ? */
1151 #else
1152 ori r10,r10,0x0002 /* ? */
1153
1154 dcbf 0,r10 /* Insure it is out */
1155 sync
1156 dcbi 0,r10 /* Toss it */
1157 #if !NOTQUITEASSIMPLE
1158 lis r7,0xF300 /* ? */
1159 ori r7,r7,0x0032 /* ? */
1160 mtdbatl 3,r7 /* ? */
1161 lis r7,0xF300 /* ? */
1162 ori r7,r7,0x0002 /* ? */
1163 mtdbatu 3,r7 /* ? */
1164 ori r12,r12,0x0010 /* ? */
1165 mtmsr r12 /* ? */
1166 isync /* ? */
1167 #endif
1168 #endif
1169
1170 dbgDprints:
1171 lis r3,HIGH_ADDR(fwdisplock) /* Get the display locker outer */
1172 ori r3,r3,LOW_ADDR(fwdisplock) /* Last part */
1173
1174 lwarx r5,0,r3 ; ?
1175 ddwait1: lwarx r5,0,r3 /* Get the lock */
1176 mr. r5,r5 /* Is it locked? */
1177 bne- ddwait1 /* Yup... */
1178 stwcx. r3,0,r3 /* Try to get it */
1179 bne- ddwait1 /* Nope, start all over... */
1180
1181 li r3,0x52 /* Print eyecatcher */
1182 bl dbgDchar /* Send it */
1183 li r3,0x65 /* Print eyecatcher */
1184 bl dbgDchar /* Send it */
1185 li r3,0x67 /* Print eyecatcher */
1186 bl dbgDchar /* Send it */
1187 li r3,0x73 /* Print eyecatcher */
1188 bl dbgDchar /* Send it */
1189 li r3,0x20 /* Print eyecatcher */
1190 bl dbgDchar /* Send it */
1191
1192 lwz r5,saver0(r13) /* Do register */
1193 bl dbg4byte /* Print */
1194 lwz r5,saver1(r13) /* Do register */
1195 bl dbg4byte /* Print */
1196 lwz r5,saver2(r13) /* Do register */
1197 bl dbg4byte /* Print */
1198 lwz r5,saver3(r13) /* Do register */
1199 bl dbg4byte /* Print */
1200 li r3,0x0A /* Linefeed */
1201 bl dbgDchar /* Send it */
1202 li r3,0x0D /* Carriage return */
1203 bl dbgDchar /* Send it */
1204
1205 li r3,0x20 /* Print eyecatcher */
1206 bl dbgDchar /* Send it */
1207 li r3,0x20 /* Print eyecatcher */
1208 bl dbgDchar /* Send it */
1209 li r3,0x20 /* Print eyecatcher */
1210 bl dbgDchar /* Send it */
1211 li r3,0x20 /* Print eyecatcher */
1212 bl dbgDchar /* Send it */
1213 li r3,0x20 /* Print eyecatcher */
1214 bl dbgDchar /* Send it */
1215 lwz r5,saver4(r13) /* Do register */
1216 bl dbg4byte /* Print */
1217 lwz r5,saver5(r13) /* Do register */
1218 bl dbg4byte /* Print */
1219 lwz r5,saver6(r13) /* Do register */
1220 bl dbg4byte /* Print */
1221 lwz r5,saver7(r13) /* Do register */
1222 bl dbg4byte /* Print */
1223 li r3,0x0A /* Linefeed */
1224 bl dbgDchar /* Send it */
1225 li r3,0x0D /* Carriage return */
1226 bl dbgDchar /* Send it */
1227
1228 li r3,0x20 /* Print eyecatcher */
1229 bl dbgDchar /* Send it */
1230 li r3,0x20 /* Print eyecatcher */
1231 bl dbgDchar /* Send it */
1232 li r3,0x20 /* Print eyecatcher */
1233 bl dbgDchar /* Send it */
1234 li r3,0x20 /* Print eyecatcher */
1235 bl dbgDchar /* Send it */
1236 li r3,0x20 /* Print eyecatcher */
1237 bl dbgDchar /* Send it */
1238 lwz r5,saver8(r13) /* Do register */
1239 bl dbg4byte /* Print */
1240 lwz r5,saver9(r13) /* Do register */
1241 bl dbg4byte /* Print */
1242 lwz r5,saver10(r13) /* Do register */
1243 bl dbg4byte /* Print */
1244 lwz r5,saver11(r13) /* Do register */
1245 bl dbg4byte /* Print */
1246 li r3,0x0A /* Linefeed */
1247 bl dbgDchar /* Send it */
1248 li r3,0x0D /* Carriage return */
1249 bl dbgDchar /* Send it */
1250
1251 li r3,0x20 /* Print eyecatcher */
1252 bl dbgDchar /* Send it */
1253 li r3,0x20 /* Print eyecatcher */
1254 bl dbgDchar /* Send it */
1255 li r3,0x20 /* Print eyecatcher */
1256 bl dbgDchar /* Send it */
1257 li r3,0x20 /* Print eyecatcher */
1258 bl dbgDchar /* Send it */
1259 li r3,0x20 /* Print eyecatcher */
1260 bl dbgDchar /* Send it */
1261 lwz r5,saver12(r13) /* Do register */
1262 bl dbg4byte /* Print */
1263 lwz r5,saver13(r13) /* Do register */
1264 bl dbg4byte /* Print */
1265 lwz r5,saver14(r13) /* Do register */
1266 bl dbg4byte /* Print */
1267 lwz r5,saver15(r13) /* Do register */
1268 bl dbg4byte /* Print */
1269 li r3,0x0A /* Linefeed */
1270 bl dbgDchar /* Send it */
1271 li r3,0x0D /* Carriage return */
1272 bl dbgDchar /* Send it */
1273
1274 li r3,0x20 /* Print eyecatcher */
1275 bl dbgDchar /* Send it */
1276 li r3,0x20 /* Print eyecatcher */
1277 bl dbgDchar /* Send it */
1278 li r3,0x20 /* Print eyecatcher */
1279 bl dbgDchar /* Send it */
1280 li r3,0x20 /* Print eyecatcher */
1281 bl dbgDchar /* Send it */
1282 li r3,0x20 /* Print eyecatcher */
1283 bl dbgDchar /* Send it */
1284 lwz r5,saver16(r13) /* Do register */
1285 bl dbg4byte /* Print */
1286 lwz r5,saver17(r13) /* Do register */
1287 bl dbg4byte /* Print */
1288 lwz r5,saver18(r13) /* Do register */
1289 bl dbg4byte /* Print */
1290 lwz r5,saver19(r13) /* Do register */
1291 bl dbg4byte /* Print */
1292 li r3,0x0A /* Linefeed */
1293 bl dbgDchar /* Send it */
1294 li r3,0x0D /* Carriage return */
1295 bl dbgDchar /* Send it */
1296
1297 li r3,0x20 /* Print eyecatcher */
1298 bl dbgDchar /* Send it */
1299 li r3,0x20 /* Print eyecatcher */
1300 bl dbgDchar /* Send it */
1301 li r3,0x20 /* Print eyecatcher */
1302 bl dbgDchar /* Send it */
1303 li r3,0x20 /* Print eyecatcher */
1304 bl dbgDchar /* Send it */
1305 li r3,0x20 /* Print eyecatcher */
1306 bl dbgDchar /* Send it */
1307 lwz r5,saver20(r13) /* Do register */
1308 bl dbg4byte /* Print */
1309 lwz r5,saver21(r13) /* Do register */
1310 bl dbg4byte /* Print */
1311 lwz r5,saver22(r13) /* Do register */
1312 bl dbg4byte /* Print */
1313 lwz r5,saver23(r13) /* Do register */
1314 bl dbg4byte /* Print */
1315 li r3,0x0A /* Linefeed */
1316 bl dbgDchar /* Send it */
1317 li r3,0x0D /* Carriage return */
1318 bl dbgDchar /* Send it */
1319
1320 li r3,0x20 /* Print eyecatcher */
1321 bl dbgDchar /* Send it */
1322 li r3,0x20 /* Print eyecatcher */
1323 bl dbgDchar /* Send it */
1324 li r3,0x20 /* Print eyecatcher */
1325 bl dbgDchar /* Send it */
1326 li r3,0x20 /* Print eyecatcher */
1327 bl dbgDchar /* Send it */
1328 li r3,0x20 /* Print eyecatcher */
1329 bl dbgDchar /* Send it */
1330 lwz r5,saver24(r13) /* Do register */
1331 bl dbg4byte /* Print */
1332 lwz r5,saver25(r13) /* Do register */
1333 bl dbg4byte /* Print */
1334 lwz r5,saver26(r13) /* Do register */
1335 bl dbg4byte /* Print */
1336 lwz r5,saver27(r13) /* Do register */
1337 bl dbg4byte /* Print */
1338 li r3,0x0A /* Linefeed */
1339 bl dbgDchar /* Send it */
1340 li r3,0x0D /* Carriage return */
1341 bl dbgDchar /* Send it */
1342
1343 li r3,0x20 /* Print eyecatcher */
1344 bl dbgDchar /* Send it */
1345 li r3,0x20 /* Print eyecatcher */
1346 bl dbgDchar /* Send it */
1347 li r3,0x20 /* Print eyecatcher */
1348 bl dbgDchar /* Send it */
1349 li r3,0x20 /* Print eyecatcher */
1350 bl dbgDchar /* Send it */
1351 li r3,0x20 /* Print eyecatcher */
1352 bl dbgDchar /* Send it */
1353 lwz r5,saver28(r13) /* Do register */
1354 bl dbg4byte /* Print */
1355 lwz r5,saver29(r13) /* Do register */
1356 bl dbg4byte /* Print */
1357 lwz r5,saver30(r13) /* Do register */
1358 bl dbg4byte /* Print */
1359 lwz r5,saver31(r13) /* Do register */
1360 bl dbg4byte /* Print */
1361 li r3,0x0A /* Linefeed */
1362 bl dbgDchar /* Send it */
1363 li r3,0x0D /* Carriage return */
1364 bl dbgDchar /* Send it */
1365
1366 /* Segment registers */
1367
1368 li r3,0x53 /* Print eyecatcher */
1369 bl dbgDchar /* Send it */
1370 li r3,0x65 /* Print eyecatcher */
1371 bl dbgDchar /* Send it */
1372 li r3,0x67 /* Print eyecatcher */
1373 bl dbgDchar /* Send it */
1374 li r3,0x73 /* Print eyecatcher */
1375 bl dbgDchar /* Send it */
1376 li r3,0x20 /* Print eyecatcher */
1377 bl dbgDchar /* Send it */
1378
1379 lwz r5,savesr0(r13) /* Do register */
1380 bl dbg4byte /* Print */
1381 lwz r5,savesr1(r13) /* Do register */
1382 bl dbg4byte /* Print */
1383 lwz r5,savesr2(r13) /* Do register */
1384 bl dbg4byte /* Print */
1385 lwz r5,savesr3(r13) /* Do register */
1386 bl dbg4byte /* Print */
1387 li r3,0x0A /* Linefeed */
1388 bl dbgDchar /* Send it */
1389 li r3,0x0D /* Carriage return */
1390 bl dbgDchar /* Send it */
1391
1392 li r3,0x20 /* Print eyecatcher */
1393 bl dbgDchar /* Send it */
1394 li r3,0x20 /* Print eyecatcher */
1395 bl dbgDchar /* Send it */
1396 li r3,0x20 /* Print eyecatcher */
1397 bl dbgDchar /* Send it */
1398 li r3,0x20 /* Print eyecatcher */
1399 bl dbgDchar /* Send it */
1400 li r3,0x20 /* Print eyecatcher */
1401 bl dbgDchar /* Send it */
1402 lwz r5,savesr4(r13) /* Do register */
1403 bl dbg4byte /* Print */
1404 lwz r5,savesr5(r13) /* Do register */
1405 bl dbg4byte /* Print */
1406 lwz r5,savesr6(r13) /* Do register */
1407 bl dbg4byte /* Print */
1408 lwz r5,savesr7(r13) /* Do register */
1409 bl dbg4byte /* Print */
1410 li r3,0x0A /* Linefeed */
1411 bl dbgDchar /* Send it */
1412 li r3,0x0D /* Carriage return */
1413 bl dbgDchar /* Send it */
1414
1415 li r3,0x20 /* Print eyecatcher */
1416 bl dbgDchar /* Send it */
1417 li r3,0x20 /* Print eyecatcher */
1418 bl dbgDchar /* Send it */
1419 li r3,0x20 /* Print eyecatcher */
1420 bl dbgDchar /* Send it */
1421 li r3,0x20 /* Print eyecatcher */
1422 bl dbgDchar /* Send it */
1423 li r3,0x20 /* Print eyecatcher */
1424 bl dbgDchar /* Send it */
1425 lwz r5,savesr8(r13) /* Do register */
1426 bl dbg4byte /* Print */
1427 lwz r5,savesr9(r13) /* Do register */
1428 bl dbg4byte /* Print */
1429 lwz r5,savesr10(r13) /* Do register */
1430 bl dbg4byte /* Print */
1431 lwz r5,savesr11(r13) /* Do register */
1432 bl dbg4byte /* Print */
1433 li r3,0x0A /* Linefeed */
1434 bl dbgDchar /* Send it */
1435 li r3,0x0D /* Carriage return */
1436 bl dbgDchar /* Send it */
1437
1438 li r3,0x20 /* Print eyecatcher */
1439 bl dbgDchar /* Send it */
1440 li r3,0x20 /* Print eyecatcher */
1441 bl dbgDchar /* Send it */
1442 li r3,0x20 /* Print eyecatcher */
1443 bl dbgDchar /* Send it */
1444 li r3,0x20 /* Print eyecatcher */
1445 bl dbgDchar /* Send it */
1446 li r3,0x20 /* Print eyecatcher */
1447 bl dbgDchar /* Send it */
1448 lwz r5,savesr12(r13) /* Do register */
1449 bl dbg4byte /* Print */
1450 lwz r5,savesr13(r13) /* Do register */
1451 bl dbg4byte /* Print */
1452 lwz r5,savesr14(r13) /* Do register */
1453 bl dbg4byte /* Print */
1454 lwz r5,savesr15(r13) /* Do register */
1455 bl dbg4byte /* Print */
1456 li r3,0x0A /* Linefeed */
1457 bl dbgDchar /* Send it */
1458 li r3,0x0D /* Carriage return */
1459 bl dbgDchar /* Send it */
1460
1461 li r3,0x30 /* Print eyecatcher */
1462 bl dbgDchar /* Send it */
1463 li r3,0x31 /* Print eyecatcher */
1464 bl dbgDchar /* Send it */
1465 li r3,0x64 /* Print eyecatcher */
1466 bl dbgDchar /* Send it */
1467 li r3,0x64 /* Print eyecatcher */
1468 bl dbgDchar /* Send it */
1469 li r3,0x20 /* Print eyecatcher */
1470 bl dbgDchar /* Send it */
1471 lwz r5,savesrr0(r13) /* Do register */
1472 bl dbg4byte /* Print */
1473 lwz r5,savesrr1(r13) /* Do register */
1474 bl dbg4byte /* Print */
1475 lwz r5,savedar(r13) /* Do register */
1476 bl dbg4byte /* Print */
1477 lwz r5,savedsisr(r13) /* Do register */
1478 bl dbg4byte /* Print */
1479 li r3,0x0A /* Linefeed */
1480 bl dbgDchar /* Send it */
1481 li r3,0x0D /* Carriage return */
1482 bl dbgDchar /* Send it */
1483
1484 li r3,0x20 /* Print eyecatcher */
1485 bl dbgDchar /* Send it */
1486 li r3,0x6C /* Print eyecatcher */
1487 bl dbgDchar /* Send it */
1488 li r3,0x63 /* Print eyecatcher */
1489 bl dbgDchar /* Send it */
1490 li r3,0x63 /* Print eyecatcher */
1491 bl dbgDchar /* Send it */
1492 li r3,0x20 /* Print eyecatcher */
1493 bl dbgDchar /* Send it */
1494 lwz r5,savelr(r13) /* Do register */
1495 bl dbg4byte /* Print */
1496 lwz r5,savecr(r13) /* Do register */
1497 bl dbg4byte /* Print */
1498 lwz r5,savectr(r13) /* Do register */
1499 bl dbg4byte /* Print */
1500 li r3,0x0A /* Linefeed */
1501 bl dbgDchar /* Send it */
1502 li r3,0x0D /* Carriage return */
1503 bl dbgDchar /* Send it */
1504 mtlr r11 /* Get back the return */
1505 dcbi 0,r10 /* ? */
1506 #if !SIMPLESCC && !NOTQUITEASSIMPLE
1507 li r7,0 /* Get a zero */
1508 mtdbatu 3,r7 /* Invalidate DBAT 3 upper */
1509 mtdbatl 3,r7 /* Invalidate DBAT 3 lower */
1510 #endif
1511 lis r3,HIGH_ADDR(fwdisplock) /* Get the display locker outer */
1512 li r7,0 /* Get a zero */
1513 ori r3,r3,LOW_ADDR(fwdisplock) /* Last part */
1514 stw r7,0(r3) /* Clear display lock */
1515 mtmsr r8 /* Restore the MSR */
1516 isync /* Wait for it */
1517 blr /* Leave... */
1518 #endif
1519
1520 /*
1521 * Used for debugging to leave stuff in 0x380-0x3FF (128 bytes).
1522 * Mapping is V=R. Stores and loads are real.
1523 */
1524
1525 .align 5
1526 .globl EXT(dbgCkpt)
1527
1528 LEXT(dbgCkpt)
1529
1530 mr r12,r0 /* Keep R0 pristene */
1531 lis r0,HIGH_ADDR(dbgCkptCall) /* Top half of dbgCkptCall firmware call number */
1532 ori r0,r0,LOW_ADDR(dbgCkptCall) /* Bottom half */
1533
1534 sc /* Go stash the stuff */
1535
1536 mr r0,r12 /* Restore R0 */
1537 blr /* Return... */
1538
1539 /* Here's the low-level part of dbgCkpt */
1540
1541 .align 5
1542 .globl EXT(dbgCkptLL)
1543
1544 LEXT(dbgCkptLL)
1545
1546
1547 li r12,0x380 /* Point to output area */
1548 li r1,32 /* Get line size */
1549 dcbz 0,r12 /* Make sure we don't fetch a cache line */
1550
1551 lwz r4,0x00(r3) /* Load up storage to checkpoint */
1552
1553 dcbt r1,r3 /* Start in the next line */
1554
1555 lwz r5,0x04(r3) /* Load up storage to checkpoint */
1556 lwz r6,0x08(r3) /* Load up storage to checkpoint */
1557 lwz r7,0x0C(r3) /* Load up storage to checkpoint */
1558 lwz r8,0x10(r3) /* Load up storage to checkpoint */
1559 lwz r9,0x14(r3) /* Load up storage to checkpoint */
1560 lwz r10,0x18(r3) /* Load up storage to checkpoint */
1561 lwz r11,0x1C(r3) /* Load up storage to checkpoint */
1562
1563 add r3,r3,r1 /* Bump input */
1564
1565 stw r4,0x00(r12) /* Store it */
1566 stw r5,0x04(r12) /* Store it */
1567 stw r6,0x08(r12) /* Store it */
1568 stw r7,0x0C(r12) /* Store it */
1569 stw r8,0x10(r12) /* Store it */
1570 stw r9,0x14(r12) /* Store it */
1571 stw r10,0x18(r12) /* Store it */
1572 stw r11,0x1C(r12) /* Store it */
1573
1574 dcbz r1,r12 /* Clear the next line */
1575 add r12,r12,r1 /* Point to next output line */
1576
1577 lwz r4,0x00(r3) /* Load up storage to checkpoint */
1578 lwz r5,0x04(r3) /* Load up storage to checkpoint */
1579 lwz r6,0x08(r3) /* Load up storage to checkpoint */
1580 lwz r7,0x0C(r3) /* Load up storage to checkpoint */
1581 lwz r8,0x10(r3) /* Load up storage to checkpoint */
1582 lwz r9,0x14(r3) /* Load up storage to checkpoint */
1583 lwz r10,0x18(r3) /* Load up storage to checkpoint */
1584 lwz r11,0x1C(r3) /* Load up storage to checkpoint */
1585
1586 dcbt r1,r3 /* Touch the next line */
1587 add r3,r3,r1 /* Point to next input line */
1588
1589 stw r4,0x00(r12) /* Store it */
1590 stw r5,0x04(r12) /* Store it */
1591 stw r6,0x08(r12) /* Store it */
1592 stw r7,0x0C(r12) /* Store it */
1593 stw r8,0x10(r12) /* Store it */
1594 stw r9,0x14(r12) /* Store it */
1595 stw r10,0x18(r12) /* Store it */
1596 stw r11,0x1C(r12) /* Store it */
1597
1598 dcbz r1,r12 /* Clear the next line */
1599 add r12,r12,r1 /* Point to next output line */
1600
1601 lwz r4,0x00(r3) /* Load up storage to checkpoint */
1602 lwz r5,0x04(r3) /* Load up storage to checkpoint */
1603 lwz r6,0x08(r3) /* Load up storage to checkpoint */
1604 lwz r7,0x0C(r3) /* Load up storage to checkpoint */
1605 lwz r8,0x10(r3) /* Load up storage to checkpoint */
1606 lwz r9,0x14(r3) /* Load up storage to checkpoint */
1607 lwz r10,0x18(r3) /* Load up storage to checkpoint */
1608 lwz r11,0x1C(r3) /* Load up storage to checkpoint */
1609
1610 dcbt r1,r3 /* Touch the next line */
1611 add r3,r3,r1 /* Point to next input line */
1612
1613 stw r4,0x00(r12) /* Store it */
1614 stw r5,0x04(r12) /* Store it */
1615 stw r6,0x08(r12) /* Store it */
1616 stw r7,0x0C(r12) /* Store it */
1617 stw r8,0x10(r12) /* Store it */
1618 stw r9,0x14(r12) /* Store it */
1619 stw r10,0x18(r12) /* Store it */
1620 stw r11,0x1C(r12) /* Store it */
1621
1622 dcbz r1,r12 /* Clear the next line */
1623 add r12,r12,r1 /* Point to next output line */
1624
1625 lwz r4,0x00(r3) /* Load up storage to checkpoint */
1626 lwz r5,0x04(r3) /* Load up storage to checkpoint */
1627 lwz r6,0x08(r3) /* Load up storage to checkpoint */
1628 lwz r7,0x0C(r3) /* Load up storage to checkpoint */
1629 lwz r8,0x10(r3) /* Load up storage to checkpoint */
1630 lwz r9,0x14(r3) /* Load up storage to checkpoint */
1631 lwz r10,0x18(r3) /* Load up storage to checkpoint */
1632 lwz r11,0x1C(r3) /* Load up storage to checkpoint */
1633
1634 stw r4,0x00(r12) /* Store it */
1635 stw r5,0x04(r12) /* Store it */
1636 stw r6,0x08(r12) /* Store it */
1637 stw r7,0x0C(r12) /* Store it */
1638 stw r8,0x10(r12) /* Store it */
1639 stw r9,0x14(r12) /* Store it */
1640 stw r10,0x18(r12) /* Store it */
1641 stw r11,0x1C(r12) /* Store it */
1642
1643 blr
1644
1645
1646 /*
1647 * Do Preemption. Forces a T_PREEMPT trap to allow a preemption to occur.
1648 */
1649
1650 .align 5
1651 .globl EXT(DoPreemptLL)
1652
1653 LEXT(DoPreemptLL)
1654
1655 li r3,T_PREEMPT /* Set preemption interrupt value */
1656 stw r3,saveexception(r13) /* Modify the exception type to preemption */
1657 b EXT(FCReturn) ; Bye dudes...
1658
1659
1660 /*
1661 * Force 'rupt handler to dispatch with new context
1662 * R3 at the call contains the new savearea.
1663 * R4 at the call contains a return code to pass back in R3.
1664 * Forces a T_CSWITCH
1665 */
1666
1667 .align 5
1668 .globl EXT(SwitchContextLL)
1669
1670 LEXT(SwitchContextLL)
1671
1672 li r3,T_CSWITCH /* Set context switch value */
1673 stw r3,saveexception(r13) /* Modify the exception type to switch context */
1674 b EXT(FCReturn) ; Bye dudes...
1675
1676
1677 /*
1678 * Create a fake I/O 'rupt.
1679 * Forces a T_INTERRUPT trap to pretend that an actual I/O interrupt occurred.
1680 */
1681
1682 .align 5
1683 .globl EXT(CreateFakeIOLL)
1684
1685 LEXT(CreateFakeIOLL)
1686
1687 li r3,T_INTERRUPT /* Set external interrupt value */
1688 stw r3,saveexception(r13) /* Modify the exception type to external */
1689 b EXT(FCReturn) ; Bye dudes...
1690
1691 /*
1692 * Create a shutdown context
1693 * Forces a T_SHUTDOWN trap.
1694 */
1695
1696 .align 5
1697 .globl EXT(CreateShutdownCTXLL)
1698
1699 LEXT(CreateShutdownCTXLL)
1700
1701 li r3,T_SHUTDOWN /* Set external interrupt value */
1702 stw r3,saveexception(r13) /* Modify the exception type to external */
1703 b EXT(FCReturn) ; Bye dudes...
1704
1705 /*
1706 * Create a fake decrementer 'rupt.
1707 * Forces a T_DECREMENTER trap to pretend that an actual decrementer interrupt occurred.
1708 */
1709
1710 .align 5
1711 .globl EXT(CreateFakeDECLL)
1712
1713 LEXT(CreateFakeDECLL)
1714
1715 li r3,T_DECREMENTER /* Set decrementer interrupt value */
1716 stw r3,saveexception(r13) /* Modify the exception type to external */
1717 b EXT(FCReturn) ; Bye dudes...
1718
1719 /*
1720 * Choke the system.
1721 */
1722
1723 .align 5
1724 .globl EXT(DoChokeLL)
1725
1726 LEXT(DoChokeLL)
1727
1728 li r3,T_CHOKE ; Set external interrupt value
1729 stw r3,saveexception(r13) ; Modify the exception type to external
1730 b EXT(FCReturn) ; Bye dudes...
1731
1732 /*
1733 * Null firmware call
1734 */
1735
1736 .align 5
1737 .globl EXT(NullLL)
1738
1739 LEXT(NullLL)
1740
1741 li r3,T_IN_VAIN ; Set to just ignore this one
1742 b EXT(FCReturn) ; Bye dudes...
1743
1744 ;
1745 ; Null firmware call
1746 ;
1747
1748 .align 5
1749 .globl EXT(iNullLL)
1750
1751 LEXT(iNullLL)
1752
1753 mfspr r4,pmc1 ; Get stamp
1754 stw r4,0x6100+(9*16)+0x0(0) ; Save it
1755 #if 1
1756 mfspr r4,pmc2 ; Get stamp
1757 stw r4,0x6100+(9*16)+0x4(0) ; Save it
1758 mfspr r4,pmc3 ; Get stamp
1759 stw r4,0x6100+(9*16)+0x8(0) ; Save it
1760 mfspr r4,pmc4 ; Get stamp
1761 stw r4,0x6100+(9*16)+0xC(0) ; Save it
1762 #endif
1763 li r3,T_IN_VAIN ; Set to just ignore this one
1764 b EXT(FCReturn) ; Bye dudes...
1765
1766 ;
1767 ; Set the low level trace flags
1768 ;
1769
1770 .align 5
1771 .globl EXT(LLTraceSet)
1772
1773 LEXT(LLTraceSet)
1774
1775 mr r4,r3 ; Save the new value
1776
1777 lwz r3,traceMask(0) ; Get the old trace flags to pass back
1778 stw r4,traceMask(0) ; Replace with the new ones
1779 blr ; Leave...
1780
1781 #if 0
1782
1783 /*
1784 ; ***************************************************************************
1785 ;
1786 ; ----------------- Grateful Deb ----------------
1787 ;
1788 ; Debugging: direct draw into main screen menu bar
1789 ;
1790 ; Takes R4 value, converts it to hex characters and displays it.
1791 ;
1792 ; Gotta make sure the DCBST is done to force the pixels from the cache.
1793 ;
1794 ; Position is taken as column, row (0 based) from R3.
1795 ; Characters are from hexfont, and are 16x16 pixels.
1796 ;
1797 ; Only works with two processors so far
1798 ;
1799 ;
1800 ; ***************************************************************************
1801 */
1802
1803 #define GDfromright 20
1804 #define GDfontsize 16
1805
1806 .align 5
1807 .globl EXT(GratefulDeb)
1808
1809 LEXT(GratefulDeb)
1810
1811 mfspr r6,pir /* Get the PIR */
1812 lis r5,HIGH_ADDR(EXT(GratefulDebWork)) /* Point to our work area */
1813 rlwinm r6,r6,8,23,23 /* Get part of the offset to our processors area */
1814 ori r5,r5,LOW_ADDR(EXT(GratefulDebWork)) /* Start building the address */
1815 rlwimi r6,r6,2,21,21 /* Get the rest of the offset to our processors area */
1816 add r6,r6,r5 /* Point at our CPU's work area */
1817 mfmsr r5 /* Get that MSR */
1818 stmw r0,GDsave(r6) /* Save all registers */
1819 lwz r10,GDready(r6) /* See if we're all ready to go */
1820 ori r0,r5,0x2000 /* Turn on the floating point */
1821 mr r31,r6 /* Get a more sane base register */
1822 mr. r10,r10 /* Are we all set? */
1823 mtmsr r0 /* Enable floating point */
1824 isync
1825
1826 stfd f0,GDfp0(r31) /* Save FP */
1827 stfd f1,GDfp1(r31) /* Save FP */
1828 stfd f2,GDfp2(r31) /* Save FP */
1829 stfd f3,GDfp3(r31) /* Save FP */
1830
1831 beq- GDbailout /* Go and bail... */
1832
1833 rlwinm r25,r3,0,16,31 /* Isolate just the row number */
1834 lwz r28,GDtopleft(r31) /* Get the physical address of our line 0 */
1835 rlwinm r3,r3,16,16,31 /* Isolate the column number */
1836 lwz r27,GDrowbytes(r31) /* Get the number of bytes per row */
1837 lwz r9,GDrowchar(r31) /* Get the number of bytes per row of full leaded charactrers */
1838 lwz r26,GDdepth(r31) /* Get the bit depth */
1839 mullw r25,r25,r9 /* get offset to the row to write in bytes */
1840 lwz r24,GDcollgn(r31) /* Get the size of columns in bytes */
1841 add r25,r28,r25 /* Physical address of row */
1842 mullw r3,r3,r24 /* Get byte offset to first output column */
1843
1844 li r9,32 /* Get the initial shift calc */
1845
1846 lis r20,HIGH_ADDR(hexfont) /* Point to the font */
1847
1848 li r18,GDfontsize /* Get the number of rows in the font */
1849 ori r20,r20,LOW_ADDR(hexfont) /* Point to the low part */
1850 add r21,r25,r3 /* Physical address of top left output pixel */
1851 sub r9,r9,r26 /* Get right shift justifier for pixel size */
1852 li r7,32 /* Number of bits per word */
1853
1854 startNybble:
1855 la r6,GDrowbuf1(r31) /* Point to the row buffer */
1856 li r19,8 /* Get the number of characters in a row */
1857
1858 getNybble: rlwinm r10,r4,9,23,26 /* Get the top nybble * 32 */
1859 rlwinm r4,r4,4,0,31 /* Rotate a nybble */
1860 add r10,r20,r10 /* Point to the character in the font */
1861
1862 rlwinm r16,r26,4,0,27 /* Width of row in actual bits */
1863 lhz r15,0(r10) /* Get the next row of the font */
1864
1865 rendrow: rlwinm r17,r15,16,0,0 /* Get the next font pixel in the row */
1866 rlwinm r15,r15,1,16,31 /* Move in the next font pixel */
1867 srawi r17,r17,31 /* Fill with 1s if black and 0s if white (reversed) */
1868
1869 slw r14,r14,r26 /* Make room for our pixel in a register */
1870 srw r17,r17,r9 /* Isolate one pixels worth of black or white */
1871 sub. r7,r7,r26 /* See how may bits are left */
1872 sub r16,r16,r26 /* Count how many bits are left to store for this row */
1873 or r14,r14,r17 /* Put in the pixel */
1874 bne+ notfull /* Finish rendering this word */
1875
1876 not r14,r14 /* Invert to black on white */
1877 stw r14,0(r6) /* Write out the word */
1878 li r7,32 /* Bit per word count */
1879 addi r6,r6,4 /* Point to the next word */
1880
1881 notfull: mr. r16,r16 /* Have we finished the whole character row? */
1882 bne+ rendrow /* Finish rendering the row */
1883
1884 addic. r19,r19,-1 /* Are we finished with a whole display row yet? */
1885 bne+ getNybble /* Not yet... */
1886
1887 la r6,GDrowbuf1(r31) /* Point to the row buffer */
1888 rlwinm r19,r26,31,0,29 /* Number of cache lines (depth/2) */
1889 mr r14,r21 /* Get the frame buffer address */
1890
1891 // BREAKPOINT_TRAP
1892
1893 blitrow: lfd f0,0(r6) /* Load a line */
1894 lfd f1,8(r6)
1895 lfd f2,16(r6)
1896 lfd f3,24(r6)
1897
1898 stfd f0,0(r14) /* Blit a line */
1899 stfd f1,8(r14)
1900 stfd f2,16(r14)
1901 stfd f3,24(r14)
1902
1903 addi r6,r6,32 /* Next buffered line */
1904
1905 dcbst 0,r14 /* Force the line to the screen */
1906 sync /* Make sure the line is on it's way */
1907 eieio /* Make sure we beat the invalidate */
1908 dcbi 0,r14 /* Make sure we leave no paradox */
1909
1910 addic. r19,r19,-1 /* Done all lines yet? */
1911 addi r14,r14,32 /* Point to the next output */
1912 bne+ blitrow /* Nope, do it some more... */
1913
1914 addic. r18,r18,-1 /* Have we done all the rows in character yet? */
1915 addi r20,r20,2 /* Offset the font to the next row */
1916 add r21,r21,r27 /* Point to start of next row */
1917 bne+ startNybble /* Nope, go through the word one more time... */
1918
1919 GDbailout: mr r1,r31 /* Move the workarea base */
1920
1921 lfd f0,GDfp0(r31) /* Restore FP */
1922 lfd f1,GDfp1(r31) /* Restore FP */
1923 lfd f2,GDfp2(r31) /* Restore FP */
1924 lfd f3,GDfp3(r31) /* Restore FP */
1925
1926 mtmsr r5 /* Disable floating point */
1927 isync
1928
1929 lmw r3,GDsave+12(r1) /* Restore most registers */
1930 lwz r0,GDsave(r1) /* Restore R0 */
1931 lwz r1,GDsave+4(r1) /* Finally, R1 */
1932 blr /* Leave... */
1933
1934
1935 /*
1936 * void GratefulDebDisp(unsigned int coord, unsigned int data);
1937 */
1938
1939
1940 .align 5
1941 .globl EXT(GratefulDebDisp)
1942
1943 LEXT(GratefulDebDisp)
1944
1945 mfmsr r9 /* Save the current MSR */
1946 mflr r7 /* Save the return */
1947 andi. r8,r9,0x7FCF /* Clear interrupt and translation */
1948 mtmsr r8 /* Turn 'em really off */
1949 isync /* Make sure about the translation part */
1950 bl EXT(GratefulDeb) /* Display it */
1951 mtmsr r9 /* Restore interrupt and translation */
1952 mtlr r7 /* Restore return */
1953 isync /* Make sure */
1954 blr
1955
1956
1957 #endif
1958
1959 /*
1960 * void checkNMI(void);
1961 */
1962
1963
1964 .align 5
1965 .globl EXT(checkNMI)
1966
1967 LEXT(checkNMI)
1968
1969 mfmsr r9 /* Save it */
1970 andi. r8,r9,0x7FCF /* Clear it */
1971 mtmsr r8 /* Disable it */
1972 isync /* Fence it */
1973 lis r7,0xF300 /* Find it */
1974 lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
1975 ori r7,r7,0x0020 /* Find it */
1976 ori r2,r2,lo16(MASK(MSR_FP)) ; Get the FP enable
1977 dcbi 0,r7 /* Toss it */
1978 sync /* Sync it */
1979 andc r9,r9,r2 ; Clear VEC and FP enables
1980 eieio /* Get it */
1981 lwz r6,0x000C(r7) /* Check it */
1982 eieio /* Fence it */
1983 dcbi 0,r7 /* Toss it */
1984 rlwinm. r4,r6,0,19,19 /* Check it */
1985 rlwinm r6,r6,0,20,18 /* Clear it */
1986 sync /* Sync it */
1987 eieio /* Fence it */
1988 beq+ xnonmi /* Branch on it */
1989
1990 stw r6,0x0008(r7) /* Reset it */
1991 sync /* Sync it */
1992 dcbi 0,r6 /* Toss it */
1993 eieio /* Fence it */
1994
1995 mtmsr r9 /* Restore it */
1996 isync /* Hold it */
1997
1998 BREAKPOINT_TRAP /* Kill it */
1999 blr /* Return from it */
2000
2001 xnonmi: /* Label it */
2002 mtmsr r9 /* Restore it */
2003 isync /* Hold it */
2004 blr /* Return from it */
2005
2006 ;
2007 ; Saves floating point registers
2008 ;
2009
2010 .align 5
2011 .globl EXT(stFloat)
2012
2013 LEXT(stFloat)
2014
2015 lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
2016 li r4,0
2017 ori r2,r2,lo16(MASK(MSR_FP)) ; Get the FP enable
2018 ori r4,r4,lo16(MASK(MSR_EE)) ; Get the EE bit
2019
2020 mfmsr r0 ; Save the MSR
2021
2022 andc r4,r0,r4 ; Clear EE
2023 ori r4,r4,lo16(MASK(MSR_FP)) ; Enable floating point
2024 mtmsr r4
2025 isync
2026
2027 andc r0,r0,r2 ; Clear VEC and FP enables
2028
2029 stfd f0,0x00(r3)
2030 stfd f1,0x08(r3)
2031 stfd f2,0x10(r3)
2032 stfd f3,0x18(r3)
2033 stfd f4,0x20(r3)
2034 stfd f5,0x28(r3)
2035 stfd f6,0x30(r3)
2036 stfd f7,0x38(r3)
2037 stfd f8,0x40(r3)
2038 stfd f9,0x48(r3)
2039 stfd f10,0x50(r3)
2040 stfd f11,0x58(r3)
2041 stfd f12,0x60(r3)
2042 stfd f13,0x68(r3)
2043 stfd f14,0x70(r3)
2044 stfd f15,0x78(r3)
2045 stfd f16,0x80(r3)
2046 stfd f17,0x88(r3)
2047 stfd f18,0x90(r3)
2048 stfd f19,0x98(r3)
2049 stfd f20,0xA0(r3)
2050 stfd f21,0xA8(r3)
2051 stfd f22,0xB0(r3)
2052 stfd f23,0xB8(r3)
2053 stfd f24,0xC0(r3)
2054 stfd f25,0xC8(r3)
2055 stfd f26,0xD0(r3)
2056 stfd f27,0xD8(r3)
2057 stfd f28,0xE0(r3)
2058 stfd f29,0xE8(r3)
2059 stfd f30,0xF0(r3)
2060 stfd f31,0xF8(r3)
2061 mffs f0
2062 stfd f0,0x100(r3)
2063 lfd f0,0x00(r3)
2064 mtmsr r0
2065 isync
2066 blr
2067
2068
2069 ;
2070 ; Saves vector registers. Returns 0 if non-Altivec machine.
2071 ;
2072
2073 .align 5
2074 .globl EXT(stVectors)
2075
2076 LEXT(stVectors)
2077
2078 lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
2079 li r4,0
2080 ori r2,r2,lo16(MASK(MSR_FP)) ; Get the FP enable
2081 ori r4,r4,lo16(MASK(MSR_EE)) ; Get the EE bit
2082
2083 mfsprg r6,2 ; Get features
2084 mr r5,r3 ; Save area address
2085 rlwinm. r6,r6,0,pfAltivecb,pfAltivecb ; Do we have Altivec?
2086 li r3,0 ; Assume failure
2087 beqlr- ; No...
2088
2089 mfmsr r0 ; Save the MSR
2090
2091 andc r4,r0,r4 ; Clear EE
2092
2093 oris r4,r4,hi16(MASK(MSR_VEC)) ; Enable vectors
2094 mtmsr r4
2095 isync
2096
2097 andc r0,r0,r2 ; Clear FP and VEC
2098
2099 stvxl v0,0,r5
2100 addi r5,r5,16
2101 stvxl v1,0,r5
2102 addi r5,r5,16
2103 stvxl v2,0,r5
2104 addi r5,r5,16
2105 stvxl v3,0,r5
2106 addi r5,r5,16
2107 stvxl v4,0,r5
2108 addi r5,r5,16
2109 stvxl v5,0,r5
2110 addi r5,r5,16
2111 stvxl v6,0,r5
2112 addi r5,r5,16
2113 stvxl v7,0,r5
2114 addi r5,r5,16
2115 stvxl v8,0,r5
2116 addi r5,r5,16
2117 stvxl v9,0,r5
2118 addi r5,r5,16
2119 stvxl v10,0,r5
2120 addi r5,r5,16
2121 stvxl v11,0,r5
2122 addi r5,r5,16
2123 stvxl v12,0,r5
2124 addi r5,r5,16
2125 stvxl v13,0,r5
2126 addi r5,r5,16
2127 stvxl v14,0,r5
2128 addi r5,r5,16
2129 stvxl v15,0,r5
2130 addi r5,r5,16
2131 stvxl v16,0,r5
2132 addi r5,r5,16
2133 stvxl v17,0,r5
2134 addi r5,r5,16
2135 stvxl v18,0,r5
2136 addi r5,r5,16
2137 stvxl v19,0,r5
2138 addi r5,r5,16
2139 stvxl v20,0,r5
2140 addi r5,r5,16
2141 stvxl v21,0,r5
2142 addi r5,r5,16
2143 stvxl v22,0,r5
2144 addi r5,r5,16
2145 stvxl v23,0,r5
2146 addi r5,r5,16
2147 stvxl v24,0,r5
2148 addi r5,r5,16
2149 stvxl v25,0,r5
2150 addi r5,r5,16
2151 stvxl v26,0,r5
2152 addi r5,r5,16
2153 stvxl v27,0,r5
2154 addi r5,r5,16
2155 stvxl v28,0,r5
2156 addi r5,r5,16
2157 stvxl v29,0,r5
2158 addi r5,r5,16
2159 stvxl v30,0,r5
2160 addi r5,r5,16
2161 stvxl v31,0,r5
2162 mfvscr v31
2163 addi r6,r5,16
2164 stvxl v31,0,r6
2165 li r3,1
2166 lvxl v31,0,r5
2167 mtmsr r0
2168 isync
2169
2170 blr
2171
2172
2173 ;
2174 ; Saves yet more registers
2175 ;
2176
2177 .align 5
2178 .globl EXT(stSpecrs)
2179
2180 LEXT(stSpecrs)
2181
2182
2183 lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
2184 li r4,0
2185 ori r2,r2,lo16(MASK(MSR_FP)) ; Get the FP enable
2186 ori r4,r4,lo16(MASK(MSR_EE)) ; Get the EE bit
2187
2188 mfsprg r9,2 ; Get feature flags
2189 mtcrf 0x02,r9 ; move pf64Bit cr6
2190
2191 mfmsr r0 ; Save the MSR
2192 andc r0,r0,r2 ; Turn off VEC and FP
2193 andc r4,r0,r4 ; And EE
2194 mtmsr r4
2195 isync
2196
2197 mfpvr r12
2198 stw r12,4(r3)
2199 rlwinm r12,r12,16,16,31
2200
2201 bt++ pf64Bitb,stsSF1 ; skip if 64-bit (only they take the hint)
2202
2203 mfdbatu r4,0
2204 mfdbatl r5,0
2205 mfdbatu r6,1
2206 mfdbatl r7,1
2207 mfdbatu r8,2
2208 mfdbatl r9,2
2209 mfdbatu r10,3
2210 mfdbatl r11,3
2211 stw r4,8(r3)
2212 stw r5,12(r3)
2213 stw r6,16(r3)
2214 stw r7,20(r3)
2215 stw r8,24(r3)
2216 stw r9,28(r3)
2217 stw r10,32(r3)
2218 stw r11,36(r3)
2219
2220 mfibatu r4,0
2221 mfibatl r5,0
2222 mfibatu r6,1
2223 mfibatl r7,1
2224 mfibatu r8,2
2225 mfibatl r9,2
2226 mfibatu r10,3
2227 mfibatl r11,3
2228 stw r4,40(r3)
2229 stw r5,44(r3)
2230 stw r6,48(r3)
2231 stw r7,52(r3)
2232 stw r8,56(r3)
2233 stw r9,60(r3)
2234 stw r10,64(r3)
2235 stw r11,68(r3)
2236
2237 mfsprg r4,0
2238 mfsprg r5,1
2239 mfsprg r6,2
2240 mfsprg r7,3
2241 stw r4,72(r3)
2242 stw r5,76(r3)
2243 stw r6,80(r3)
2244 stw r7,84(r3)
2245
2246 mfsdr1 r4
2247 stw r4,88(r3)
2248
2249 la r4,92(r3)
2250 li r5,0
2251
2252 stSnsr: mfsrin r6,r5
2253 addis r5,r5,0x1000
2254 stw r6,0(r4)
2255 mr. r5,r5
2256 addi r4,r4,4
2257 bne+ stSnsr
2258
2259 cmplwi r12,PROCESSOR_VERSION_750
2260 mfspr r4,hid0
2261 stw r4,(39*4)(r3)
2262
2263 li r4,0
2264 li r5,0
2265 li r6,0
2266 li r7,0
2267
2268 mfspr r4,hid1
2269 mfspr r5,l2cr
2270 mfspr r6,msscr0
2271 mfspr r7,msscr1
2272
2273 stw r4,(40*4)(r3)
2274 stw r6,(42*4)(r3)
2275 stw r5,(41*4)(r3)
2276 stw r7,(43*4)(r3)
2277
2278 li r4,0
2279 beq isis750
2280
2281 mfspr r4,pir
2282 isis750: stw r4,0(r3)
2283
2284 li r4,0
2285 li r5,0
2286 li r6,0
2287 li r7,0
2288 blt- b4750
2289
2290 mfspr r4,thrm1
2291 mfspr r5,thrm2
2292 mfspr r6,thrm3
2293 mfspr r7,ictc
2294
2295 b4750: stw r4,(44*4)(r3)
2296 stw r5,(45*4)(r3)
2297 stw r6,(46*4)(r3)
2298 stw r7,(47*4)(r3)
2299
2300 li r4,0
2301 li r6,0
2302 cmplwi r12,PROCESSOR_VERSION_7400
2303 bne nnmax
2304
2305 mfspr r6,dabr
2306 mfpvr r5
2307 rlwinm r5,r5,0,16,31
2308 cmplwi r5,0x1101
2309 beq gnmax
2310 cmplwi r5,0x1102
2311 bne nnmax
2312
2313 gnmax: mfspr r4,1016
2314
2315 nnmax: stw r4,(48*4)(r3)
2316 stw r6,(49*4)(r3)
2317
2318 mtmsr r0
2319 isync
2320
2321 blr
2322
2323 stsSF1: mfsprg r4,0
2324 mfsprg r5,1
2325 mfsprg r6,2
2326 mfsprg r7,3
2327 std r4,(18*4)(r3)
2328 std r5,(20*4)(r3)
2329 std r6,(22*4)(r3)
2330 std r7,(24*4)(r3)
2331
2332 mfsdr1 r4
2333 std r4,(26*4)(r3)
2334
2335 mfspr r4,hid0
2336 std r4,(28*4)(r3)
2337 mfspr r4,hid1
2338 std r4,(30*4)(r3)
2339 mfspr r4,hid4
2340 std r4,(32*4)(r3)
2341 mfspr r4,hid5
2342 std r4,(34*4)(r3)
2343
2344
2345 stsSF2: li r5,0
2346 la r4,(80*4)(r3)
2347
2348 stsslbm: slbmfee r6,r5
2349 slbmfev r7,r5
2350 std r6,0(r4)
2351 std r7,8(r4)
2352 addi r5,r5,1
2353 cmplwi r5,64
2354 addi r4,r4,16
2355 blt stsslbm
2356
2357 mtmsr r0
2358 isync
2359
2360 blr
2361
2362 ;
2363 ; fwEmMck - this forces the hardware to emulate machine checks
2364 ; Only valid on 64-bit machines
2365 ; Note: we want interruptions disabled here
2366 ;
2367
2368 .globl EXT(fwEmMck)
2369
2370 .align 5
2371
2372 LEXT(fwEmMck)
2373
2374
2375 rlwinm r3,r3,0,1,0 ; Copy low of high high - scomd
2376 rlwinm r5,r5,0,1,0 ; Copy low of high high - hid1
2377 rlwinm r7,r7,0,1,0 ; Copy low of high high - hid4
2378 rlwimi r3,r4,0,0,31 ; Copy low of low low
2379 rlwimi r5,r6,0,0,31 ; Copy low of low low
2380 rlwimi r7,r8,0,0,31 ; Copy low of low low
2381
2382 lis r9,3 ; Start forming hid1 error inject mask
2383 lis r10,hi16(0x01084083) ; Start formaing hid4 error inject mask
2384 ori r9,r9,0xC000 ; Next bit
2385 ori r10,r10,lo16(0x01084083) ; Next part
2386 sldi r9,r9,32 ; Shift up high
2387 sldi r10,r10,8 ; Shift into position
2388
2389 mfspr r0,hid1 ; Get hid1
2390 mfspr r2,hid4 ; and hid4
2391
2392 and r5,r5,r9 ; Keep only error inject controls - hid1
2393 and r7,r7,r10 ; Keep only error inject controls - hid4
2394
2395 andc r0,r0,r9 ; Clear error inject controls hid1
2396 andc r2,r2,r10 ; Clear error inject controls hid4
2397
2398 or r0,r0,r5 ; Add in the new controls hid1
2399 or r2,r2,r7 ; Add in the new controls hid4
2400
2401 /* ? */
2402 #if 0
2403 lis r12,CoreErrI ; Get the error inject controls
2404 sync
2405
2406 mtspr scomd,r3 ; Set the error inject controls
2407 mtspr scomc,r12 ; Request error inject
2408 mfspr r11,scomc ; Get back the status (we just ignore it)
2409 #endif
2410 sync
2411 isync
2412
2413 mtspr hid1,r0 ; Move in hid1 controls
2414 mtspr hid1,r0 ; We need to do it twice
2415 isync
2416
2417 sync
2418 mtspr hid4,r2 ; Move in hid4 controls
2419 isync
2420
2421 blr ; Leave...
2422
2423 ;
2424 ; fwSCOMrd - read/write SCOM
2425 ;
2426 .align 5
2427 .globl EXT(fwSCOM)
2428
2429 LEXT(fwSCOM)
2430
2431 lhz r12,scomfunc(r3) ; Get the function
2432 lwz r4,scomreg(r3) ; Get the register
2433 rldicr r4,r4,8,47 ; Position for SCOM
2434
2435 mr. r12,r12 ; See if read or write
2436 bne fwSCwrite ; Go do a write
2437
2438 mfsprg r0,2 ; Get the feature flags
2439 ori r4,r4,0x8000 ; Set to read data
2440 rlwinm. r0,r0,pfSCOMFixUpb+1,31,31 ; Set shift if we need a fix me up
2441 sync
2442
2443 mtspr scomc,r4 ; Request the register
2444 mfspr r11,scomd ; Get the register contents
2445 mfspr r10,scomc ; Get back the status
2446 sync
2447 isync
2448
2449 sld r11,r11,r0 ; Fix up if needed
2450
2451 std r11,scomdata(r3) ; Save result
2452 eieio
2453 std r10,scomstat(r3) ; Save status
2454
2455 blr
2456
2457 fwSCwrite: ld r5,scomdata(r3) ; Get the data
2458
2459 sync
2460
2461 mtspr scomd,r5 ; Set the data
2462 mtspr scomc,r4 ; Set it
2463 mfspr r10,scomc ; Get back the status
2464 sync
2465 isync
2466
2467 std r10,scomstat(r3) ; Save status
2468
2469 blr
2470
2471 ;
2472 ; diagTrap - this is used to trigger checks from user space
2473 ; any "twi 31,r31,0xFFFx" will come here (x = 0 to F).
2474 ; On entry R3 points to savearea.
2475 ; R4 is the "x" from instruction;
2476 ; Pass back 1 to no-op twi and return to user
2477 ; Pass back 0 to treat as normal twi.
2478 ;
2479
2480 .globl EXT(diagTrap)
2481
2482 .align 5
2483
2484 LEXT(diagTrap)
2485
2486 li r3,1 ; Ignore TWI
2487 blr ; Leave...
2488
2489
2490
2491
2492 ;
2493 ; setPmon - this is used to manipulate MMCR0 and MMCR1
2494
2495 .globl EXT(setPmon)
2496
2497 .align 5
2498
2499 LEXT(setPmon)
2500
2501 li r0,0
2502 isync
2503 mtspr mmcr0,r0 ; Clear MMCR0
2504 mtspr mmcr1,r0 ; Clear MMCR1
2505 mtspr pmc1,r0
2506 mtspr pmc2,r0
2507 mtspr pmc3,r0
2508 mtspr pmc4,r0
2509
2510 isync
2511
2512 mtspr mmcr0,r3 ; Set MMCR0
2513 mtspr mmcr1,r4 ; Set MMCR1
2514 isync
2515 blr ; Leave...
2516
2517