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