/*
* Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* "License"). You may not use this file except in compliance with the
* License. Please obtain a copy of the License at
* http://www.apple.com/publicsource and read it before using this file.
*
* This Original Code and all software distributed under the License are
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#include <ppc/asm.h>
#include <ppc/proc_reg.h>
#include <ppc/exception.h>
#include <mach/ppc/vm_param.h>
#include <assym.s>
/*
* Classic atomic switch and fast trap code
* Written by: Mark Gorlinsky
*/
/*
**
** Blue Box Fast Trap entry
**
**
** The registers at entry are as hw_exceptions left them. Which means
** that the Blue Box data area is pointed to be R26.
**
** We exit here through the fast path exit point in hw_exceptions. That means that
** upon exit, R4 must not change. It is the savearea with the current user context
** to restore.
**
** Input registers are:
** r0 = Syscall number
** r4 = Current context savearea (do not modify)
** r13 = THREAD_TOP_ACT pointer
** r26 = base of ACT_MACH_BDA in kernel address space
** -- for Traps --
** r24 = Index into TWI table (x4)
**
**
*/
ENTRY(atomic_switch_syscall, TAG_NO_FRAME_USED)
/*
* Note: the BlueBox fast path system calls (-1 and -2) we handled as
* an ultra-fast trap in lowmem_vectors.
*/
li r5, BTTD_SYSCALL_VECTOR
b .L_CallPseudoKernel
ENTRY(atomic_switch_trap, TAG_NO_FRAME_USED)
/*
** functions 0-15 -> Call PseudoKernel
** 16 -> Exit PseudoKernel
*/
cmplwi cr7,r24,BB_RFI_TRAP
li r5, BTTD_TRAP_VECTOR
/******************************************************************************
* void CallPseudoKernel ( int vector, thread_act_t * act, BEDA_t * beda, savearea *sv )
*
* This op provides a means of invoking the BlueBox PseudoKernel from a
* system (68k) or native (PPC) context while changing BlueBox interruption
* state atomically. As an added bonus, this op leaves all but R1/PC of the user
* state registers intact. R1/PC are saved in a per thread save area, the base of
* which is located in the bbDescAddr member of the thread_act structure.
*
* This op is invoked from the Emulator Trap dispatch table or from a System
* Call when Mach SCs have been disabled. A vectorindex is passed in to indicate
* which vector should be taken.
*
* If this op is invoked from the Emulator Trap dispatch table, the kernel is
* aware of starting address of this table. It used the users PC (SRR0)
* and the start of the Trap dispatch table address to verify the trap exception
* as a atomic_switch trap. If a trap exception is verified as a atomic_switch
* trap we enter here with the following registers loaded.
*
* Input registers are:
* r5 = Vector to take
* r13 = Current thread context data
* r26 = Base address of BlueBox exception data area in kernel address space
* r4 = Current context savearea (do not modify)
*
******************************************************************************/
.L_CallPseudoKernel:
mfsprg r2,0 lwz r7,ACT_MACT_SPF(r13) rlwinm r7,r7,0,bbNoMachSCbit+1,bbNoMachSCbit-1
cmpwi r1,0 stw r7,spcFlags(r2)
rlwinm r1,r8,0,INTSTATEMASK_B,INTSTATEMASK_E
lwz r1,savecr(r4) oris r8,r8,PSEUDOKERNELSTATE
rlwimi r8,r1,32-INTCR2TOBACKUPSHIFT,INTBACKUPCR2MASK_B,INTBACKUPCR2MASK_E
stw r8,BTTD_INTCONTROLWORD(r6) .L_CallFromPreemptiveThread:
lwz r1,savesrr0(r4) lwz r3,savesrr1(r4) rlwinm r3,r3,0,MSR_BE_BIT+1,MSR_SE_BIT-1
stw r3,savesrr1(r4) lwz r1,BEDA_SPRG0(r26) stw r3,BEDA_SRR1(r26) stw r2,savesrr0(r4) b EXT(fastexit) /******************************************************************************
* void ExitPseudoKernel ( thread_act_t * act, BEDA_t * beda, savearea * sv )
*
* This op provides a means of exiting from the BlueBox PseudoKernel to a
* user context. This op attempts to simulate an RFI for the returning
* Traps (atomic_switch_trap) and SysCalls (atomic_switch_syscall). Only the
* Blue Thread handling interrupts is allowed to atomically change
* interruption state and handle pending interrupts.
*
* If an interrupt is pending and we are returning to the alternate context,
* the exit is aborted and we return to an pending interrupt handler in the
* Blue Box pseudokernel.
*
* It also allows the MSR's FE0, FE1, BE and SE bits to updated for the user
* and completes the PPC register loading.
*
* Input registers are:
* r4 = Current context savearea (do not modify)
* r13 = Pointer to the current active thread's data
* r26 = Base address of BlueBox Data in kernel address space
*
******************************************************************************/
.L_ExitPseudoKernel:
rlwinm r6,r26,0,0,19 lwz r2,BTTD_INTERRUPT_VECTOR(r6) ori r7,r7,(0x8000 >> (bbNoMachSCbit - 16)) cmpwi r2,0 beq .L_ExitFromPreemptiveThread
lwz r8,BTTD_INTCONTROLWORD(r6) lwz r2,BTTD_TESTINTMASK(r6) rlwimi r8,r1,0,INTSTATEMASK_B,INTSTATEMASK_E
and. r2,r8,r2
beq cr1,.L_ExitToSystemContext
lwz r2,saver1(r4) stw r2,BEDA_SPRG1(r26) lwz r3,BTTD_PENDINGINT_VECTOR(r6)
.L_ExitToSystemContext:
rlwimi r1,r8,INTCR2TOBACKUPSHIFT,INTCR2MASK_B,INTCR2MASK_E
stw r8,BTTD_INTCONTROLWORD(r6)
.L_ExitFromPreemptiveThread:
mfsprg r3,0 lwz r1,BEDA_SRR1(r26) stw r7,spcFlags(r3) stw r2,savesrr1(r4) .L_ExitAbortExit:
stw r3,savesrr0(r4) b EXT(fastexit)