The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/ppc/atomic_switch.s

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: cf419f9b3fbe33692b2a3b55e53c4190


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.