1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
|
#if defined(JAZZ) && defined(R4000)
// TITLE("Interrupt and Exception Processing")
//++
//
// Copyright (c) 1991 Microsoft Corporation
//
// Module Name:
//
// j4trap.s
//
// Abstract:
//
// This module implements the code necessary to field and process MIPS
// interrupt and exception conditions during bootstrap.
//
// Author:
//
// David N. Cutler (davec) 21-Apr-1991
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
#include "ksmips.h"
SBTTL("Constant Value Definitions")
//++
//
// The following are definitions of constants used in this module.
//
//--
#define PSR_MASK (~((0x3 << PSR_KSU) | (1 << PSR_EXL))) // PSR exception mask
//++
//
// Define dummy data allocation.
//
//--
.data
.space 4 //
SavedK1Address:
.space 4 // address where to save k1 to return to fw.
SBTTL("General Exception Vector Routine")
//++
//
// Routine Description:
//
// This routine is entered as the result of a general exception. The reason
// for the exception is contained in the cause register. When this routine
// is entered, interrupts are disabled.
//
// All exception that occur during the bootstrap process are treated as
// if a breakpoint had occurred. This ultimately causes either the kernel
// debugger or a stub routine provided by the bootstrap itself to be
// invoked.
//
// The address of this routine is copied to the GEV in the SPB
// so that the firmware jumps to this routine when a GeneralException
// occurres. This routine must return to the address pointed by k1.
// and leave the address where the firmware must return from the
// exception in k0.
//
//
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiGeneralException)
//
// No TLB Miss is supposed to occurr during the boot process
// The TbMiss handler is just the same general exception handler.
//
ALTERNATE_ENTRY(KiTbMiss)
START_REGION(KiGeneralExceptionStartAddress)
.set noreorder
.set noat
la k0,10f // transfer immediately to physical
j k0 //
nop //
10: subu k0,sp,TrapFrameLength // allocate trap frame
sw sp,TrIntSp(k0) // save integer register sp
move sp,k0 // set new stack pointer
la k0,SavedK1Address // get address of where to save k1
sw k1,0(k0) // save firmware return address
sw gp,TrIntGp(sp) // save integer register gp
sw s8,TrIntS8(sp) // save integer register s8
sw ra,TrIntRa(sp) // save integer register ra
mfc0 s8,cause // get cause of exception
mfc0 k0,psr // get current processor status
mfc0 k1,epc // get exception PC
sw k0,TrPsr(sp) // save current PSR
sw k1,TrFir(sp) // save exception PC
bgez s8,20f // if gez, exception not in delay slot
move s8,sp // set address of trap frame
addu k1,k1,4 // compute address of exception
20: j KiBreakpointException // finish in breakpoint code
nop // fill delay slot
.set at
.set reorder
END_REGION(KiGeneralExceptionEndAddress)
.end KiGeneralException
SBTTL("Breakpoint Dispatch")
//++
//
// Routine Description:
//
// The following code is never executed. Its purpose is to allow the
// kernel debugger to walk call frames backwards through an exception,
// to support unwinding through exceptions for system services, and to
// support get/set user context.
//
//--
NESTED_ENTRY(KiBreakpointDispatch, TrapFrameLength, zero);
.set noreorder
.set noat
sw sp,TrIntSp(sp) // save stack pointer
sw ra,TrIntRa(sp) // save return address
sw ra,TrFir(sp) // save return address
sw s8,TrIntS8(sp) // save frame pointer
sw gp,TrIntGp(sp) // save general pointer
move s8,sp // set frame pointer
.set at
.set reorder
PROLOGUE_END
//++
//
// Routine Description:
//
// Control reaches here when a breakpoint exception code is read from the
// cause register. When this routine is entered, interrupts are disabled.
//
// The function of this routine is to raise a breakpoint exception.
//
// N.B. Integer register v1 is not usuable in the first instuction of the
// routine.
//
// Arguments:
//
// k0 - Supplies the current PSR with the EXL bit set.
// k1 - Supplies the address of the faulting instruction.
// gp - Supplies a pointer to the system short data area.
// s8 - Supplies a pointer to the trap frame.
//
// Return Value:
//
// None.
//
//--
ALTERNATE_ENTRY(KiBreakpointException)
GENERATE_TRAP_FRAME // save volatile machine state
addu a0,s8,TrExceptionRecord // compute exception record address
sw k1,ErExceptionAddress(a0) // save address of exception
lw t0,0(k1) // get actual breakpoint instruction
.set noreorder
.set noat
mfc0 k0,cause // get cause of exception
.set at
.set reorder
li t1,XCODE_BREAKPOINT // get exception code for breakpoint
li t2,STATUS_BREAKPOINT // set exception status code
and k0,k0,R4000_XCODE_MASK // isolate exception code
beq k0,t1,10f // if eq, breakpoint
move t2,k0 // set status to cause value
10: sw t0,ErExceptionInformation(a0) // save breakpoint instruction
sw t2,ErExceptionCode(a0) //
sw zero,ErExceptionFlags(a0) // set exception flags
sw zero,ErExceptionRecord(a0) // set associated record
sw zero,ErNumberParameters(a0) // set number of parameters
jal KiExceptionDispatch // join common code
b 10b // dummy
.end KiBreakpointDispatch
SBTTL("Exception Dispatch")
//++
//
// Routine Desription:
//
// Control is transfered to this routine to call the exception
// dispatcher to resolve an exception.
//
// Arguments:
//
// a0 - Supplies a pointer to an exception record.
//
// s8 - Supplies a pointer to a trap frame.
//
// Return Value:
//
// There is no return from this routine.
//
//--
NESTED_ENTRY(KiExceptionDispatch, ExceptionFrameLength, zero)
subu sp,sp,ExceptionFrameLength // allocate exception frame
sw ra,ExIntRa(sp) // save return address
sw s0,ExIntS0(sp) // save integer registers s0 - s7
sw s1,ExIntS1(sp) //
sw s2,ExIntS2(sp) //
sw s3,ExIntS3(sp) //
sw s4,ExIntS4(sp) //
sw s5,ExIntS5(sp) //
sw s6,ExIntS6(sp) //
sw s7,ExIntS7(sp) //
sdc1 f20,ExFltF20(sp) // save floating registers f20 - f31
sdc1 f22,ExFltF22(sp) //
sdc1 f24,ExFltF24(sp) //
sdc1 f26,ExFltF26(sp) //
sdc1 f28,ExFltF28(sp) //
sdc1 f30,ExFltF30(sp) //
PROLOGUE_END
//
// Call the exception dispatcher.
//
move a1,sp // set exception frame address
move a2,s8 // set trap frame address
move a3,zero // set previous processor mode
li t0,TRUE // set first chance TRUE
sw t0,ExArgs + (4 * 4)(sp) //
jal KiDispatchException // call exception dispatcher
//
// Restore the nonvolatile registers.
//
lw s0,ExIntS0(sp) // restore integer registers s0 - s7
lw s1,ExIntS1(sp) //
lw s2,ExIntS2(sp) //
lw s3,ExIntS3(sp) //
lw s4,ExIntS4(sp) //
lw s5,ExIntS5(sp) //
lw s6,ExIntS6(sp) //
lw s7,ExIntS7(sp) //
ldc1 f20,ExFltF20(sp) // restore floating registers f20 - f31
ldc1 f22,ExFltF22(sp) //
ldc1 f24,ExFltF24(sp) //
ldc1 f26,ExFltF26(sp) //
ldc1 f28,ExFltF28(sp) //
ldc1 f30,ExFltF30(sp) //
//
// Exit from the exception.
//
lw t0,TrPsr(s8) // get previous processor status
lw gp,TrIntGp(s8) // restore integer register gp
li t3,(1 << PSR_CU1) | (1 << PSR_EXL) // ****** r4000 errata
.set noreorder
.set noat
mtc0 t3,psr // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
mtc0 t0,psr // disable interrupts
nop // ****** r4000 errata
jal KiRestoreTrapFrame // restore volatile state
lw AT,TrIntAt(s8) // restore integer register at
move sp,s8 // trim stack to trap frame
la k0,SavedK1Address // get address of where to save k1
lw k1,(k0) // save firmware return address
lw k0,TrFir(sp) // get continuation address
lw s8,TrIntS8(sp) // restore integer register s8
lw ra,TrIntRa(sp) // restore return address
j k1 // return to firmware
lw sp,TrIntSp(sp) // restore stack pointer
.set at
.set reorder
.end KiExceptionDispatch
SBTTL("Fill Fixed Translation Buffer Entry")
//++
//
// VOID
// KeFillFixedEntryTb (
// IN HARDWARE_PTE Pte[],
// IN PVOID Virtual,
// IN ULONG Index
// )
//
// Routine Description:
//
// This function fills a fixed translation buffer entry.
//
// Arguments:
//
// Pte (a0) - Supplies a pointer to the page table entries that are to be
// written into the TB.
//
// Virtual (a1) - Supplies the virtual address of the entry that is to
// be filled in the translation buffer.
//
// Index (a2) - Supplies the index where the TB entry is to be written.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KeFillFixedEntryTb)
lw t0,0(a0) // get first PTE value
lw t1,4(a0) // get second PTE value
DISABLE_INTERRUPTS(t2) // disable interrupts
.set noreorder
.set noat
mfc0 t3,entryhi // get current PID and VPN2
srl a1,a1,ENTRYHI_VPN2 // isolate VPN2 of virtual address
sll a1,a1,ENTRYHI_VPN2 //
and t3,t3,0xff << ENTRYHI_PID // isolate current PID
or a1,t3,a1 // merge PID with VPN2 of virtual address
mtc0 a1,entryhi // set VPN2 and PID for probe
mtc0 t0,entrylo0 // set first PTE value
mtc0 t1,entrylo1 // set second PTE value
mtc0 a2,index // set TB entry index
nop // 1 cycle hazzard
tlbwi // overwrite indexed TB entry
nop // 3 cycle hazzard
.set at
.set reorder
ENABLE_INTERRUPTS(t2) // enable interrupts
j ra // return
.end KeFillFixedEntryTb
SBTTL("Flush Entire Translation Buffer")
//++
//
// VOID
// KiFlushEntireTb (
// )
//
// Routine Description:
//
// This function flushes the random part of the translation buffer.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiFlushEntireTb)
b KiFlushRandomTb // execute common code
.end KiFlushEntireTb
SBTTL("Flush Fixed Translation Buffer Entries")
//++
//
// VOID
// KiFlushFixedTb (
// )
//
// Routine Description:
//
// This function is called to flush all the fixed entries from the
// translation buffer.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiFlushFixedTb)
li t0,FIXED_BASE // set base index of fixed TB entries
li t3,FIXED_ENTRIES // set number of fixed TB entries
b KiFlushTb //
.end KiFlushFixedTb
SBTTL("Flush Random Translation Buffer Entries")
//++
//
// VOID
// KiFlushRandomTb (
// )
//
// Routine Description:
//
// This function is called to flush all the random entries from the TB.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiFlushRandomTb)
li t0,FIXED_ENTRIES // set base index of random TB entries
li t3,(48 - FIXED_ENTRIES) // set number of random TB entries
ALTERNATE_ENTRY(KiFlushTb)
li t4,KSEG0_BASE // set high part of TB entry
DISABLE_INTERRUPTS(t2) // disable interrupts
.set noreorder
.set noat
addu t3,t0,t3 // set index of highest entry + 1
sll t0,t0,INDEX_INDEX // shift starting index into position
sll t3,t3,INDEX_INDEX // shift ending index into position
mfc0 t1,entryhi // save contents of entryhi
mtc0 zero,entrylo0 // set low part of TB entry
mtc0 zero,entrylo1 //
mtc0 t4,entryhi //
mtc0 t0,index // set TB entry index
10: addu t0,t0,1 //
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
tlbwi // write TB entry
bne t0,t3,10b // if ne, more entries to flush
mtc0 t0,index // set TB entry index
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
mtc0 t1,entryhi // restore contents of entryhi
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
.set at
.set reorder
ENABLE_INTERRUPTS(t2) // enable interrupts
j ra // return
.end KiFlushRandomTb
SBTTL("Flush Single Translation Buffer Entry")
//++
//
// VOID
// KiFlushSingleTb (
// IN BOOLEAN Invalid,
// IN PVOID Virtual
// )
//
// Routine Description:
//
// This function flushes a single entry from the translation buffer.
//
// Arguments:
//
// Invalid (a0) - Supplies a boolean variable that determines the reason
// that the TB entry is being flushed.
//
// Virtual (a1) - Supplies the virtual address of the entry that is to
// be flushed from the translation buffer.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiFlushSingleTb)
DISABLE_INTERRUPTS(t0) // disable interrupts
.set noreorder
.set noat
srl t1,a1,ENTRYHI_VPN2 // clear all but VPN2 of virtual address
mfc0 t2,entryhi // get current PID and VPN2
sll t1,t1,ENTRYHI_VPN2 //
and t2,t2,0xff << ENTRYHI_PID // isolate current PID
or t1,t1,t2 // merge PID with VPN2 of virtual address
mtc0 t1,entryhi // set VPN2 and PID for probe
nop // 3 cycle hazzard
nop //
nop //
nop // ****** r4000 errata
nop // ****** r4000 errata
tlbp // probe for entry in TB
nop // 2 cycle hazzard
nop //
mfc0 t3,index // read result of probe
nop // 1 cycle hazzard
bltz t3,30f // if ltz, entry is not in TB
sll t1,a1,0x1f - (ENTRYHI_VPN2 - 1) // shift low bit of VPN into sign
bltzl t1,10f // if ltz, invalidate second PTE
mtc0 zero,entrylo1 // clear second PTE for flush
mtc0 zero,entrylo0 // clear first PTE for flush
10: nop // 1 cycle hazzard
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
nop // ****** r4000 errata
tlbwi // overwrite index TB entry
nop // 3 cycle hazzard
nop // ****** r4000 errata
nop // ****** r4000 errata
.set at
.set reorder
30: ENABLE_INTERRUPTS(t0) // enable interrupts
j ra // return
.end KiFlushSingleTb
SBTTL("Probe Tb Entry")
//++
//
// ULONG
// KiProbeEntryTb (
// IN PVOID VirtualAddress
// )
//
// Routine Description:
//
// This function is called to determine if a specified entry is valid
/// and within the fixed portion of the TB.
//
// Arguments:
//
// VirtualAddress - Supplies the virtual address to probe.
//
// Return Value:
//
// A value of TRUE is returned if the specified entry is valid and within
// the fixed part of the TB. Otherwise, a value of FALSE is returned.
//
//--
LEAF_ENTRY(KiProbeEntryTb)
DISABLE_INTERRUPTS(t0) // disable interrupts
.set noreorder
.set noat
srl t1,a0,ENTRYHI_VPN2 // clear all but VPN2 of virtual address
mfc0 t2,entryhi // get current PID and VPN2
sll t1,t1,ENTRYHI_VPN2 //
and t2,t2,0xff << ENTRYHI_PID // isolate current PID
or t1,t1,t2 // merge PID with VPN2 of virtual address
mtc0 t1,entryhi // set VPN2 and PID for probe
nop // 3 cycle hazzard
nop //
nop //
nop // ****** r4000 errata
nop // ****** r4000 errata
tlbp // probe for entry in TB
nop // 2 cycle hazzard
nop //
mfc0 t2,index // read result of probe
nop // 1 cycle hazzard
bltz t2,20f // if ltz, entry is not in TB
li v0,FALSE // set to return failure
tlbr // read entry from TB
nop // 3 cycle hazzard
nop //
nop //
nop // ****** r4000 errata
nop // ****** r4000 errata
sll t1,a0,0x1f - (ENTRYHI_VPN2 - 1) // shift low bit of VPN into sign
bltzl t1,10f // if ltz, check second PTE
mfc0 t1,entrylo1 // get second PTE for probe
mfc0 t1,entrylo0 // get first PTE for probe
10: nop // 1 cycle hazzard
sll t1,t1,0x1f - ENTRYLO_V // shift valid bit into sign position
bgez t1,20f // if geq, entry is not valid
srl t2,INDEX_INDEX // isolate index
and t2,t2,0x3f //
sltu v0,t2,FIXED_ENTRIES // check if entry in fixed part of TB
.set at
.set reorder
20: ENABLE_INTERRUPTS(t0) // enable interrupts
.end KiProbeEntryTb
SBTTL("Read Tb Entry")
//++
//
// VOID
// KiReadEntryTb (
// IN ULONG Index,
// OUT PULONG EntryLo[],
// OUT PULONG EntryHi
// )
//
// Routine Description:
//
// This function is called to read an entry from the TB.
//
// Arguments:
//
// Index - Supplies the index of the entry to read.
//
// entrylo - Supplies a pointer to a array that receives the first and
// second TB entry values.
//
// EntryHi - Supplies a pointer to a variable that receives the high
// part of the TB entry.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiReadEntryTb)
DISABLE_INTERRUPTS(t0) // disable interrupts
.set noreorder
.set noat
sll a0,INDEX_INDEX // shift index into position
mfc0 t1,entryhi // save entry high register
mtc0 a0,index // set TB entry index
nop //
nop // ****** r4000 errate
nop // ****** r4000 errate
nop // ****** r4000 errate
nop // ****** r4000 errate
tlbr // read entry from TB
nop // 3 cycle hazzard
nop //
nop //
nop // ****** r4000 errate
nop // ****** r4000 errate
mfc0 t2,entrylo0 // save first PTE value
mfc0 t3,entrylo1 // save second PTE value
mfc0 t4,entryhi // save entry high register
mtc0 t1,entryhi // restore entry high register
nop // ****** r4000 errate
nop // ****** r4000 errate
nop // ****** r4000 errate
nop // ****** r4000 errate
nop // ****** r4000 errate
.set at
.set reorder
ENABLE_INTERRUPTS(t0) // enable interrupts
sw t2,0(a1) // set first PTE value
sw t3,4(a1) // set second PTE value
sw t4,0(a2) // set entry high register value
j ra // return
.end KiReadEntryTb
SBTTL("Flush Write Buffer")
//++
//
// VOID
// KeFlushWriteBuffer (
// VOID
// )
//
// Routine Description:
//
// This function flushes the write buffer on the current processor.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KeFlushWriteBuffer)
j ra // return
.end KeFlushWritebuffer
//++
//
// BOOLEAN
// KiDisableInterrupts (
// VOID
// )
//
// Routine Description:
//
// This function disables interrupts and returns whether interrupts
// were previously enabled.
//
// Arguments:
//
// None.
//
// Return Value:
//
// A boolean value that determines whether interrupts were previously
// enabled (TRUE) or disabled(FALSE).
//
//--
LEAF_ENTRY(KiDisableInterrupts)
.set noreorder
.set noat
mfc0 t0,psr // get current processor status
li t1,~(1 << PSR_IE) // set interrupt enable mask
and t2,t1,t0 // clear interrupt enable
mtc0 t2,psr // disable interrupts
and v0,t0,1 << PSR_IE // iosolate current interrupt enable
srl v0,v0,PSR_IE //
.set at
.set reorder
j ra // return
.end KiDisableInterrupts
SBTTL("Restore Interrupts")
//++
//
// VOID
// KiRestoreInterrupts (
// IN BOOLEAN Enable
// )
//
// Routine Description:
//
// This function restores the interrupt enable that was returned by
// the disable interrupts function.
//
// Arguments:
//
// Enable (a0) - Supplies the interrupt enable value.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiRestoreInterrupts)
.set noreorder
.set noat
mfc0 t0,psr // get current processor status
sll t1,a0,PSR_IE // shift previous enable into position
or t1,t1,t0 // merge previous enable
mtc0 t1,psr // restore previous interrupt enable
nop //
.set at
.set reorder
j ra // return
.end KiRestoreInterrupts
SBTTL("Generate Trap Frame")
//++
//
// Routine Desription:
//
// This routine is called to save the volatile integer and floating
// registers in a trap frame.
//
// N.B. This routine uses a special argument passing mechanism and destroys
// no registers. It is assumed that integer register AT is saved by the
// caller.
//
// Arguments:
//
// s8 - Supplies a pointer to the base of an trap frame.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiGenerateTrapFrame)
sw v0,TrIntV0(s8) // save integer register v0
sw v1,TrIntV1(s8) // save integer register v1
mflo v1 // save lo integer register
sw v1,TrIntLo(s8) //
mfhi v1 // save hi integer register
sw v1,TrIntHi(s8) //
lw v1,TrIntV1(s8) // restore integer register v1
sw a0,TrIntA0(s8) // save integer registers a0 - a3
sw a1,TrIntA1(s8) //
sw a2,TrIntA2(s8) //
sw a3,TrIntA3(s8) //
sw t0,TrIntT0(s8) // save integer registers t0 - t9
sw t1,TrIntT1(s8) //
sw t2,TrIntT2(s8) //
sw t3,TrIntT3(s8) //
sw t4,TrIntT4(s8) //
sw t5,TrIntT5(s8) //
sw t6,TrIntT6(s8) //
sw t7,TrIntT7(s8) //
sw t8,TrIntT8(s8) //
sw t9,TrIntT9(s8) //
#if defined(R3000)
swc1 f0,TrFltF0(s8) // save floating register f0
#endif
#if defined(R4000)
sdc1 f0,TrFltF0(s8) // save floating register f0
#endif
b KiSaveVolatileFloatState // save remainder of state
.end KiGenerateTrapFrame
SBTTL("Restore Trap Frame")
//++
//
// Routine Description:
//
// This routine is called to restore the volatile integer and floating
// registers from a trap frame.
//
// N.B. This routine uses a special argument passing mechanism and destroys
// no registers. It is assumed that integer register AT is restored by
// the caller.
//
// Arguments:
//
// sp - Supplies a pointer to an exception frame.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiRestoreTrapFrame)
lw v0,TrIntV0(s8) // restore integer register v0
lw v1,TrIntV1(s8) // restore integer register v1
lw a0,TrIntA0(s8) // restore integer registers a0 - a3
lw a1,TrIntA1(s8) //
lw a2,TrIntA2(s8) //
lw a3,TrIntA3(s8) //
lw t0,TrIntLo(s8) // restore lo and hi integer registers
lw t1,TrIntHi(s8) //
mtlo t0 //
mthi t1 //
lw t0,TrIntT0(s8) // restore integer registers t0 - t9
lw t1,TrIntT1(s8) //
lw t2,TrIntT2(s8) //
lw t3,TrIntT3(s8) //
lw t4,TrIntT4(s8) //
lw t5,TrIntT5(s8) //
lw t6,TrIntT6(s8) //
lw t7,TrIntT7(s8) //
lw t8,TrIntT8(s8) //
lw t9,TrIntT9(s8) //
#if defined(R3000)
lwc1 f0,TrFltF0(s8) // restore floating register f0
#endif
#if defined(R4000)
ldc1 f0,TrFltF0(s8) // restore floating register f0
#endif
b KiRestoreVolatileFloatState // restore remainder of state
.end KiRestoreTrapFrame
SBTTL("Save Volatile Floating Registers")
//++
//
// Routine Desription:
//
// This routine is called to save the volatile floating registers.
//
// N.B. This routine uses a special argument passing mechanism and destroys
// no registers. It is assumed that floating register f0 is saved by the
// caller.
//
// Arguments:
//
// s8 - Supplies a pointer to a trap frame.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiSaveVolatileFloatState)
#if defined(R3000)
swc1 f1,TrFltF1(s8) // save floating register f1 - f19
swc1 f2,TrFltF2(s8) //
swc1 f3,TrFltF3(s8) //
swc1 f4,TrFltF4(s8) //
swc1 f5,TrFltF5(s8) //
swc1 f6,TrFltF6(s8) //
swc1 f7,TrFltF7(s8) //
swc1 f8,TrFltF8(s8) //
swc1 f9,TrFltF9(s8) //
swc1 f10,TrFltF10(s8) //
swc1 f11,TrFltF11(s8) //
swc1 f12,TrFltF12(s8) //
swc1 f13,TrFltF13(s8) //
swc1 f14,TrFltF14(s8) //
swc1 f15,TrFltF15(s8) //
swc1 f16,TrFltF16(s8) //
swc1 f17,TrFltF17(s8) //
swc1 f18,TrFltF18(s8) //
swc1 f19,TrFltF19(s8) //
#endif
#if defined(R4000)
sdc1 f2,TrFltF2(s8) // save floating register f2 - f19
sdc1 f4,TrFltF4(s8) //
sdc1 f6,TrFltF6(s8) //
sdc1 f8,TrFltF8(s8) //
sdc1 f10,TrFltF10(s8) //
sdc1 f12,TrFltF12(s8) //
sdc1 f14,TrFltF14(s8) //
sdc1 f16,TrFltF16(s8) //
sdc1 f18,TrFltF18(s8) //
#endif
j ra // return
.end KiSaveVolatileFloatState)
SBTTL("Restore Volatile Floating Registers")
//++
//
// Routine Desription:
//
// This routine is called to restore the volatile floating registers.
//
// N.B. This routine uses a special argument passing mechanism and destroys
// no registers. It is assumed that floating register f0 is restored by
// the caller.
//
// Arguments:
//
// s8 - Supplies a pointer to a trap frame.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(KiRestoreVolatileFloatState)
#if defined(R3000)
lwc1 f1,TrFltF1(s8) // restore floating registers f1 - f19
lwc1 f2,TrFltF2(s8) //
lwc1 f3,TrFltF3(s8) //
lwc1 f4,TrFltF4(s8) //
lwc1 f5,TrFltF5(s8) //
lwc1 f6,TrFltF6(s8) //
lwc1 f7,TrFltF7(s8) //
lwc1 f8,TrFltF8(s8) //
lwc1 f9,TrFltF9(s8) //
lwc1 f10,TrFltF10(s8) //
lwc1 f11,TrFltF11(s8) //
lwc1 f12,TrFltF12(s8) //
lwc1 f13,TrFltF13(s8) //
lwc1 f14,TrFltF14(s8) //
lwc1 f15,TrFltF15(s8) //
lwc1 f16,TrFltF16(s8) //
lwc1 f17,TrFltF17(s8) //
lwc1 f18,TrFltF18(s8) //
lwc1 f19,TrFltF19(s8) //
#endif
#if defined(R4000)
ldc1 f2,TrFltF2(s8) // restore floating registers f2 - f19
ldc1 f4,TrFltF4(s8) //
ldc1 f6,TrFltF6(s8) //
ldc1 f8,TrFltF8(s8) //
ldc1 f10,TrFltF10(s8) //
ldc1 f12,TrFltF12(s8) //
ldc1 f14,TrFltF14(s8) //
ldc1 f16,TrFltF16(s8) //
ldc1 f18,TrFltF18(s8) //
#endif
j ra // return
.end KiRestoreVolatileFloatState
#endif
|