]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
8f6c56a5 | 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
1c79356b | 5 | * |
8f6c56a5 A |
6 | * This file contains Original Code and/or Modifications of Original Code |
7 | * as defined in and that are subject to the Apple Public Source License | |
8 | * Version 2.0 (the 'License'). You may not use this file except in | |
9 | * compliance with the License. The rights granted to you under the License | |
10 | * may not be used to create, or enable the creation or redistribution of, | |
11 | * unlawful or unlicensed copies of an Apple operating system, or to | |
12 | * circumvent, violate, or enable the circumvention or violation of, any | |
13 | * terms of an Apple operating system software license agreement. | |
14 | * | |
15 | * Please obtain a copy of the License at | |
16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. | |
17 | * | |
18 | * The Original Code and all software distributed under the License are | |
19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
23 | * Please see the License for the specific language governing rights and | |
8ad349bb | 24 | * limitations under the License. |
8f6c56a5 A |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ | |
1c79356b A |
27 | */ |
28 | #include <ppc/asm.h> | |
29 | #include <ppc/proc_reg.h> | |
30 | #include <ppc/exception.h> | |
31 | #include <mach/ppc/vm_param.h> | |
32 | #include <assym.s> | |
33 | ||
34 | /* | |
35 | * Classic atomic switch and fast trap code | |
36 | * Written by: Mark Gorlinsky | |
37 | */ | |
38 | ||
39 | /* | |
40 | ** | |
41 | ** Blue Box Fast Trap entry | |
42 | ** | |
43 | ** | |
44 | ** The registers at entry are as hw_exceptions left them. Which means | |
45 | ** that the Blue Box data area is pointed to be R26. | |
46 | ** | |
47 | ** We exit here through the fast path exit point in hw_exceptions. That means that | |
48 | ** upon exit, R4 must not change. It is the savearea with the current user context | |
49 | ** to restore. | |
50 | ** | |
51 | ** Input registers are: | |
52 | ** r0 = Syscall number | |
53 | ** r4 = Current context savearea (do not modify) | |
54 | ** r13 = THREAD_TOP_ACT pointer | |
55 | ** r26 = base of ACT_MACH_BDA in kernel address space | |
56 | ** -- for Traps -- | |
57 | ** r24 = Index into TWI table (x4) | |
58 | ** | |
59 | ** | |
60 | */ | |
61 | ||
62 | ||
63 | ENTRY(atomic_switch_syscall, TAG_NO_FRAME_USED) | |
64 | ||
65 | /* | |
0b4e3aa0 A |
66 | * Note: the BlueBox fast path system calls (-1 and -2) we handled as |
67 | * an ultra-fast trap in lowmem_vectors. | |
1c79356b | 68 | */ |
55e303ae | 69 | lwz r5,bbSysCall(r13) ; Pick up the syscall vector |
1c79356b A |
70 | b .L_CallPseudoKernel |
71 | ||
72 | ENTRY(atomic_switch_trap, TAG_NO_FRAME_USED) | |
73 | ||
74 | /* | |
75 | ** functions 0-15 -> Call PseudoKernel | |
76 | ** 16 -> Exit PseudoKernel | |
77 | */ | |
78 | ||
79 | cmplwi cr7,r24,BB_RFI_TRAP ; Is this an RFI? | |
80 | beq cr7,.L_ExitPseudoKernel ; Yes... | |
81 | ||
55e303ae | 82 | lwz r5,bbTrap(r13) ; Pick up the trap vector |
1c79356b A |
83 | |
84 | /****************************************************************************** | |
85 | * void CallPseudoKernel ( int vector, thread_act_t * act, BEDA_t * beda, savearea *sv ) | |
86 | * | |
87 | * This op provides a means of invoking the BlueBox PseudoKernel from a | |
88 | * system (68k) or native (PPC) context while changing BlueBox interruption | |
89 | * state atomically. As an added bonus, this op leaves all but R1/PC of the user | |
90 | * state registers intact. R1/PC are saved in a per thread save area, the base of | |
91 | * which is located in the bbDescAddr member of the thread_act structure. | |
92 | * | |
93 | * This op is invoked from the Emulator Trap dispatch table or from a System | |
94 | * Call when Mach SCs have been disabled. A vectorindex is passed in to indicate | |
95 | * which vector should be taken. | |
96 | * | |
97 | * If this op is invoked from the Emulator Trap dispatch table, the kernel is | |
98 | * aware of starting address of this table. It used the users PC (SRR0) | |
99 | * and the start of the Trap dispatch table address to verify the trap exception | |
100 | * as a atomic_switch trap. If a trap exception is verified as a atomic_switch | |
101 | * trap we enter here with the following registers loaded. | |
102 | * | |
103 | * Input registers are: | |
104 | * r5 = Vector to take | |
105 | * r13 = Current thread context data | |
106 | * r26 = Base address of BlueBox exception data area in kernel address space | |
107 | * r4 = Current context savearea (do not modify) | |
108 | * | |
109 | ******************************************************************************/ | |
110 | ||
111 | .L_CallPseudoKernel: | |
112 | ||
91447636 A |
113 | mfsprg r2,1 ; Get the current activation |
114 | lwz r2,ACT_PER_PROC(r2) ; Get the per_proc block | |
1c79356b A |
115 | rlwinm r6,r26,0,0,19 ; Start of page is bttd |
116 | lwz r7,ACT_MACT_SPF(r13) ; Get special flags | |
117 | lwz r1,BTTD_INTERRUPT_VECTOR(r6) ; Get interrupt vector | |
118 | rlwinm r7,r7,0,bbNoMachSCbit+1,bbNoMachSCbit-1 | |
119 | ; Reactivate Mach SCs | |
120 | lwz r8,BTTD_INTCONTROLWORD(r6) ; Get Interrupt Control Word | |
121 | cmpwi r1,0 ; Is this a preemptive thread ? | |
122 | stw r7,ACT_MACT_SPF(r13) ; Update special flags | |
0b4e3aa0 | 123 | stw r7,spcFlags(r2) ; Update per_proc version |
1c79356b A |
124 | beq .L_CallFromPreemptiveThread ; No int vector means preemptive thread |
125 | ||
126 | rlwinm r1,r8,0,INTSTATEMASK_B,INTSTATEMASK_E | |
127 | ; Extract current Interrupt state | |
128 | rlwinm r8,r8,0,INTSTATEMASK_E+1,INTSTATEMASK_B-1 | |
129 | ; Clear current interrupt state | |
130 | xoris r2,r1,SYSCONTEXTSTATE ; Setup for System Context check | |
131 | lwz r1,savecr(r4) ; Load current CR bits | |
132 | cmpwi r2,0 ; Check if state is System Context? | |
133 | oris r8,r8,PSEUDOKERNELSTATE ; Update state for entering the PK | |
134 | bne .L_CallFromAlternateContext ; No, then do not save CR2 bits | |
135 | ||
136 | rlwimi r8,r1,32-INTCR2TOBACKUPSHIFT,INTBACKUPCR2MASK_B,INTBACKUPCR2MASK_E | |
137 | ; Insert live CR2 in ICW BackupCR2 | |
138 | .L_CallFromAlternateContext: | |
139 | ||
140 | stw r8,BTTD_INTCONTROLWORD(r6) ; Update ICW | |
141 | ||
142 | .L_CallFromPreemptiveThread: | |
143 | ||
55e303ae A |
144 | lwz r1,savesrr0+4(r4) ; Get current PC |
145 | lwz r2,saver1+4(r4) ; Get current R1 | |
146 | lwz r3,savesrr1+4(r4) ; Get current MSR | |
1c79356b A |
147 | stw r1,BEDA_SRR0(r26) ; Save current PC |
148 | rlwinm r3,r3,0,MSR_BE_BIT+1,MSR_SE_BIT-1 | |
149 | ; Clear SE|BE bits in MSR | |
150 | stw r2,BEDA_SPRG1(r26) ; Save current R1 | |
55e303ae | 151 | stw r3,savesrr1+4(r4) ; Load new MSR |
1c79356b A |
152 | |
153 | lwz r1,BEDA_SPRG0(r26) ; Get replacement R1 | |
55e303ae | 154 | stw r5,savesrr0+4(r4) ; Save vector as PC |
1c79356b | 155 | stw r3,BEDA_SRR1(r26) ; Update saved MSR |
55e303ae | 156 | stw r1,saver1+4(r4) ; Load up new R1 |
1c79356b A |
157 | |
158 | b EXT(fastexit) ; Go back and take the fast path exit... | |
159 | ||
160 | /****************************************************************************** | |
161 | * void ExitPseudoKernel ( thread_act_t * act, BEDA_t * beda, savearea * sv ) | |
162 | * | |
163 | * This op provides a means of exiting from the BlueBox PseudoKernel to a | |
164 | * user context. This op attempts to simulate an RFI for the returning | |
165 | * Traps (atomic_switch_trap) and SysCalls (atomic_switch_syscall). Only the | |
166 | * Blue Thread handling interrupts is allowed to atomically change | |
167 | * interruption state and handle pending interrupts. | |
168 | * | |
169 | * If an interrupt is pending and we are returning to the alternate context, | |
170 | * the exit is aborted and we return to an pending interrupt handler in the | |
171 | * Blue Box pseudokernel. | |
172 | * | |
173 | * It also allows the MSR's FE0, FE1, BE and SE bits to updated for the user | |
174 | * and completes the PPC register loading. | |
175 | * | |
176 | * Input registers are: | |
177 | * r4 = Current context savearea (do not modify) | |
178 | * r13 = Pointer to the current active thread's data | |
179 | * r26 = Base address of BlueBox Data in kernel address space | |
180 | * | |
181 | ******************************************************************************/ | |
182 | ||
183 | .L_ExitPseudoKernel: | |
184 | ||
185 | rlwinm r6,r26,0,0,19 ; Start of page is bttd | |
186 | lwz r7,ACT_MACT_SPF(r13) ; Get special flags | |
187 | lwz r2,BTTD_INTERRUPT_VECTOR(r6) ; Get the interrupt vector | |
188 | lwz r1,BEDA_SPRG1(r26) ; Get saved CTR | |
0b4e3aa0 | 189 | ori r7,r7,(0x8000 >> (bbNoMachSCbit - 16)) ; Disable Mach SCs for Blue Box |
1c79356b A |
190 | |
191 | cmpwi r2,0 ; Is this a preemptive thread | |
55e303ae | 192 | stw r1,savectr+4(r4) ; Update CTR |
1c79356b A |
193 | beq .L_ExitFromPreemptiveThread |
194 | ||
195 | lwz r8,BTTD_INTCONTROLWORD(r6) ; Get ICW | |
196 | lwz r1,BTTD_NEWEXITSTATE(r6) ; New interrupt state | |
197 | lwz r2,BTTD_TESTINTMASK(r6) ; Get pending interrupt mask | |
198 | lis r3,SYSCONTEXTSTATE ; Setup for check in system context | |
199 | rlwimi r8,r1,0,INTSTATEMASK_B,INTSTATEMASK_E | |
200 | ; Insert new state | |
201 | cmplw cr1,r1,r3 ; System context ? | |
202 | and. r2,r8,r2 ; Any pending interrupt? | |
203 | lwz r1,savecr(r4) ; Get current CR | |
204 | ||
205 | beq cr1,.L_ExitToSystemContext ; We are in system context | |
206 | beq .L_ExitUpdateRuptControlWord ; We do not have a pending interrupt | |
207 | ||
55e303ae | 208 | lwz r2,saver1+4(r4) ; Get current R1 |
1c79356b A |
209 | lwz r1,BEDA_SPRG0(r26) ; Get replacement R1 |
210 | stw r2,BEDA_SPRG1(r26) ; Save current R1 | |
55e303ae A |
211 | stw r1,saver1+4(r4) ; Load up new R1 |
212 | lwz r3,bbPending(r13) ; Get pending interrupt PC | |
1c79356b A |
213 | b .L_ExitAbortExit ; Abort and Exit |
214 | ||
215 | .L_ExitToSystemContext: | |
216 | rlwimi r1,r8,INTCR2TOBACKUPSHIFT,INTCR2MASK_B,INTCR2MASK_E | |
217 | ; Insert live CR2 into backup CR2 | |
218 | .L_ExitUpdateRuptControlWord: | |
219 | stw r8,BTTD_INTCONTROLWORD(r6) ; Update ICW | |
220 | stw r1,savecr(r4) ; Update CR | |
221 | ||
222 | .L_ExitFromPreemptiveThread: | |
91447636 A |
223 | mfsprg r3,1 ; Get the current activation |
224 | lwz r3,ACT_PER_PROC(r3) ; Get the per_proc block | |
55e303ae | 225 | lwz r2,savesrr1+4(r4) ; Get current MSR |
1c79356b A |
226 | lwz r1,BEDA_SRR1(r26) ; Get new MSR |
227 | stw r7,ACT_MACT_SPF(r13) ; Update special flags | |
0b4e3aa0 | 228 | stw r7,spcFlags(r3) ; Update per_proc version |
1c79356b A |
229 | rlwimi r2,r1,0,MSR_FE0_BIT,MSR_FE1_BIT |
230 | ; Insert FE0,FE1,SE,BE bits | |
231 | lwz r3,BEDA_SRR0(r26) ; Get new PC | |
55e303ae | 232 | stw r2,savesrr1+4(r4) ; Update MSR |
1c79356b A |
233 | |
234 | .L_ExitAbortExit: | |
55e303ae | 235 | stw r3,savesrr0+4(r4) ; Update PC |
1c79356b A |
236 | |
237 | b EXT(fastexit) ; Go back and take the fast path exit... | |
238 |