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