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/machine_routines_asm.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  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 #include <ppc/asm.h>
   26 #include <ppc/proc_reg.h>
   27 #include <cpus.h>
   28 #include <assym.s>
   29 #include <debug.h>
   30 #include <mach/ppc/vm_param.h>
   31 #include <ppc/exception.h>
   32         
   33     
   34 /*
   35  * ml_set_physical()                    -- turn off DR and (if 64-bit) turn SF on
   36  *                                                                 it is assumed that pf64Bit is already in cr6
   37  * ml_set_physical_get_ffs()    -- turn DR off, SF on, and get feature flags 
   38  * ml_set_physical_disabled()   -- turn DR and EE off, SF on, get feature flags
   39  * ml_set_translation_off()             -- turn DR, IR, and EE off, SF on, get feature flags
   40  *
   41  * Callable only from assembler, these return:
   42  *       r2 -- new MSR
   43  *      r11 -- old MSR
   44  *      r10 -- feature flags (pf64Bit etc, ie SPRG 2)
   45  *      cr6 -- feature flags 24-27, ie pf64Bit, pf128Byte, and pf32Byte
   46  *
   47  * Uses r0 and r2.  ml_set_translation_off also uses r3 and cr5.
   48  */
   49 
   50         .align  4
   51         .globl  EXT(ml_set_translation_off)
   52 LEXT(ml_set_translation_off)
   53         mfsprg  r10,2                                           // get feature flags
   54         li              r0,0                                            ; Clear this
   55         mtcrf   0x02,r10                                        // move pf64Bit etc to cr6
   56         ori             r0,r0,lo16(MASK(MSR_EE)+MASK(MSR_FP)+MASK(MSR_IR)+MASK(MSR_DR)) // turn off all 4
   57         mfmsr   r11                                                     // get MSR
   58                 oris    r0,r0,hi16(MASK(MSR_VEC))       // Turn off vector too
   59         mtcrf   0x04,r10                                        // move pfNoMSRir etc to cr5
   60         andc    r2,r11,r0                                       // turn off EE, IR, and DR
   61         bt++    pf64Bitb,ml_set_physical_64     // skip if 64-bit (only they take the hint)
   62         bf              pfNoMSRirb,ml_set_physical_32   // skip if we can load MSR directly
   63         li              r0,loadMSR                                      // Get the MSR setter SC
   64         mr              r3,r2                                           // copy new MSR to r2
   65         sc                                                                      // Set it
   66         blr
   67         
   68                 .align  4
   69                 .globl  EXT(ml_set_physical_disabled)
   70 
   71 LEXT(ml_set_physical_disabled)
   72                 li              r0,0                                            ; Clear
   73         mfsprg  r10,2                                           // get feature flags
   74         ori             r0,r0,lo16(MASK(MSR_EE))        // turn EE and fp off
   75         mtcrf   0x02,r10                                        // move pf64Bit etc to cr6
   76         b               ml_set_physical_join
   77 
   78                 .align  5
   79                 .globl  EXT(ml_set_physical_get_ffs)
   80 
   81 LEXT(ml_set_physical_get_ffs)
   82         mfsprg  r10,2                                           // get feature flags
   83         mtcrf   0x02,r10                                        // move pf64Bit etc to cr6
   84 
   85                 .globl  EXT(ml_set_physical)
   86 LEXT(ml_set_physical)
   87 
   88         li              r0,0                                            // do not turn off interrupts
   89 
   90 ml_set_physical_join:
   91                 oris    r0,r0,hi16(MASK(MSR_VEC))       // Always gonna turn of vectors
   92         mfmsr   r11                                                     // get MSR
   93         ori             r0,r0,lo16(MASK(MSR_DR)+MASK(MSR_FP))   // always turn off DR and FP bit
   94         andc    r2,r11,r0                                       // turn off DR and maybe EE
   95         bt++    pf64Bitb,ml_set_physical_64     // skip if 64-bit (only they take the hint)
   96 ml_set_physical_32:
   97         mtmsr   r2                                                      // turn off translation
   98         isync
   99         blr
  100         
  101 ml_set_physical_64:
  102         li              r0,1                                            // get a 1 to slam into SF
  103         rldimi  r2,r0,63,MSR_SF_BIT                     // set SF bit (bit 0)
  104         mtmsrd  r2                                                      // set 64-bit mode, turn off data relocation
  105         isync                                                           // synchronize
  106         blr
  107     
  108 
  109 /*
  110  * ml_restore(old_MSR)
  111  *
  112  * Callable only from assembler, restores the MSR in r11 saved by ml_set_physical.
  113  * We assume cr6 and r11 are as set by ml_set_physical, ie:
  114  *      cr6 - pf64Bit flag (feature flags 24-27)
  115  *      r11 - old MSR
  116  */
  117  
  118                 .align  5
  119                 .globl  EXT(ml_restore)
  120 
  121 LEXT(ml_restore)
  122         bt++    pf64Bitb,ml_restore_64          // handle 64-bit cpus (only they take the hint)
  123         mtmsr   r11                                                     // restore a 32-bit MSR
  124         isync
  125         blr
  126         
  127 ml_restore_64:
  128         mtmsrd  r11                                                     // restore a 64-bit MSR
  129         isync
  130         blr
  131 
  132     
  133 /* PCI config cycle probing
  134  *
  135  *      boolean_t ml_probe_read(vm_offset_t paddr, unsigned int *val)
  136  *
  137  *      Read the memory location at physical address paddr.
  138  *  This is a part of a device probe, so there is a good chance we will
  139  *  have a machine check here. So we have to be able to handle that.
  140  *  We assume that machine checks are enabled both in MSR and HIDs
  141  */
  142 
  143 ;                       Force a line boundry here
  144                         .align  5
  145                         .globl  EXT(ml_probe_read)
  146 
  147 LEXT(ml_probe_read)
  148 
  149                         mfsprg  r9,2                                                    ; Get feature flags
  150                         
  151                         rlwinm. r0,r9,0,pf64Bitb,pf64Bitb               ; Are we on a 64-bit machine?
  152                         rlwinm  r3,r3,0,0,31                                    ; Clean up for 64-bit machines
  153                         bne++   mpr64bit                                                ; Go do this the 64-bit way...
  154 
  155 mpr32bit:       lis             r8,hi16(MASK(MSR_VEC))                  ; Get the vector flag
  156                         mfmsr   r0                                                              ; Save the current MSR
  157                         ori             r8,r8,lo16(MASK(MSR_FP))                ; Add the FP flag
  158 
  159                         neg             r10,r3                                                  ; Number of bytes to end of page
  160                         andc    r0,r0,r8                                                ; Clear VEC and FP
  161                         rlwinm. r10,r10,0,20,31                                 ; Clear excess junk and test for page bndry
  162                         ori             r8,r8,lo16(MASK(MSR_EE)|MASK(MSR_IR)|MASK(MSR_DR))              ; Drop EE, IR, and DR
  163                         mr              r12,r3                                                  ; Save the load address
  164                         andc    r2,r0,r8                                                ; Clear VEC, FP, and EE
  165                         mtcrf   0x04,r9                                                 ; Set the features                      
  166                         cmplwi  cr1,r10,4                                               ; At least 4 bytes left in page?
  167                         beq-    mprdoit                                                 ; We are right on the boundary...
  168                         li              r3,0
  169                         bltlr-  cr1                                                             ; No, just return failure...
  170 
  171 mprdoit:
  172 
  173                         bt              pfNoMSRirb,mprNoMSR                             ; No MSR...
  174 
  175                         mtmsr   r2                                                              ; Translation and all off
  176                         isync                                                                   ; Toss prefetch
  177                         b               mprNoMSRx
  178                         
  179 mprNoMSR:       
  180                         mr              r5,r0
  181                         li              r0,loadMSR                                              ; Get the MSR setter SC
  182                         mr              r3,r2                                                   ; Get new MSR
  183                         sc                                                                              ; Set it
  184                         mr              r0,r5
  185                         li              r3,0
  186 mprNoMSRx:
  187 
  188                         mfspr           r6, hid0                                        ; Get a copy of hid0
  189                         
  190                         rlwinm.         r5, r9, 0, pfNoMuMMCKb, pfNoMuMMCKb             ; Check for NoMuMMCK
  191                         bne             mprNoMuM
  192                         
  193                         rlwinm          r5, r6, 0, ice+1, ice-1                         ; Turn off L1 I-Cache
  194                         mtspr           hid0, r5
  195                         isync                                                           ; Wait for I-Cache off
  196                         rlwinm          r5, r6, 0, mum+1, mum-1                         ; Turn off MuM w/ I-Cache on
  197                         mtspr           hid0, r5
  198 mprNoMuM:
  199 
  200 ;
  201 ;                       We need to insure that there is no more than 1 BAT register that
  202 ;                       can get a hit. There could be repercussions beyond the ken
  203 ;                       of mortal man. It is best not to tempt fate.
  204 ;
  205 
  206 ;                       Note: we will reload these from the shadow BATs later
  207 
  208                         li              r10,0                                                   ; Clear a register
  209                         
  210                         sync                                                                    ; Make sure all is well
  211 
  212                         mtdbatu 1,r10                                                   ; Invalidate DBAT 1 
  213                         mtdbatu 2,r10                                                   ; Invalidate DBAT 2 
  214                         mtdbatu 3,r10                                                   ; Invalidate DBAT 3  
  215                         
  216                         rlwinm  r10,r12,0,0,14                                  ; Round down to a 128k boundary
  217                         ori             r11,r10,0x32                                    ; Set uncached, coherent, R/W
  218                         ori             r10,r10,2                                               ; Make the upper half (128k, valid supervisor)
  219                         mtdbatl 0,r11                                                   ; Set lower BAT first
  220                         mtdbatu 0,r10                                                   ; Now the upper
  221                         sync                                                                    ; Just make sure
  222                         
  223                         dcbf    0,r12                                                   ; Make sure we kill the cache to avoid paradoxes
  224                         sync
  225                         
  226                         ori             r11,r2,lo16(MASK(MSR_DR))               ; Turn on data translation
  227                         mtmsr   r11                                                             ; Do it for real
  228                         isync                                                                   ; Make sure of it
  229                         
  230                         eieio                                                                   ; Make sure of all previous accesses
  231                         sync                                                                    ; Make sure it is all caught up
  232                         
  233                         lwz             r11,0(r12)                                              ; Get it and maybe machine check here
  234                         
  235                         eieio                                                                   ; Make sure of ordering again
  236                         sync                                                                    ; Get caught up yet again
  237                         isync                                                                   ; Do not go further till we are here
  238                         
  239                         mtmsr   r2                                                              ; Turn translation back off
  240                         isync
  241                         
  242                         lis             r10,hi16(EXT(shadow_BAT)+shdDBAT)       ; Get shadow address
  243                         ori             r10,r10,lo16(EXT(shadow_BAT)+shdDBAT)   ; Get shadow address
  244                         
  245                         lwz             r5,0(r10)                                               ; Pick up DBAT 0 high
  246                         lwz             r6,4(r10)                                               ; Pick up DBAT 0 low
  247                         lwz             r7,8(r10)                                               ; Pick up DBAT 1 high
  248                         lwz             r8,16(r10)                                              ; Pick up DBAT 2 high
  249                         lwz             r9,24(r10)                                              ; Pick up DBAT 3 high
  250                         
  251                         mtdbatu 0,r5                                                    ; Restore DBAT 0 high
  252                         mtdbatl 0,r6                                                    ; Restore DBAT 0 low
  253                         mtdbatu 1,r7                                                    ; Restore DBAT 1 high
  254                         mtdbatu 2,r8                                                    ; Restore DBAT 2 high
  255                         mtdbatu 3,r9                                                    ; Restore DBAT 3 high 
  256                         sync
  257                         
  258                         li              r3,1                                                    ; We made it
  259                         
  260                         mtmsr   r0                                                              ; Restore translation and exceptions
  261                         isync                                                                   ; Toss speculations
  262                         
  263                         stw             r11,0(r4)                                               ; Save the loaded value
  264                         blr                                                                             ; Return...
  265                         
  266 ;                       Force a line boundry here. This means we will be able to check addresses better
  267                         .align  5
  268                         .globl  EXT(ml_probe_read_mck)
  269 LEXT(ml_probe_read_mck)
  270 
  271     
  272 /* PCI config cycle probing - 64-bit
  273  *
  274  *      boolean_t ml_probe_read_64(addr64_t paddr, unsigned int *val)
  275  *
  276  *      Read the memory location at physical address paddr.
  277  *  This is a part of a device probe, so there is a good chance we will
  278  *  have a machine check here. So we have to be able to handle that.
  279  *  We assume that machine checks are enabled both in MSR and HIDs
  280  */
  281 
  282 ;                       Force a line boundry here
  283                         .align  6
  284                         .globl  EXT(ml_probe_read_64)
  285 
  286 LEXT(ml_probe_read_64)
  287 
  288                         mfsprg  r9,2                                                    ; Get feature flags
  289                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  290                         rlwinm. r0,r9,0,pf64Bitb,pf64Bitb               ; Are we on a 64-bit machine?
  291                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  292                         
  293                         mr              r4,r5                                                   ; Move result to common register
  294                         beq--   mpr32bit                                                ; Go do this the 32-bit way...
  295 
  296 mpr64bit:       andi.   r0,r3,3                                                 ; Check if we are on a word boundary
  297                         li              r0,0                                                    ; Clear the EE bit (and everything else for that matter)
  298                         bne--   mprFail                                                 ; Boundary not good...
  299                         mfmsr   r11                                                             ; Get the MSR
  300                         mtmsrd  r0,1                                                    ; Set the EE bit only (do not care about RI)
  301                         rlwinm  r11,r11,0,MSR_EE_BIT,MSR_EE_BIT ; Isolate just the EE bit
  302                         mfmsr   r10                                                             ; Refresh our view of the MSR (VMX/FP may have changed)
  303                         or              r12,r10,r11                                             ; Turn on EE if on before we turned it off
  304                         ori             r0,r0,lo16(MASK(MSR_IR)|MASK(MSR_DR))   ; Get the IR and DR bits
  305                         li              r2,1                                                    ; Get a 1
  306                         sldi    r2,r2,63                                                ; Get the 64-bit bit
  307                         andc    r10,r10,r0                                              ; Clear IR and DR
  308                         or              r10,r10,r2                                              ; Set 64-bit
  309                         
  310                         li              r0,1                                                    ; Get a 1
  311                         mtmsrd  r10                                                             ; Translation and EE off, 64-bit on
  312                         isync                   
  313                         
  314                         sldi    r0,r0,32+8                                              ; Get the right bit to inhibit caching
  315 
  316                         mfspr   r8,hid4                                                 ; Get HID4
  317                         or              r2,r8,r0                                                ; Set bit to make real accesses cache-inhibited
  318                         sync                                                                    ; Sync up
  319                         mtspr   hid4,r2                                                 ; Make real accesses cache-inhibited
  320                         isync                                                                   ; Toss prefetches
  321                         
  322                         lis             r7,0xE000                                               ; Get the unlikeliest ESID possible
  323                         srdi    r7,r7,1                                                 ; Make 0x7FFFFFFFF0000000
  324                         slbie   r7                                                              ; Make sure the ERAT is cleared 
  325                         
  326                         sync
  327                         isync
  328 
  329                         eieio                                                                   ; Make sure of all previous accesses
  330                         
  331                         lwz             r11,0(r3)                                               ; Get it and maybe machine check here
  332                         
  333                         eieio                                                                   ; Make sure of ordering again
  334                         sync                                                                    ; Get caught up yet again
  335                         isync                                                                   ; Do not go further till we are here
  336 
  337                         sync                                                                    ; Sync up
  338                         mtspr   hid4,r8                                                 ; Make real accesses not cache-inhibited
  339                         isync                                                                   ; Toss prefetches
  340 
  341                         lis             r7,0xE000                                               ; Get the unlikeliest ESID possible
  342                         srdi    r7,r7,1                                                 ; Make 0x7FFFFFFFF0000000
  343                         slbie   r7                                                              ; Make sure the ERAT is cleared 
  344 
  345                         mtmsrd  r12                                                             ; Restore entry MSR
  346                         isync
  347                         
  348                         stw             r11,0(r4)                                               ; Pass back the result
  349                         li              r3,1                                                    ; Indicate success
  350                         blr                                                                             ; Leave...
  351 
  352 mprFail:        li              r3,0                                                    ; Set failure
  353                         blr                                                                             ; Leave...
  354 
  355 ;                       Force a line boundry here. This means we will be able to check addresses better
  356                         .align  6
  357                         .globl  EXT(ml_probe_read_mck_64)
  358 LEXT(ml_probe_read_mck_64)
  359 
  360 
  361 /* Read physical address byte
  362  *
  363  *      unsigned int ml_phys_read_byte(vm_offset_t paddr)
  364  *      unsigned int ml_phys_read_byte_64(addr64_t paddr)
  365  *
  366  *      Read the byte at physical address paddr. Memory should not be cache inhibited.
  367  */
  368 
  369 ;                       Force a line boundry here
  370 
  371                         .align  5
  372                         .globl  EXT(ml_phys_read_byte_64)
  373 
  374 LEXT(ml_phys_read_byte_64)
  375 
  376                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  377                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits
  378             b           ml_phys_read_byte_join                  
  379 
  380                         .globl  EXT(ml_phys_read_byte)
  381 
  382 LEXT(ml_phys_read_byte)
  383             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  384 ml_phys_read_byte_join:                                                         ; r3 = address to read (reg64_t)
  385                         mflr    r11                                                             ; Save the return
  386                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  387                         
  388                         lbz             r3,0(r3)                                                ; Get the byte
  389                         b               rdwrpost                                                ; Clean up and leave...
  390 
  391 
  392 /* Read physical address half word
  393  *
  394  *      unsigned int ml_phys_read_half(vm_offset_t paddr)
  395  *      unsigned int ml_phys_read_half_64(addr64_t paddr)
  396  *
  397  *      Read the half word at physical address paddr. Memory should not be cache inhibited.
  398  */
  399 
  400 ;                       Force a line boundry here
  401 
  402                         .align  5
  403                         .globl  EXT(ml_phys_read_half_64)
  404 
  405 LEXT(ml_phys_read_half_64)
  406 
  407                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  408                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits
  409             b           ml_phys_read_half_join          
  410 
  411                         .globl  EXT(ml_phys_read_half)
  412 
  413 LEXT(ml_phys_read_half)
  414             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  415 ml_phys_read_half_join:                                                         ; r3 = address to read (reg64_t)
  416                         mflr    r11                                                             ; Save the return
  417                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  418                         
  419                         lhz             r3,0(r3)                                                ; Get the half word
  420                         b               rdwrpost                                                ; Clean up and leave...
  421 
  422 
  423 /* Read physical address word
  424  *
  425  *      unsigned int ml_phys_read(vm_offset_t paddr)
  426  *      unsigned int ml_phys_read_64(addr64_t paddr)
  427  *      unsigned int ml_phys_read_word(vm_offset_t paddr)
  428  *      unsigned int ml_phys_read_word_64(addr64_t paddr)
  429  *
  430  *      Read the word at physical address paddr. Memory should not be cache inhibited.
  431  */
  432 
  433 ;                       Force a line boundry here
  434 
  435                         .align  5
  436                         .globl  EXT(ml_phys_read_64)
  437                         .globl  EXT(ml_phys_read_word_64)
  438 
  439 LEXT(ml_phys_read_64)
  440 LEXT(ml_phys_read_word_64)
  441 
  442                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  443                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits
  444             b           ml_phys_read_word_join          
  445 
  446                         .globl  EXT(ml_phys_read)
  447                         .globl  EXT(ml_phys_read_word)
  448 
  449 LEXT(ml_phys_read)
  450 LEXT(ml_phys_read_word)
  451             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  452 ml_phys_read_word_join:                                                         ; r3 = address to read (reg64_t)
  453                         mflr    r11                                                             ; Save the return
  454                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  455                         
  456                         lwz             r3,0(r3)                                                ; Get the word
  457                         b               rdwrpost                                                ; Clean up and leave...
  458 
  459 
  460 /* Read physical address double word
  461  *
  462  *      unsigned long long ml_phys_read_double(vm_offset_t paddr)
  463  *      unsigned long long ml_phys_read_double_64(addr64_t paddr)
  464  *
  465  *      Read the double word at physical address paddr. Memory should not be cache inhibited.
  466  */
  467 
  468 ;                       Force a line boundry here
  469 
  470                         .align  5
  471                         .globl  EXT(ml_phys_read_double_64)
  472 
  473 LEXT(ml_phys_read_double_64)
  474 
  475                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  476                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  477             b           ml_phys_read_double_join                
  478 
  479                         .globl  EXT(ml_phys_read_double)
  480 
  481 LEXT(ml_phys_read_double)
  482             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  483 ml_phys_read_double_join:                                                       ; r3 = address to read (reg64_t)
  484                         mflr    r11                                                             ; Save the return
  485                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  486                         
  487                         lwz             r4,4(r3)                                                ; Get the low word
  488                         lwz             r3,0(r3)                                                ; Get the high word
  489                         b               rdwrpost                                                ; Clean up and leave...
  490 
  491 
  492 /* Write physical address byte
  493  *
  494  *      void ml_phys_write_byte(vm_offset_t paddr, unsigned int data)
  495  *      void ml_phys_write_byte_64(addr64_t paddr, unsigned int data)
  496  *
  497  *      Write the byte at physical address paddr. Memory should not be cache inhibited.
  498  */
  499 
  500                         .align  5
  501                         .globl  EXT(ml_phys_write_byte_64)
  502 
  503 LEXT(ml_phys_write_byte_64)
  504 
  505                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  506                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  507                         mr              r4,r5                                                   ; Copy over the data
  508             b           ml_phys_write_byte_join
  509 
  510                         .globl  EXT(ml_phys_write_byte)
  511 
  512 LEXT(ml_phys_write_byte)
  513             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  514 ml_phys_write_byte_join:                                                        ; r3 = address to write (reg64_t), r4 = data
  515                         mflr    r11                                                             ; Save the return
  516                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  517                         
  518                         stb             r4,0(r3)                                                ; Set the byte
  519                         b               rdwrpost                                                ; Clean up and leave...
  520 
  521 
  522 /* Write physical address half word
  523  *
  524  *      void ml_phys_write_half(vm_offset_t paddr, unsigned int data)
  525  *      void ml_phys_write_half_64(addr64_t paddr, unsigned int data)
  526  *
  527  *      Write the half word at physical address paddr. Memory should not be cache inhibited.
  528  */
  529 
  530                         .align  5
  531                         .globl  EXT(ml_phys_write_half_64)
  532 
  533 LEXT(ml_phys_write_half_64)
  534 
  535                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  536                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  537                         mr              r4,r5                                                   ; Copy over the data
  538             b           ml_phys_write_half_join
  539 
  540                         .globl  EXT(ml_phys_write_half)
  541 
  542 LEXT(ml_phys_write_half)
  543             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  544 ml_phys_write_half_join:                                                        ; r3 = address to write (reg64_t), r4 = data
  545                         mflr    r11                                                             ; Save the return
  546                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  547                         
  548                         sth             r4,0(r3)                                                ; Set the half word
  549                         b               rdwrpost                                                ; Clean up and leave...
  550 
  551 
  552 /* Write physical address word
  553  *
  554  *      void ml_phys_write(vm_offset_t paddr, unsigned int data)
  555  *      void ml_phys_write_64(addr64_t paddr, unsigned int data)
  556  *      void ml_phys_write_word(vm_offset_t paddr, unsigned int data)
  557  *      void ml_phys_write_word_64(addr64_t paddr, unsigned int data)
  558  *
  559  *      Write the word at physical address paddr. Memory should not be cache inhibited.
  560  */
  561 
  562                         .align  5
  563                         .globl  EXT(ml_phys_write_64)
  564                         .globl  EXT(ml_phys_write_word_64)
  565 
  566 LEXT(ml_phys_write_64)
  567 LEXT(ml_phys_write_word_64)
  568 
  569                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  570                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  571                         mr              r4,r5                                                   ; Copy over the data
  572             b           ml_phys_write_word_join
  573 
  574                         .globl  EXT(ml_phys_write)
  575                         .globl  EXT(ml_phys_write_word)
  576 
  577 LEXT(ml_phys_write)
  578 LEXT(ml_phys_write_word)
  579             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  580 ml_phys_write_word_join:                                                        ; r3 = address to write (reg64_t), r4 = data
  581                         mflr    r11                                                             ; Save the return
  582                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  583                         
  584                         stw             r4,0(r3)                                                ; Set the word
  585                         b               rdwrpost                                                ; Clean up and leave...
  586 
  587 
  588 /* Write physical address double word
  589  *
  590  *      void ml_phys_write_double(vm_offset_t paddr, unsigned long long data)
  591  *      void ml_phys_write_double_64(addr64_t paddr, unsigned long long data)
  592  *
  593  *      Write the double word at physical address paddr. Memory should not be cache inhibited.
  594  */
  595 
  596                         .align  5
  597                         .globl  EXT(ml_phys_write_double_64)
  598 
  599 LEXT(ml_phys_write_double_64)
  600 
  601                         rlwinm  r3,r3,0,1,0                                             ; Copy low 32 bits to top 32
  602                         rlwimi  r3,r4,0,0,31                                    ; Insert low part of 64-bit address in bottom 32 bits                   
  603                         mr              r4,r5                                                   ; Copy over the high data
  604                         mr              r5,r6                                                   ; Copy over the low data
  605             b           ml_phys_write_double_join
  606 
  607                         .globl  EXT(ml_phys_write_double)
  608 
  609 LEXT(ml_phys_write_double)
  610             rlwinm   r3,r3,0,0,31                               ; truncate address to 32-bits
  611 ml_phys_write_double_join:                                                      ; r3 = address to write (reg64_t), r4,r5 = data (long long)
  612                         mflr    r11                                                             ; Save the return
  613                         bl              rdwrpre                                                 ; Get set up, translation/interrupts off, 64-bit on, etc.
  614                         
  615                         stw             r4,0(r3)                                                ; Set the high word
  616                         stw             r5,4(r3)                                                ; Set the low word
  617                         b               rdwrpost                                                ; Clean up and leave...
  618 
  619 
  620                         .align  5
  621 
  622 rdwrpre:        mfsprg  r12,2                                                   ; Get feature flags 
  623                         lis             r8,hi16(MASK(MSR_VEC))                  ; Get the vector flag
  624                         mfmsr   r10                                                             ; Save the MSR 
  625                         ori             r8,r8,lo16(MASK(MSR_FP))                ; Add the FP flag
  626                         mtcrf   0x02,r12                                                ; move pf64Bit
  627                         andc    r10,r10,r8                                              ; Clear VEC and FP
  628                         ori             r9,r8,lo16(MASK(MSR_EE)|MASK(MSR_IR)|MASK(MSR_DR))              ; Drop EE, DR, and IR
  629                         li              r2,1                                                    ; Prepare for 64 bit
  630                         andc    r9,r10,r9                                               ; Clear VEC, FP, DR, and EE
  631                         bf--    pf64Bitb,rdwrpre32                              ; Join 32-bit code...
  632                         
  633                         srdi    r7,r3,31                                                ; Get a 1 if address is in I/O memory
  634                         rldimi  r9,r2,63,MSR_SF_BIT                             ; set SF bit (bit 0)
  635                         cmpldi  cr7,r7,1                                                ; Is source in I/O memory?
  636                         mtmsrd  r9                                                              ; set 64-bit mode, turn off EE, DR, and IR
  637                         isync                                                                   ; synchronize
  638 
  639                         sldi    r0,r2,32+8                                              ; Get the right bit to turn off caching
  640                         
  641                         bnelr++ cr7                                                             ; We are not in the I/O area, all ready...
  642                         
  643                         mfspr   r8,hid4                                                 ; Get HID4
  644                         or              r2,r8,r0                                                ; Set bit to make real accesses cache-inhibited
  645                         sync                                                                    ; Sync up
  646                         mtspr   hid4,r2                                                 ; Make real accesses cache-inhibited
  647                         isync                                                                   ; Toss prefetches
  648                         
  649                         lis             r7,0xE000                                               ; Get the unlikeliest ESID possible
  650                         srdi    r7,r7,1                                                 ; Make 0x7FFFFFFFF0000000
  651                         slbie   r7                                                              ; Make sure the ERAT is cleared 
  652                         
  653                         sync
  654                         isync
  655                         blr                                                                             ; Finally,  all ready...
  656         
  657                         .align  5
  658                         
  659 rdwrpre32:      rlwimi  r9,r10,0,MSR_IR_BIT,MSR_IR_BIT  ; Leave the IR bit unchanged
  660                         mtmsr   r9                                                              ; Drop EE, DR, and leave IR unchanged
  661                         isync
  662                         blr                                                                             ; All set up, leave...
  663                         
  664                         .align  5
  665                         
  666 rdwrpost:       mtlr    r11                                                             ; Restore the return
  667                         bt++    pf64Bitb,rdwrpost64                             ; Join 64-bit code...
  668                         
  669                         mtmsr   r10                                                             ; Restore entry MSR (sans FP and VEC)
  670                         isync
  671                         blr                                                                             ; Leave...
  672                         
  673 rdwrpost64:     bne++   cr7,rdwrpcok                                    ; Skip enabling real mode caching if we did not change it...
  674 
  675                         sync                                                                    ; Sync up
  676                         mtspr   hid4,r8                                                 ; Make real accesses not cache-inhibited
  677                         isync                                                                   ; Toss prefetches
  678 
  679                         lis             r7,0xE000                                               ; Get the unlikeliest ESID possible
  680                         srdi    r7,r7,1                                                 ; Make 0x7FFFFFFFF0000000
  681                         slbie   r7                                                              ; Make sure the ERAT is cleared 
  682 
  683 rdwrpcok:       mtmsrd  r10                                                             ; Restore entry MSR (sans FP and VEC)
  684                         isync
  685                         blr                                                                             ; Leave...
  686 
  687 
  688 /* set interrupts enabled or disabled
  689  *
  690  *      boolean_t set_interrupts_enabled(boolean_t enable)
  691  *
  692  *      Set EE bit to "enable" and return old value as boolean
  693  */
  694 
  695 ;                       Force a line boundry here
  696                         .align  5
  697                         .globl  EXT(ml_set_interrupts_enabled)
  698  
  699 LEXT(ml_set_interrupts_enabled)
  700 
  701                         andi.   r4,r3,1                                                 ; Are we turning interruptions on?
  702                         lis             r0,hi16(MASK(MSR_VEC))                  ; Get vector enable
  703                         mfmsr   r5                                                              ; Get the current MSR
  704                         ori             r0,r0,lo16(MASK(MSR_EE)|MASK(MSR_FP))   ; Get float enable and EE enable
  705                         rlwinm  r3,r5,17,31,31                                  ; Set return value
  706                         andc    r5,r5,r0                                                ; Force VEC and FP off
  707                         bne         CheckPreemption                                     ; Interrupts going on, check ASTs...
  708 
  709                         mtmsr   r5                              ; Slam diable (always going disabled here)
  710                         isync                                                                   ; Need this because FP/Vec might go off
  711                         blr
  712 
  713                         .align  5
  714 
  715 CheckPreemption:
  716                         mfsprg  r7,0
  717                         ori             r5,r5,lo16(MASK(MSR_EE))                ; Turn on the enable
  718                         lwz             r8,PP_NEED_AST(r7)                              ; Get pointer to AST flags
  719                         mfsprg  r9,1                                                    ; Get current activation
  720                         li              r6,AST_URGENT                                   ; Get the type we will preempt for 
  721                         lwz             r7,ACT_PREEMPT_CNT(r9)                  ; Get preemption count
  722                         lwz             r8,0(r8)                                                ; Get AST flags
  723                         lis             r0,hi16(DoPreemptCall)                  ; High part of Preempt FW call
  724                         cmpwi   cr1,r7,0                                                ; Are preemptions masked off?
  725                         and.    r8,r8,r6                                                ; Are we urgent?
  726                         crorc   cr1_eq,cr0_eq,cr1_eq                    ; Remember if preemptions are masked or not urgent
  727                         ori             r0,r0,lo16(DoPreemptCall)       ; Bottome of FW call
  728 
  729                         mtmsr   r5                                                              ; Restore the MSR now, before we can preempt
  730                         isync                                                                   ; Need this because FP/Vec might go off
  731 
  732                         beqlr++ cr1                                                             ; Return if no premption...
  733                         sc                                                                              ; Preempt
  734                         blr
  735 
  736 /*  Emulate a decremeter exception
  737  *
  738  *      void machine_clock_assist(void)
  739  *
  740  */
  741 
  742 ;                       Force a line boundry here
  743                         .align  5
  744                         .globl  EXT(machine_clock_assist)
  745  
  746 LEXT(machine_clock_assist)
  747 
  748                         mfsprg  r7,0
  749                         lwz             r4,PP_INTS_ENABLED(r7)
  750                         mr.             r4,r4
  751                         bnelr+  cr0
  752                         b       EXT(CreateFakeDEC)
  753 
  754 /*  Set machine into idle power-saving mode. 
  755  *
  756  *      void machine_idle_ppc(void)
  757  *
  758  *      We will use the PPC NAP or DOZE for this. 
  759  *      This call always returns.  Must be called with spllo (i.e., interruptions
  760  *      enabled).
  761  *
  762  */
  763 
  764 ;                       Force a line boundry here
  765                         .align  5
  766                         .globl  EXT(machine_idle_ppc)
  767 
  768 LEXT(machine_idle_ppc)
  769 
  770                         lis             r0,hi16(MASK(MSR_VEC))                  ; Get the vector flag
  771                         mfmsr   r3                                                              ; Save the MSR 
  772                         ori             r0,r0,lo16(MASK(MSR_FP))                ; Add the FP flag
  773                         andc    r3,r3,r0                                                ; Clear VEC and FP
  774                         ori             r0,r0,lo16(MASK(MSR_EE))                ; Drop EE also
  775                         andc    r5,r3,r0                                                ; Clear VEC, FP, DR, and EE
  776 
  777                         mtmsr   r5                                                              ; Hold up interruptions for now
  778                         isync                                                                   ; May have messed with fp/vec
  779                         mfsprg  r12,0                                                   ; Get the per_proc_info
  780                         mfsprg  r11,2                                                   ; Get CPU specific features
  781                         mfspr   r6,hid0                                                 ; Get the current power-saving mode
  782                         mtcrf   0xC7,r11                                                ; Get the facility flags
  783 
  784                         lis             r4,hi16(napm)                                   ; Assume we can nap
  785                         bt              pfWillNapb,yesnap                               ; Yeah, nap is ok...
  786                         
  787                         lis             r4,hi16(dozem)                                  ; Assume we can doze
  788                         bt              pfCanDozeb,yesnap                               ; We can sleep or doze one this machine...
  789                         
  790                         ori             r3,r3,lo16(MASK(MSR_EE))                ; Flip on EE
  791                         mtmsr   r3                                                              ; Turn interruptions back on
  792                         blr                                                                             ; Leave...
  793 
  794 yesnap:         mftbu   r9                                                              ; Get the upper timebase
  795                         mftb    r7                                                              ; Get the lower timebase
  796                         mftbu   r8                                                              ; Get the upper one again
  797                         cmplw   r9,r8                                                   ; Did the top tick?
  798                         bne-    yesnap                                                  ; Yeah, need to get it again...
  799                         stw             r8,napStamp(r12)                                ; Set high order time stamp
  800                         stw             r7,napStamp+4(r12)                              ; Set low order nap stamp
  801 
  802                         rlwinm. r7,r11,0,pfNoL2PFNapb,pfNoL2PFNapb      ; Turn off L2 Prefetch before nap?
  803                         beq     miL2PFok
  804 
  805                         mfspr   r7,msscr0                                               ; Get currect MSSCR0 value
  806                         rlwinm  r7,r7,0,0,l2pfes-1                              ; Disable L2 Prefetch
  807                         mtspr   msscr0,r7                                               ; Updates MSSCR0 value
  808                         sync
  809                         isync
  810 
  811 miL2PFok:
  812                         rlwinm. r7,r11,0,pfSlowNapb,pfSlowNapb  ; Should nap at slow speed?
  813                         beq     minoslownap
  814 
  815                         mfspr   r7,hid1                                                 ; Get current HID1 value
  816                         oris    r7,r7,hi16(hid1psm)                             ; Select PLL1
  817                         mtspr   hid1,r7                                                 ; Update HID1 value
  818 
  819 minoslownap:
  820 
  821 ;
  822 ;                       We have to open up interruptions here because book 4 says that we should
  823 ;                       turn on only the POW bit and that we should have interrupts enabled
  824 ;                       The interrupt handler will detect that nap or doze is set if an interrupt
  825 ;                       is taken and set everything up to return directly to machine_idle_ret.
  826 ;                       So, make sure everything we need there is already set up...
  827 ;
  828 
  829                         li              r10,hi16(dozem|napm|sleepm)             ; Mask of power management bits
  830                 
  831                         bf--    pf64Bitb,mipNSF1                                ; skip if 32-bit...
  832                         
  833                         sldi    r4,r4,32                                                ; Position the flags
  834                         sldi    r10,r10,32                                              ; Position the masks
  835 
  836                 
  837 mipNSF1:        andc    r6,r6,r10                                               ; Clean up the old power bits           
  838 
  839                         ori             r7,r5,lo16(MASK(MSR_EE))                ; Flip on EE
  840                         or              r6,r6,r4                                                ; Set nap or doze
  841                         oris    r5,r7,hi16(MASK(MSR_POW))               ; Turn on power management in next MSR
  842                         
  843                         sync
  844                         mtspr   hid0,r6                                                 ; Set up the HID for nap/doze
  845                         mfspr   r6,hid0                                                 ; Yes, this is silly, keep it here
  846                         mfspr   r6,hid0                                                 ; Yes, this is a duplicate, keep it here
  847                         mfspr   r6,hid0                                                 ; Yes, this is a duplicate, keep it here
  848                         mfspr   r6,hid0                                                 ; Yes, this is a duplicate, keep it here
  849                         mfspr   r6,hid0                                                 ; Yes, this is a duplicate, keep it here
  850                         mfspr   r6,hid0                                                 ; Yes, this is a duplicate, keep it here
  851                         isync                                                                   ; Make sure it is set
  852                 
  853                         mtmsr   r7                                                              ; Enable for interrupts
  854                         rlwinm. r11,r11,0,pfAltivecb,pfAltivecb ; Do we have altivec?
  855                         beq-    minovec                                                 ; No...
  856                         dssall                                                                  ; Stop the streams before we nap/doze
  857 
  858 minovec:        sync                                                                    ; Make sure queues are clear                    
  859                         mtmsr   r5                                                              ; Nap or doze
  860                         isync                                                                   ; Make sure this takes before we proceed
  861                         b               minovec                                                 ; loop if POW does not take
  862 ;
  863 ;                       Note that the interrupt handler will turn off the nap/doze bits in the hid.
  864 ;                       Also remember that the interrupt handler will force return to here whenever
  865 ;                       the nap/doze bits are set.
  866 ;
  867                         .globl  EXT(machine_idle_ret)
  868 LEXT(machine_idle_ret)
  869                         mtmsr   r7                                                              ; Make sure the MSR is what we want
  870                         isync                                                                   ; In case we turn on translation
  871                         
  872                         blr                                                                             ; Return...
  873 
  874 /*  Put machine to sleep. 
  875  *      This call never returns. We always exit sleep via a soft reset.
  876  *      All external interruptions must be drained at this point and disabled.
  877  *
  878  *      void ml_ppc_sleep(void)
  879  *
  880  *      We will use the PPC SLEEP for this. 
  881  *
  882  *      There is one bit of hackery in here: we need to enable for
  883  *      interruptions when we go to sleep and there may be a pending
  884  *      decrimenter rupt.  So we make the decrimenter 0x7FFFFFFF and enable for
  885  *      interruptions. The decrimenter rupt vector recognizes this and returns
  886  *      directly back here.
  887  *
  888  */
  889 
  890 ;                       Force a line boundry here
  891                         .align  5
  892                         .globl  EXT(ml_ppc_sleep)
  893 
  894 LEXT(ml_ppc_sleep)
  895 
  896 #if 0
  897                         mfmsr   r5                                                              ; Hack to spin instead of sleep 
  898                         rlwinm  r5,r5,0,MSR_DR_BIT+1,MSR_IR_BIT-1       ; Turn off translation  
  899                         rlwinm  r5,r5,0,MSR_EE_BIT+1,MSR_EE_BIT-1       ; Turn off interruptions
  900                         mtmsr   r5                                                              ; No talking
  901                         isync
  902                         
  903 deadsleep:      addi    r3,r3,1                                                 ; Make analyzer happy
  904                         addi    r3,r3,1
  905                         addi    r3,r3,1
  906                         b               deadsleep                                               ; Die the death of 1000 joys...
  907 #endif  
  908                         
  909                         mfsprg  r12,0                                                   ; Get the per_proc_info
  910                         mfspr   r4,hid0                                                 ; Get the current power-saving mode
  911                         eqv             r10,r10,r10                                             ; Get all foxes
  912                         mfsprg  r11,2                                                   ; Get CPU specific features
  913 
  914                         rlwinm. r5,r11,0,pfNoL2PFNapb,pfNoL2PFNapb      ; Turn off L2 Prefetch before sleep?
  915                         beq     mpsL2PFok
  916 
  917                         mfspr   r5,msscr0                                               ; Get currect MSSCR0 value
  918                         rlwinm  r5,r5,0,0,l2pfes-1                              ; Disable L2 Prefetch
  919                         mtspr   msscr0,r5                                               ; Updates MSSCR0 value
  920                         sync
  921                         isync
  922 
  923 mpsL2PFok:
  924                         rlwinm. r5,r11,0,pf64Bitb,pf64Bitb              ; PM bits are shifted on 64bit systems.
  925                         bne             mpsPF64bit
  926 
  927                         rlwinm  r4,r4,0,sleep+1,doze-1                  ; Clear all possible power-saving modes (not DPM though)
  928                         oris    r4,r4,hi16(sleepm)                              ; Set sleep
  929                         b       mpsClearDEC
  930 
  931 mpsPF64bit:
  932                         lis     r5, hi16(dozem|napm|sleepm)                     ; Clear all possible power-saving modes (not DPM though)
  933                         sldi    r5, r5, 32
  934                         andc    r4, r4, r5
  935                         lis     r5, hi16(napm)                                          ; Set sleep
  936 //                      lis     r5, hi16(dozem)                                         ; Set sleep
  937                         sldi    r5, r5, 32
  938                         or      r4, r4, r5
  939 
  940 mpsClearDEC:
  941                         mfmsr   r5                                                              ; Get the current MSR
  942                         rlwinm  r10,r10,0,1,31                                  ; Make 0x7FFFFFFF
  943                         mtdec   r10                                                             ; Load decrimenter with 0x7FFFFFFF
  944                         isync                                                                   ; and make sure,
  945                         mfdec   r9                                                              ; really sure, it gets there
  946                         
  947                         mtcrf   0x07,r11                                                ; Get the cache flags, etc
  948 
  949                         rlwinm  r5,r5,0,MSR_DR_BIT+1,MSR_IR_BIT-1       ; Turn off translation          
  950 ;
  951 ;                       Note that we need translation off before we set the HID to sleep.  Otherwise
  952 ;                       we will ignore any PTE misses that occur and cause an infinite loop.
  953 ;
  954                         bt              pfNoMSRirb,mpsNoMSR                             ; No MSR...
  955 
  956                         mtmsr   r5                                                              ; Translation off
  957                         isync                                                                   ; Toss prefetch
  958                         b               mpsNoMSRx
  959                         
  960 mpsNoMSR:       
  961                         li              r0,loadMSR                                              ; Get the MSR setter SC
  962                         mr              r3,r5                                                   ; Get new MSR
  963                         sc                                                                              ; Set it
  964 mpsNoMSRx:
  965 
  966                         ori             r3,r5,lo16(MASK(MSR_EE))                ; Flip on EE
  967                         sync
  968                         mtspr   hid0,r4                                                 ; Set up the HID to sleep
  969                         mfspr   r4,hid0                                                 ; Yes, this is silly, keep it here
  970                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
  971                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
  972                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
  973                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
  974                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
  975 
  976                         mtmsr   r3                                                              ; Enable for interrupts to drain decrimenter
  977                                 
  978                         add             r6,r4,r5                                                ; Just waste time
  979                         add             r6,r6,r4                                                ; A bit more
  980                         add             r6,r6,r5                                                ; A bit more
  981 
  982                         mtmsr   r5                                                              ; Interruptions back off
  983                         isync                                                                   ; Toss prefetch
  984 
  985 ;
  986 ;                       We are here with translation off, interrupts off, all possible
  987 ;                       interruptions drained off, and a decrimenter that will not pop.
  988 ;
  989 
  990                         bl              EXT(cacheInit)                                  ; Clear out the caches.  This will leave them on
  991                         bl              EXT(cacheDisable)                               ; Turn off all caches
  992                         
  993                         mfmsr   r5                                                              ; Get the current MSR
  994                         oris    r5,r5,hi16(MASK(MSR_POW))               ; Turn on power management in next MSR
  995                                                                                                         ; Leave EE off because power goes off shortly
  996                         mfsprg  r12,0                                                   ; Get the per_proc_info
  997                         li              r10,PP_CPU_FLAGS
  998                         lhz             r11,PP_CPU_FLAGS(r12)                   ; Get the flags
  999                         ori             r11,r11,SleepState                              ; Marked SleepState
 1000                         sth             r11,PP_CPU_FLAGS(r12)                   ; Set the flags
 1001                         dcbf    r10,r12
 1002 slSleepNow:
 1003                         sync                                                                    ; Sync it all up
 1004                         mtmsr   r5                                                              ; Do sleep with interruptions enabled
 1005                         isync                                                                   ; Take a pill
 1006                         b               slSleepNow                                              ; Go back to sleep if we wake up...
 1007                         
 1008 
 1009 
 1010 /*  Initialize all caches including the TLBs
 1011  *
 1012  *      void cacheInit(void)
 1013  *
 1014  *      This is used to force the caches to an initial clean state.  First, we 
 1015  *      check if the cache is on, if so, we need to flush the contents to memory.
 1016  *      Then we invalidate the L1. Next, we configure and invalidate the L2 etc.
 1017  *      Finally we turn on all of the caches
 1018  *
 1019  *      Note that if translation is not disabled when this is called, the TLB will not
 1020  *      be completely clear after return.
 1021  *
 1022  */
 1023 
 1024 ;                       Force a line boundry here
 1025                         .align  5
 1026                         .globl  EXT(cacheInit)
 1027 
 1028 LEXT(cacheInit)
 1029 
 1030                         mfsprg  r12,0                                                   ; Get the per_proc_info
 1031                         mfspr   r9,hid0                                                 ; Get the current power-saving mode
 1032                         
 1033                         mfsprg  r11,2                                                   ; Get CPU specific features
 1034                         mfmsr   r7                                                              ; Get the current MSR
 1035                         rlwinm  r7,r7,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
 1036                         rlwinm  r7,r7,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
 1037                         rlwimi  r11,r11,pfLClckb+1,31,31                ; Move pfLClck to another position (to keep from using non-volatile CRs)
 1038                         rlwinm  r5,r7,0,MSR_DR_BIT+1,MSR_IR_BIT-1       ; Turn off translation          
 1039                         rlwinm  r5,r5,0,MSR_EE_BIT+1,MSR_EE_BIT-1       ; Turn off interruptions
 1040                         mtcrf   0x87,r11                                                ; Get the feature flags
 1041                         lis             r10,hi16(dozem|napm|sleepm|dpmm)        ; Mask of power management bits
 1042                         bf--    pf64Bitb,cIniNSF1                               ; Skip if 32-bit...
 1043                         
 1044                         sldi    r10,r10,32                                              ; Position the masks
 1045 
 1046 cIniNSF1:       andc    r4,r9,r10                                               ; Clean up the old power bits           
 1047                         mtspr   hid0,r4                                                 ; Set up the HID
 1048                         mfspr   r4,hid0                                                 ; Yes, this is silly, keep it here
 1049                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1050                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1051                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1052                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1053                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1054 
 1055                         bt              pfNoMSRirb,ciNoMSR                              ; No MSR...
 1056 
 1057                         mtmsr   r5                                                              ; Translation and all off
 1058                         isync                                                                   ; Toss prefetch
 1059                         b               ciNoMSRx
 1060                         
 1061 ciNoMSR:        
 1062                         li              r0,loadMSR                                              ; Get the MSR setter SC
 1063                         mr              r3,r5                                                   ; Get new MSR
 1064                         sc                                                                              ; Set it
 1065 ciNoMSRx:
 1066                         
 1067                         bf              pfAltivecb,cinoDSS                              ; No Altivec here...
 1068                         
 1069                         dssall                                                                  ; Stop streams
 1070                         sync
 1071 
 1072 cinoDSS:        li              r5,tlbieLock                                    ; Get the TLBIE lock
 1073                         li              r0,128                                                  ; Get number of TLB entries
 1074                         
 1075                         li              r6,0                                                    ; Start at 0
 1076                         bf--    pf64Bitb,citlbhang                              ; Skip if 32-bit...
 1077                         li              r0,1024                                                 ; Get the number of TLB entries
 1078 
 1079 citlbhang:      lwarx   r2,0,r5                                                 ; Get the TLBIE lock
 1080                         mr.             r2,r2                                                   ; Is it locked?
 1081                         bne-    citlbhang                                               ; It is locked, go wait...
 1082                         stwcx.  r0,0,r5                                                 ; Try to get it
 1083                         bne-    citlbhang                                               ; We was beat...
 1084 
 1085                         mtctr   r0                                                              ; Set the CTR
 1086                         
 1087 cipurgeTLB:     tlbie   r6                                                              ; Purge this entry
 1088                         addi    r6,r6,4096                                              ; Next page
 1089                         bdnz    cipurgeTLB                                              ; Do them all...
 1090                         
 1091                         mtcrf   0x80,r11                                                ; Set SMP capability
 1092                         sync                                                                    ; Make sure all TLB purges are done
 1093                         eieio                                                                   ; Order, order in the court
 1094                         
 1095                         bf              pfSMPcapb,cinoSMP                               ; SMP incapable...
 1096                         
 1097                         tlbsync                                                                 ; Sync all TLBs
 1098                         sync
 1099                         isync
 1100                         
 1101                         bf--    pf64Bitb,cinoSMP                                ; Skip if 32-bit...
 1102                         ptesync                                                                 ; Wait for quiet again
 1103                         sync
 1104                         
 1105 cinoSMP:        stw             r2,tlbieLock(0)                                 ; Unlock TLBIE lock
 1106 
 1107                         bt++    pf64Bitb,cin64                                  ; Skip if 64-bit...
 1108 
 1109                         rlwinm. r0,r9,0,ice,dce                                 ; Were either of the level 1s on?
 1110                         beq-    cinoL1                                                  ; No, no need to flush...
 1111                         
 1112             rlwinm.     r0,r11,0,pfL1fab,pfL1fab                ; do we have L1 flush assist?
 1113                         beq             ciswdl1                                                 ; If no hw flush assist, go do by software...
 1114                         
 1115                         mfspr   r8,msscr0                                               ; Get the memory system control register
 1116                         oris    r8,r8,hi16(dl1hwfm)                             ; Turn on the hardware flush request
 1117                         
 1118                         mtspr   msscr0,r8                                               ; Start the flush operation
 1119                         
 1120 ciwdl1f:        mfspr   r8,msscr0                                               ; Get the control register again
 1121                         
 1122                         rlwinm. r8,r8,0,dl1hwf,dl1hwf                   ; Has the flush request been reset yet?
 1123                         bne             ciwdl1f                                                 ; No, flush is still in progress...
 1124                         b               ciinvdl1                                                ; Go invalidate l1...
 1125                         
 1126 ;
 1127 ;                       We need to either make this very complicated or to use ROM for
 1128 ;                       the flush.  The problem is that if during the following sequence a
 1129 ;                       snoop occurs that invalidates one of the lines in the cache, the
 1130 ;                       PLRU sequence will be altered making it possible to miss lines
 1131 ;                       during the flush.  So, we either need to dedicate an area of RAM
 1132 ;                       to each processor, lock use of a RAM area, or use ROM.  ROM is
 1133 ;                       by far the easiest. Note that this is not an issue for machines
 1134 ;                       that have harware flush assists.
 1135 ;
 1136 
 1137 ciswdl1:        lwz             r0,pfl1dSize(r12)                               ; Get the level 1 cache size
 1138                                         
 1139                         bf              31,cisnlck                                              ; Skip if pfLClck not set...
 1140                         
 1141                         mfspr   r4,msscr0                                               ; ?
 1142                         rlwinm  r6,r4,0,0,l2pfes-1                              ; ?
 1143                         mtspr   msscr0,r6                                               ; Set it
 1144                         sync
 1145                         isync
 1146                         
 1147                         mfspr   r8,ldstcr                                               ; Save the LDSTCR
 1148                         li              r2,1                                                    ; Get a mask of 0x01
 1149                         lis             r3,0xFFF0                                               ; Point to ROM
 1150                         rlwinm  r11,r0,29,3,31                                  ; Get the amount of memory to handle all indexes
 1151 
 1152                         li              r6,0                                                    ; Start here
 1153                         
 1154 cisiniflsh:     dcbf    r6,r3                                                   ; Flush each line of the range we use
 1155                         addi    r6,r6,32                                                ; Bump to the next
 1156                         cmplw   r6,r0                                                   ; Have we reached the end?
 1157                         blt+    cisiniflsh                                              ; Nope, continue initial flush...
 1158                         
 1159                         sync                                                                    ; Make sure it is done
 1160         
 1161                         addi    r11,r11,-1                                              ; Get mask for index wrap       
 1162                         li              r6,0                                                    ; Get starting offset
 1163                                                 
 1164 cislckit:       not             r5,r2                                                   ; Lock all but 1 way
 1165                         rlwimi  r5,r8,0,0,23                                    ; Build LDSTCR
 1166                         mtspr   ldstcr,r5                                               ; Lock a way
 1167                         sync                                                                    ; Clear out memory accesses
 1168                         isync                                                                   ; Wait for all
 1169                         
 1170                         
 1171 cistouch:       lwzx    r10,r3,r6                                               ; Pick up some trash
 1172                         addi    r6,r6,32                                                ; Go to the next index
 1173                         and.    r0,r6,r11                                               ; See if we are about to do next index
 1174                         bne+    cistouch                                                ; Nope, do more...
 1175                         
 1176                         sync                                                                    ; Make sure it is all done
 1177                         isync                                                                   
 1178                         
 1179                         sub             r6,r6,r11                                               ; Back up to start + 1
 1180                         addi    r6,r6,-1                                                ; Get it right
 1181                         
 1182 cisflush:       dcbf    r3,r6                                                   ; Flush everything out
 1183                         addi    r6,r6,32                                                ; Go to the next index
 1184                         and.    r0,r6,r11                                               ; See if we are about to do next index
 1185                         bne+    cisflush                                                ; Nope, do more...
 1186 
 1187                         sync                                                                    ; Make sure it is all done
 1188                         isync                                                                   
 1189                         
 1190                         
 1191                         rlwinm. r2,r2,1,24,31                                   ; Shift to next way
 1192                         bne+    cislckit                                                ; Do this for all ways...
 1193 
 1194                         mtspr   ldstcr,r8                                               ; Slam back to original
 1195                         sync
 1196                         isync
 1197                         
 1198                         mtspr   msscr0,r4                                               ; ?
 1199                         sync
 1200                         isync
 1201 
 1202                         b               cinoL1                                                  ; Go on to level 2...
 1203                         
 1204 
 1205 cisnlck:        rlwinm  r2,r0,0,1,30                                    ; Double cache size
 1206                         add             r0,r0,r2                                                ; Get 3 times cache size
 1207                         rlwinm  r0,r0,26,6,31                                   ; Get 3/2 number of cache lines
 1208                         lis             r3,0xFFF0                                               ; Dead recon ROM address for now
 1209                         mtctr   r0                                                              ; Number of lines to flush
 1210 
 1211 ciswfldl1a:     lwz             r2,0(r3)                                                ; Flush anything else
 1212                         addi    r3,r3,32                                                ; Next line
 1213                         bdnz    ciswfldl1a                                              ; Flush the lot...
 1214                         
 1215 ciinvdl1:       sync                                                                    ; Make sure all flushes have been committed
 1216 
 1217                         mfspr   r8,hid0                                                 ; Get the HID0 bits
 1218                         rlwinm  r8,r8,0,dce+1,ice-1                             ; Clear cache enables
 1219                         mtspr   hid0,r8                                                 ; and turn off L1 cache
 1220                         sync                                                                    ; Make sure all is done
 1221                         isync
 1222 
 1223                         ori             r8,r8,lo16(icem|dcem|icfim|dcfim)       ; Set the HID0 bits for enable, and invalidate
 1224                         sync
 1225                         isync                                                                           
 1226                         
 1227                         mtspr   hid0,r8                                                 ; Start the invalidate and turn on cache        
 1228                         rlwinm  r8,r8,0,dcfi+1,icfi-1                   ; Turn off the invalidate bits
 1229                         mtspr   hid0,r8                                                 ; Turn off the invalidate (needed for some older machines)
 1230                         sync
 1231 
 1232                         
 1233 cinoL1:
 1234 ;
 1235 ;                       Flush and disable the level 2
 1236 ;
 1237             mfsprg      r10,2                                                   ; need to check 2 features we did not put in CR
 1238             rlwinm.     r0,r10,0,pfL2b,pfL2b                    ; do we have L2?
 1239                         beq             cinol2                                                  ; No level 2 cache to flush
 1240 
 1241                         mfspr   r8,l2cr                                                 ; Get the L2CR
 1242                         lwz             r3,pfl2cr(r12)                                  ; Get the L2CR value
 1243                         rlwinm.         r0,r8,0,l2e,l2e                                 ; Was the L2 enabled?
 1244                         bne             ciflushl2                                       ; Yes, force flush
 1245                         cmplwi          r8, 0                                           ; Was the L2 all the way off?
 1246                         beq             ciinvdl2                                        ; Yes, force invalidate
 1247                         lis             r0,hi16(l2sizm|l2clkm|l2ramm|l2ohm)     ; Get confiuration bits
 1248                         xor             r2,r8,r3                                                ; Get changing bits?
 1249                         ori             r0,r0,lo16(l2slm|l2dfm|l2bypm)  ; More config bits
 1250                         and.    r0,r0,r2                                                ; Did any change?
 1251                         bne-    ciinvdl2                                                ; Yes, just invalidate and get PLL synced...            
 1252                         
 1253 ciflushl2:
 1254             rlwinm.     r0,r10,0,pfL2fab,pfL2fab                ; hardware-assisted L2 flush?
 1255                         beq             ciswfl2                                                 ; Flush not in hardware...
 1256                         
 1257                         mr              r10,r8                                                  ; Take a copy now
 1258                         
 1259                         bf              31,cinol2lck                                    ; Skip if pfLClck not set...
 1260                         
 1261                         oris    r10,r10,hi16(l2ionlym|l2donlym) ; Set both instruction- and data-only
 1262                         sync
 1263                         mtspr   l2cr,r10                                                ; Lock out the cache
 1264                         sync
 1265                         isync
 1266                         
 1267 cinol2lck:      ori             r10,r10,lo16(l2hwfm)                    ; Request flush
 1268                         sync                                                                    ; Make sure everything is done
 1269                         
 1270                         mtspr   l2cr,r10                                                ; Request flush
 1271                         
 1272 cihwfl2:        mfspr   r10,l2cr                                                ; Get back the L2CR
 1273                         rlwinm. r10,r10,0,l2hwf,l2hwf                   ; Is the flush over?
 1274                         bne+    cihwfl2                                                 ; Nope, keep going...
 1275                         b               ciinvdl2                                                ; Flush done, go invalidate L2...
 1276                         
 1277 ciswfl2:
 1278                         lwz             r0,pfl2Size(r12)                                ; Get the L2 size
 1279                         oris    r2,r8,hi16(l2dom)                               ; Set L2 to data only mode
 1280 
 1281                         b               ciswfl2doa                                      ; Branch to next line...
 1282 
 1283                         .align  5
 1284 ciswfl2doc:
 1285                         mtspr   l2cr,r2                                                 ; Disable L2
 1286                         sync
 1287                         isync
 1288                         b               ciswfl2dod                                      ; It is off, go invalidate it...
 1289 
 1290 ciswfl2doa:
 1291                         b               ciswfl2dob                                      ; Branch to next...
 1292 
 1293 ciswfl2dob:
 1294                         sync                                                            ; Finish memory stuff
 1295                         isync                                                           ; Stop speculation
 1296                         b               ciswfl2doc                                      ; Jump back up and turn on data only...
 1297 ciswfl2dod:
 1298                         rlwinm  r0,r0,27,5,31                                   ; Get the number of lines
 1299                         lis             r10,0xFFF0                                              ; Dead recon ROM for now
 1300                         mtctr   r0                                                              ; Set the number of lines
 1301                         
 1302 ciswfldl2a:     lwz             r0,0(r10)                                               ; Load something to flush something
 1303                         addi    r10,r10,32                                              ; Next line
 1304                         bdnz    ciswfldl2a                                              ; Do the lot...
 1305                         
 1306 ciinvdl2:       rlwinm  r8,r3,0,l2e+1,31                                ; Clear the enable bit
 1307                         b               cinla                                                   ; Branch to next line...
 1308 
 1309                         .align  5
 1310 cinlc:          mtspr   l2cr,r8                                                 ; Disable L2
 1311                         sync
 1312                         isync
 1313                         b               ciinvl2                                                 ; It is off, go invalidate it...
 1314                         
 1315 cinla:          b               cinlb                                                   ; Branch to next...
 1316 
 1317 cinlb:          sync                                                                    ; Finish memory stuff
 1318                         isync                                                                   ; Stop speculation
 1319                         b               cinlc                                                   ; Jump back up and turn off cache...
 1320                         
 1321 ciinvl2:        sync
 1322                         isync
 1323 
 1324                         cmplwi  r3, 0                                                   ; Should the L2 be all the way off?
 1325                         beq     cinol2                                                  ; Yes, done with L2
 1326 
 1327                         oris    r2,r8,hi16(l2im)                                ; Get the invalidate flag set
 1328                         
 1329                         mtspr   l2cr,r2                                                 ; Start the invalidate
 1330                         sync
 1331                         isync
 1332 ciinvdl2a:      mfspr   r2,l2cr                                                 ; Get the L2CR
 1333             mfsprg      r0,2                                                    ; need to check a feature in "non-volatile" set
 1334             rlwinm.     r0,r0,0,pfL2ib,pfL2ib                   ; flush in HW?
 1335                         beq             ciinvdl2b                                               ; Flush not in hardware...
 1336                         rlwinm. r2,r2,0,l2i,l2i                                 ; Is the invalidate still going?
 1337                         bne+    ciinvdl2a                                               ; Assume so, this will take a looong time...
 1338                         sync
 1339                         b               cinol2                                                  ; No level 2 cache to flush
 1340 ciinvdl2b:
 1341                         rlwinm. r2,r2,0,l2ip,l2ip                               ; Is the invalidate still going?
 1342                         bne+    ciinvdl2a                                               ; Assume so, this will take a looong time...
 1343                         sync
 1344                         mtspr   l2cr,r8                                                 ; Turn off the invalidate request
 1345                         
 1346 cinol2:
 1347                         
 1348 ;
 1349 ;                       Flush and enable the level 3
 1350 ;
 1351                         bf              pfL3b,cinol3                                    ; No level 3 cache to flush
 1352 
 1353                         mfspr   r8,l3cr                                                 ; Get the L3CR
 1354                         lwz             r3,pfl3cr(r12)                                  ; Get the L3CR value
 1355                         rlwinm.         r0,r8,0,l3e,l3e                                 ; Was the L3 enabled?
 1356                         bne             ciflushl3                                       ; Yes, force flush
 1357                         cmplwi          r8, 0                                           ; Was the L3 all the way off?
 1358                         beq             ciinvdl3                                        ; Yes, force invalidate
 1359                         lis             r0,hi16(l3pem|l3sizm|l3dxm|l3clkm|l3spom|l3ckspm)       ; Get configuration bits
 1360                         xor             r2,r8,r3                                                ; Get changing bits?
 1361                         ori             r0,r0,lo16(l3pspm|l3repm|l3rtm|l3cyam|l3dmemm|l3dmsizm) ; More config bits
 1362                         and.    r0,r0,r2                                                ; Did any change?
 1363                         bne-    ciinvdl3                                                ; Yes, just invalidate and get PLL synced...
 1364                         
 1365 ciflushl3:
 1366                         sync                                                                    ; 7450 book says do this even though not needed
 1367                         mr              r10,r8                                                  ; Take a copy now
 1368                         
 1369                         bf              31,cinol3lck                                    ; Skip if pfL23lck not set...
 1370                         
 1371                         oris    r10,r10,hi16(l3iom)                             ; Set instruction-only
 1372                         ori             r10,r10,lo16(l3donlym)                  ; Set data-only
 1373                         sync
 1374                         mtspr   l3cr,r10                                                ; Lock out the cache
 1375                         sync
 1376                         isync
 1377                         
 1378 cinol3lck:      ori             r10,r10,lo16(l3hwfm)                    ; Request flush
 1379                         sync                                                                    ; Make sure everything is done
 1380                         
 1381                         mtspr   l3cr,r10                                                ; Request flush
 1382                         
 1383 cihwfl3:        mfspr   r10,l3cr                                                ; Get back the L3CR
 1384                         rlwinm. r10,r10,0,l3hwf,l3hwf                   ; Is the flush over?
 1385                         bne+    cihwfl3                                                 ; Nope, keep going...
 1386 
 1387 ciinvdl3:       rlwinm  r8,r3,0,l3e+1,31                                ; Clear the enable bit
 1388                         sync                                                                    ; Make sure of life, liberty, and justice
 1389                         mtspr   l3cr,r8                                                 ; Disable L3
 1390                         sync
 1391 
 1392                         cmplwi  r3, 0                                                   ; Should the L3 be all the way off?
 1393                         beq     cinol3                                                  ; Yes, done with L3
 1394 
 1395                         ori             r8,r8,lo16(l3im)                                ; Get the invalidate flag set
 1396 
 1397                         mtspr   l3cr,r8                                                 ; Start the invalidate
 1398 
 1399 ciinvdl3b:      mfspr   r8,l3cr                                                 ; Get the L3CR
 1400                         rlwinm. r8,r8,0,l3i,l3i                                 ; Is the invalidate still going?
 1401                         bne+    ciinvdl3b                                               ; Assume so...
 1402                         sync
 1403 
 1404                         lwz     r10, pfBootConfig(r12)                                  ; ?
 1405                         rlwinm. r10, r10, 24, 28, 31                                    ; ?
 1406                         beq     ciinvdl3nopdet                                          ; ?
 1407                         
 1408                         mfspr   r8,l3pdet                                               ; ?
 1409                         srw     r2, r8, r10                                             ; ?
 1410                         rlwimi  r2, r8, 0, 24, 31                                       ; ?
 1411                         subfic  r10, r10, 32                                            ; ?
 1412                         li      r8, -1                                                  ; ?
 1413                         ori     r2, r2, 0x0080                                          ; ?
 1414                         slw     r8, r8, r10                                             ; ?
 1415                         or      r8, r2, r8                                              ; ?
 1416                         mtspr   l3pdet, r8                                              ; ?
 1417                         isync
 1418 
 1419 ciinvdl3nopdet:
 1420                         mfspr   r8,l3cr                                                 ; Get the L3CR
 1421                         rlwinm  r8,r8,0,l3clken+1,l3clken-1             ; Clear the clock enable bit
 1422                         mtspr   l3cr,r8                                                 ; Disable the clock
 1423 
 1424                         li              r2,128                                                  ; ?
 1425 ciinvdl3c:      addi    r2,r2,-1                                                ; ?
 1426                         cmplwi  r2,0                                                    ; ?
 1427                         bne+    ciinvdl3c
 1428 
 1429                         mfspr   r10,msssr0                                              ; ?
 1430                         rlwinm  r10,r10,0,vgL3TAG+1,vgL3TAG-1   ; ?
 1431                         mtspr   msssr0,r10                                              ; ?
 1432                         sync
 1433 
 1434                         mtspr   l3cr,r3                                                 ; Enable it as desired
 1435                         sync
 1436 cinol3:
 1437             mfsprg      r0,2                                                    ; need to check a feature in "non-volatile" set
 1438             rlwinm.     r0,r0,0,pfL2b,pfL2b                             ; is there an L2 cache?
 1439                         beq             cinol2a                                                 ; No level 2 cache to enable
 1440 
 1441                         lwz             r3,pfl2cr(r12)                                  ; Get the L2CR value
 1442                         cmplwi          r3, 0                                           ; Should the L2 be all the way off?
 1443                         beq             cinol2a                                                 : Yes, done with L2
 1444                         mtspr   l2cr,r3                                                 ; Enable it as desired
 1445                         sync
 1446 
 1447 ;
 1448 ;                       Invalidate and turn on L1s
 1449 ;
 1450 
 1451 cinol2a:        
 1452                         bt              31,cinoexit                                             ; Skip if pfLClck set...
 1453 
 1454                         rlwinm  r8,r9,0,dce+1,ice-1                             ; Clear the I- and D- cache enables
 1455                         mtspr   hid0,r8                                                 ; Turn off dem caches
 1456                         sync
 1457                         
 1458                         ori             r8,r9,lo16(icem|dcem|icfim|dcfim)       ; Set the HID0 bits for enable, and invalidate
 1459                         rlwinm  r9,r8,0,dcfi+1,icfi-1                   ; Turn off the invalidate bits
 1460                         sync
 1461                         isync                                                                                   
 1462 
 1463                         mtspr   hid0,r8                                                 ; Start the invalidate and turn on L1 cache     
 1464 
 1465 cinoexit:       mtspr   hid0,r9                                                 ; Turn off the invalidate (needed for some older machines) and restore entry conditions
 1466                         sync
 1467                         mtmsr   r7                                                              ; Restore MSR to entry
 1468                         isync
 1469                         blr                                                                             ; Return...
 1470 
 1471 
 1472 ;
 1473 ;                       Handle 64-bit architecture
 1474 ;                       This processor can not run without caches, so we just push everything out
 1475 ;                       and flush.  It will be relativily clean afterwards
 1476 ;
 1477                         
 1478                         .align  5
 1479                         
 1480 cin64:          
 1481                         li              r10,hi16(dozem|napm|sleepm)             ; Mask of power management bits we want cleared
 1482                         sldi    r10,r10,32                                              ; Position the masks
 1483                         andc    r9,r9,r10                                               ; Clean up the old power bits
 1484                         mr              r4,r9   
 1485                         isync
 1486                         mtspr   hid0,r4                                                 ; Set up the HID
 1487                         mfspr   r4,hid0                                                 ; Yes, this is silly, keep it here
 1488                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1489                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1490                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1491                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1492                         mfspr   r4,hid0                                                 ; Yes, this is a duplicate, keep it here
 1493                         isync
 1494 
 1495                         mfspr   r10,hid1                                                ; Save hid1
 1496                         mfspr   r4,hid4                                                 ; Save hid4
 1497                         mr              r12,r10                                                 ; Really save hid1
 1498                         mr              r11,r4                                                  ; Get a working copy of hid4
 1499 
 1500                         li              r0,0                                                    ; Get a 0
 1501                         eqv             r2,r2,r2                                                ; Get all foxes
 1502                         
 1503                         rldimi  r10,r0,55,7                                             ; Clear I$ prefetch bits (7:8)
 1504                         
 1505                         isync
 1506                         mtspr   hid1,r10                                                ; Stick it
 1507                         mtspr   hid1,r10                                                ; Stick it again
 1508                         isync
 1509 
 1510                         rldimi  r11,r2,38,25                                    ; Disable D$ prefetch (25:25)
 1511                         
 1512                         sync
 1513                         mtspr   hid4,r11                                                ; Stick it
 1514                         isync
 1515 
 1516                         li              r3,8                                                    ; Set bit 28+32
 1517                         sldi    r3,r3,32                                                ; Make it bit 28
 1518                         or              r3,r3,r11                                               ; Turn on the flash invalidate L1D$
 1519                         
 1520                         oris    r5,r11,0x0600                                   ; Set disable L1D$ bits         
 1521                         sync
 1522                         mtspr   hid4,r3                                                 ; Invalidate
 1523                         isync
 1524         
 1525                         mtspr   hid4,r5                                                 ; Un-invalidate and disable L1D$
 1526                         isync
 1527                         
 1528                         lis             r8,GUSModeReg                                   ; Get the GUS mode ring address
 1529                         mfsprg  r0,2                                                    ; Get the feature flags
 1530                         ori             r8,r8,0x8000                                    ; Set to read data
 1531                         rlwinm. r0,r0,pfSCOMFixUpb+1,31,31              ; Set shift if we need a fix me up
 1532 
 1533                         sync
 1534 
 1535                         mtspr   scomc,r8                                                ; Request the GUS mode
 1536                         mfspr   r11,scomd                                               ; Get the GUS mode
 1537                         mfspr   r8,scomc                                                ; Get back the status (we just ignore it)
 1538                         sync
 1539                         isync                                                   
 1540 
 1541                         sld             r11,r11,r0                                              ; Fix up if needed
 1542 
 1543                         ori             r6,r11,lo16(GUSMdmapen)                 ; Set the bit that means direct L2 cache address
 1544                         lis             r8,GUSModeReg                                   ; Get GUS mode register address
 1545                                 
 1546                         sync
 1547 
 1548                         mtspr   scomd,r6                                                ; Set that we want direct L2 mode
 1549                         mtspr   scomc,r8                                                ; Tell GUS we want direct L2 mode
 1550                         mfspr   r3,scomc                                                ; Get back the status
 1551                         sync
 1552                         isync                                                   
 1553 
 1554                         li              r3,0                                                    ; Clear start point
 1555                 
 1556 cflushlp:       lis             r6,0x0040                                               ; Pick 4MB line as our target
 1557                         or              r6,r6,r3                                                ; Put in the line offset
 1558                         lwz             r5,0(r6)                                                ; Load a line
 1559                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1560                         lwz             r5,0(r6)                                                ; Load a line
 1561                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1562                         lwz             r5,0(r6)                                                ; Load a line
 1563                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1564                         lwz             r5,0(r6)                                                ; Load a line
 1565                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1566                         lwz             r5,0(r6)                                                ; Load a line
 1567                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1568                         lwz             r5,0(r6)                                                ; Load a line
 1569                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1570                         lwz             r5,0(r6)                                                ; Load a line
 1571                         addis   r6,r6,8                                                 ; Roll bit 42:44
 1572                         lwz             r5,0(r6)                                                ; Load a line
 1573 
 1574                         addi    r3,r3,128                                               ; Next line
 1575                         andis.  r5,r3,8                                                 ; Have we done enough?
 1576                         beq++   cflushlp                                                ; Not yet...
 1577                         
 1578                         sync
 1579 
 1580                         lis             r6,0x0040                                               ; Pick 4MB line as our target
 1581 
 1582 cflushx:        dcbf    0,r6                                                    ; Flush line and invalidate
 1583                         addi    r6,r6,128                                               ; Next line
 1584                         andis.  r5,r6,0x0080                                    ; Have we done enough?
 1585                         beq++   cflushx                                                 ; Keep on flushing...
 1586 
 1587                         mr              r3,r10                                                  ; Copy current hid1
 1588                         rldimi  r3,r2,54,9                                              ; Set force icbi match mode
 1589                         
 1590                         li              r6,0                                                    ; Set start if ICBI range
 1591                         isync
 1592                         mtspr   hid1,r3                                                 ; Stick it
 1593                         mtspr   hid1,r3                                                 ; Stick it again
 1594                         isync
 1595 
 1596 cflicbi:        icbi    0,r6                                                    ; Kill I$
 1597                         addi    r6,r6,128                                               ; Next line
 1598                         andis.  r5,r6,1                                                 ; Have we done them all?
 1599                         beq++   cflicbi                                                 ; Not yet...
 1600 
 1601                         lis             r8,GUSModeReg                                   ; Get GUS mode register address
 1602                                 
 1603                         sync
 1604 
 1605                         mtspr   scomd,r11                                               ; Set that we do not want direct mode
 1606                         mtspr   scomc,r8                                                ; Tell GUS we do not want direct mode
 1607                         mfspr   r3,scomc                                                ; Get back the status
 1608                         sync
 1609                         isync                                                   
 1610                         
 1611                         isync
 1612                         mtspr   hid1,r12                                                ; Restore entry hid1
 1613                         mtspr   hid1,r12                                                ; Stick it again
 1614                         isync
 1615                 
 1616                         sync
 1617                         mtspr   hid4,r4                                                 ; Restore entry hid4
 1618                         isync
 1619 
 1620                         sync
 1621                         mtmsr   r7                                                              ; Restore MSR to entry
 1622                         isync
 1623                         blr                                                                             ; Return...
 1624                         
 1625                         
 1626 
 1627 /*  Disables all caches
 1628  *
 1629  *      void cacheDisable(void)
 1630  *
 1631  *      Turns off all caches on the processor. They are not flushed.
 1632  *
 1633  */
 1634 
 1635 ;                       Force a line boundry here
 1636                         .align  5
 1637                         .globl  EXT(cacheDisable)
 1638 
 1639 LEXT(cacheDisable)
 1640 
 1641                         mfsprg  r11,2                                                   ; Get CPU specific features
 1642                         mtcrf   0x83,r11                                                ; Set feature flags
 1643                         
 1644                         bf              pfAltivecb,cdNoAlt                              ; No vectors...
 1645                         
 1646                         dssall                                                                  ; Stop streams
 1647                         
 1648 cdNoAlt:        sync
 1649                         
 1650                         btlr    pf64Bitb                                                ; No way to disable a 64-bit machine...
 1651                         
 1652                         mfspr   r5,hid0                                                 ; Get the hid
 1653                         rlwinm  r5,r5,0,dce+1,ice-1                             ; Clear the I- and D- cache enables
 1654                         mtspr   hid0,r5                                                 ; Turn off dem caches
 1655                         sync
 1656 
 1657             rlwinm.     r0,r11,0,pfL2b,pfL2b                    ; is there an L2?
 1658                         beq             cdNoL2                                                  ; Skip if no L2...
 1659 
 1660                         mfspr   r5,l2cr                                                 ; Get the L2
 1661                         rlwinm  r5,r5,0,l2e+1,31                                ; Turn off enable bit
 1662 
 1663                         b               cinlaa                                                  ; Branch to next line...
 1664 
 1665                         .align  5
 1666 cinlcc:         mtspr   l2cr,r5                                                 ; Disable L2
 1667                         sync
 1668                         isync
 1669                         b               cdNoL2                                                  ; It is off, we are done...
 1670                         
 1671 cinlaa:         b               cinlbb                                                  ; Branch to next...
 1672 
 1673 cinlbb:         sync                                                                    ; Finish memory stuff
 1674                         isync                                                                   ; Stop speculation
 1675                         b               cinlcc                                                  ; Jump back up and turn off cache...
 1676 
 1677 cdNoL2:
 1678 
 1679                         bf              pfL3b,cdNoL3                                    ; Skip down if no L3...
 1680                         
 1681                         mfspr   r5,l3cr                                                 ; Get the L3
 1682                         rlwinm  r5,r5,0,l3e+1,31                                ; Turn off enable bit
 1683                         rlwinm  r5,r5,0,l3clken+1,l3clken-1             ; Turn off cache enable bit
 1684                         mtspr   l3cr,r5                                                 ; Disable the caches
 1685                         sync
 1686                         
 1687 cdNoL3:
 1688                         blr                                                                             ; Leave...
 1689 
 1690 
 1691 /*  Initialize processor thermal monitoring  
 1692  *      void ml_thrm_init(void)
 1693  *
 1694  *      Build initial TAU registers and start them all going.
 1695  *      We ca not do this at initial start up because we need to have the processor frequency first.
 1696  *      And just why is this in assembler when it does not have to be?? Cause I am just too 
 1697  *      lazy to open up a "C" file, thats why.
 1698  */
 1699 
 1700 ;                       Force a line boundry here
 1701                         .align  5
 1702                         .globl  EXT(ml_thrm_init)
 1703 
 1704 LEXT(ml_thrm_init)
 1705 
 1706                         mfsprg  r12,0                                                   ; Get the per_proc blok
 1707                         lis             r11,hi16(EXT(gPEClockFrequencyInfo))    ; Get top of processor information
 1708                         mfsprg  r10,2                                                   ; Get CPU specific features
 1709                         ori             r11,r11,lo16(EXT(gPEClockFrequencyInfo))        ; Get bottom of processor information
 1710                         mtcrf   0x40,r10                                                ; Get the installed features
 1711 
 1712                         li              r3,lo16(thrmtidm|thrmvm)                ; Set for lower-than thermal event at 0 degrees
 1713                         bflr    pfThermalb                                              ; No thermal monitoring on this cpu
 1714                         mtspr   thrm1,r3                                                ; Do it
 1715 
 1716                         lwz             r3,thrmthrottleTemp(r12)                ; Get our throttle temprature
 1717                         rlwinm  r3,r3,31-thrmthre,thrmthrs,thrmthre     ; Position it
 1718                         ori             r3,r3,lo16(thrmvm)                              ; Set for higher-than event 
 1719                         mtspr   thrm2,r3                                                ; Set it
 1720 
 1721                         lis             r4,hi16(1000000)                                ; Top of million
 1722 ;
 1723 ;                       Note: some CPU manuals say this is processor clocks, some say bus rate.  The latter
 1724 ;                       makes more sense because otherwise we can not get over about 400MHz.
 1725 #if 0
 1726                         lwz             r3,PECFIcpurate(r11)                            ; Get the processor speed
 1727 #else
 1728                         lwz             r3,PECFIbusrate(r11)                            ; Get the bus speed
 1729 #endif
 1730                         ori             r4,r4,lo16(1000000)                             ; Bottom of million
 1731                         lis             r7,hi16(thrmsitvm>>1)                   ; Get top of highest possible value
 1732                         divwu   r3,r3,r4                                                ; Get number of cycles per microseconds
 1733                         ori             r7,r7,lo16(thrmsitvm>>1)                ; Get the bottom of the highest possible value
 1734                         addi    r3,r3,1                                                 ; Insure we have enough
 1735                         mulli   r3,r3,20                                                ; Get 20 microseconds worth of cycles
 1736                         cmplw   r3,r7                                                   ; Check against max
 1737                         ble+    smallenuf                                               ; It is ok...
 1738                         mr              r3,r7                                                   ; Saturate
 1739                         
 1740 smallenuf:      rlwinm  r3,r3,31-thrmsitve,thrmsitvs,thrmsitve  ; Position                      
 1741                         ori             r3,r3,lo16(thrmem)                              ; Enable with at least 20micro sec sample
 1742                         stw             r3,thrm3val(r12)                                ; Save this in case we need it later
 1743                         mtspr   thrm3,r3                                                ; Do it
 1744                         blr
 1745 
 1746 
 1747 /*  Set thermal monitor bounds 
 1748  *      void ml_thrm_set(unsigned int low, unsigned int high)
 1749  *
 1750  *      Set TAU to interrupt below low and above high.  A value of
 1751  *      zero disables interruptions in that direction.
 1752  */
 1753 
 1754 ;                       Force a line boundry here
 1755                         .align  5
 1756                         .globl  EXT(ml_thrm_set)
 1757 
 1758 LEXT(ml_thrm_set)
 1759 
 1760                         mfmsr   r0                                                              ; Get the MSR
 1761                         rlwinm  r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
 1762                         rlwinm  r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
 1763                         rlwinm  r6,r0,0,MSR_EE_BIT+1,MSR_EE_BIT-1       ; Clear EE bit
 1764                         mtmsr   r6
 1765                         isync
 1766 
 1767                         mfsprg  r12,0                                                   ; Get the per_proc blok
 1768 
 1769                         rlwinm. r6,r3,31-thrmthre,thrmthrs,thrmthre     ; Position it and see if enabled
 1770                         mfsprg  r9,2                                                    ; Get CPU specific features
 1771                         stw             r3,thrmlowTemp(r12)                             ; Set the low temprature
 1772                         mtcrf   0x40,r9                                                 ; See if we can thermal this machine
 1773                         rlwinm  r9,r9,(((31-thrmtie)+(pfThermIntb+1))&31),thrmtie,thrmtie       ; Set interrupt enable if this machine can handle it
 1774                         bf              pfThermalb,tsetcant                             ; No can do...
 1775                         beq             tsetlowo                                                ; We are setting the low off...
 1776                         ori             r6,r6,lo16(thrmtidm|thrmvm)             ; Set the lower-than and valid bit
 1777                         or              r6,r6,r9                                                ; Set interruption request if supported
 1778 
 1779 tsetlowo:       mtspr   thrm1,r6                                                ; Cram the register
 1780                         
 1781                         rlwinm. r6,r4,31-thrmthre,thrmthrs,thrmthre     ; Position it and see if enabled
 1782                         stw             r4,thrmhighTemp(r12)                    ; Set the high temprature
 1783                         beq             tsethigho                                               ; We are setting the high off...
 1784                         ori             r6,r6,lo16(thrmvm)                              ; Set valid bit
 1785                         or              r6,r6,r9                                                ; Set interruption request if supported
 1786 
 1787 tsethigho:      mtspr   thrm2,r6                                                ; Cram the register
 1788 
 1789 tsetcant:       mtmsr   r0                                                              ; Reenable interruptions
 1790                         blr                                                                             ; Leave...
 1791 
 1792 /*  Read processor temprature  
 1793  *      unsigned int ml_read_temp(void)
 1794  *
 1795  */
 1796 
 1797 ;                       Force a line boundry here
 1798                         .align  5
 1799                         .globl  EXT(ml_read_temp)
 1800 
 1801 LEXT(ml_read_temp)
 1802 
 1803                         mfmsr   r9                                                              ; Save the MSR
 1804                         li              r5,15                                                   ; Starting point for ranging (start at 15 so we do not overflow)
 1805                         rlwinm  r9,r9,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
 1806                         rlwinm  r9,r9,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
 1807                         rlwinm  r8,r9,0,MSR_EE_BIT+1,MSR_EE_BIT-1       ; Turn off interruptions
 1808                         mfsprg  r7,2                                                    ; Get CPU specific features
 1809                         mtmsr   r8                                                              ; Do not allow interruptions
 1810                         mtcrf   0x40,r7                                                 ; See if we can thermal this machine
 1811                         bf              pfThermalb,thrmcant                             ; No can do...
 1812 
 1813                         mfspr   r11,thrm1                                               ; Save thrm1
 1814 
 1815 thrmrange:      rlwinm  r4,r5,31-thrmthre,thrmthrs,thrmthre     ; Position it
 1816                         ori             r4,r4,lo16(thrmtidm|thrmvm)             ; Flip on the valid bit and make comparision for less than
 1817 
 1818                         mtspr   thrm1,r4                                                ; Set the test value
 1819                         
 1820 thrmreada:      mfspr   r3,thrm1                                                ; Get the thermal register back
 1821                         rlwinm. r0,r3,0,thrmtiv,thrmtiv                 ; Has it settled yet?
 1822                         beq+    thrmreada                                               ; Nope...
 1823 
 1824                         rlwinm. r0,r3,0,thrmtin,thrmtin                 ; Are we still under the threshold?
 1825                         bne             thrmsearch                                              ; No, we went over...
 1826 
 1827                         addi    r5,r5,16                                                ; Start by trying every 16 degrees
 1828                         cmplwi  r5,127                                                  ; Have we hit the max?
 1829                         blt-    thrmrange                                               ; Got some more to do...
 1830 
 1831 thrmsearch:     rlwinm  r4,r5,31-thrmthre,thrmthrs,thrmthre     ; Position it
 1832                         ori             r4,r4,lo16(thrmtidm|thrmvm)             ; Flip on the valid bit and make comparision for less than
 1833                         
 1834                         mtspr   thrm1,r4                                                ; Set the test value
 1835                         
 1836 thrmread:       mfspr   r3,thrm1                                                ; Get the thermal register back
 1837                         rlwinm. r0,r3,0,thrmtiv,thrmtiv                 ; Has it settled yet?
 1838                         beq+    thrmread                                                ; Nope...
 1839                         
 1840                         rlwinm. r0,r3,0,thrmtin,thrmtin                 ; Are we still under the threshold?
 1841                         beq             thrmdone                                                ; No, we hit it...
 1842                         addic.  r5,r5,-1                                                ; Go down a degree
 1843                         bge+    thrmsearch                                              ; Try again (until we are below freezing)...
 1844                         
 1845 thrmdone:       addi    r3,r5,1                                                 ; Return the temprature (bump it up to make it correct)
 1846                         mtspr   thrm1,r11                                               ; Restore the thermal register
 1847                         mtmsr   r9                                                              ; Re-enable interruptions
 1848                         blr                                                                             ; Leave...
 1849                         
 1850 thrmcant:       eqv             r3,r3,r3                                                ; Return bogus temprature because we can not read it
 1851                         mtmsr   r9                                                              ; Re-enable interruptions
 1852                         blr                                                                             ; Leave...
 1853 
 1854 /*  Throttle processor speed up or down
 1855  *      unsigned int ml_throttle(unsigned int step)
 1856  *
 1857  *      Returns old speed and sets new.  Both step and return are values from 0 to
 1858  *      255 that define number of throttle steps, 0 being off and "ictcfim" is max * 2.
 1859  *
 1860  */
 1861 
 1862 ;                       Force a line boundry here
 1863                         .align  5
 1864                         .globl  EXT(ml_throttle)
 1865 
 1866 LEXT(ml_throttle)
 1867 
 1868                         mfmsr   r9                                                              ; Save the MSR
 1869                         rlwinm  r9,r9,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
 1870                         rlwinm  r9,r9,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
 1871                         rlwinm  r8,r9,0,MSR_EE_BIT+1,MSR_EE_BIT-1       ; Turn off interruptions
 1872                         cmplwi  r3,lo16(ictcfim>>1)                             ; See if we are going too far                                   
 1873                         mtmsr   r8                                                              ; Do not allow interruptions    
 1874                         isync           
 1875                         ble+    throtok                                                 ; Throttle value is ok...
 1876                         li              r3,lo16(ictcfim>>1)                             ; Set max
 1877 
 1878 throtok:        rlwinm. r4,r3,1,ictcfib,ictcfie                 ; Set the throttle
 1879                         beq             throtoff                                                ; Skip if we are turning it off...
 1880                         ori             r4,r4,lo16(thrmvm)                              ; Turn on the valid bit
 1881                         
 1882 throtoff:       mfspr   r3,ictc                                                 ; Get the old throttle
 1883                         mtspr   ictc,r4                                                 ; Set the new
 1884                         rlwinm  r3,r3,31,1,31                                   ; Shift throttle value over
 1885                         mtmsr   r9                                                              ; Restore interruptions
 1886                         blr                                                                             ; Return...
 1887 
 1888 /*
 1889 **      ml_get_timebase()
 1890 **
 1891 **      Entry   - R3 contains pointer to 64 bit structure.
 1892 **
 1893 **      Exit    - 64 bit structure filled in.
 1894 **
 1895 */
 1896 ;                       Force a line boundry here
 1897                         .align  5
 1898                         .globl  EXT(ml_get_timebase)
 1899 
 1900 LEXT(ml_get_timebase)
 1901 
 1902 loop:
 1903                         mftbu   r4
 1904                         mftb    r5
 1905                         mftbu   r6
 1906                         cmpw    r6, r4
 1907                         bne-    loop
 1908                         
 1909                         stw     r4, 0(r3)
 1910                         stw     r5, 4(r3)
 1911                         
 1912                         blr
 1913 
 1914 /*
 1915  *              unsigned int cpu_number(void)
 1916  *
 1917  *                      Returns the current cpu number. 
 1918  */
 1919 
 1920                         .align  5
 1921                         .globl  EXT(cpu_number)
 1922 
 1923 LEXT(cpu_number)
 1924                         mfsprg  r4,0                                                    ; Get per-proc block
 1925                         lhz             r3,PP_CPU_NUMBER(r4)                    ; Get CPU number 
 1926                         blr                                                                             ; Return...
 1927 
 1928 
 1929 /*
 1930  *              void set_machine_current_act(thread_act_t)
 1931  *
 1932  *                      Set the current activation
 1933  */
 1934                         .align  5
 1935                         .globl  EXT(set_machine_current_act)
 1936 
 1937 LEXT(set_machine_current_act)
 1938 
 1939                         mtsprg  1,r3                                                    ; Set spr1 with the active thread
 1940                         blr                                                                             ; Return...
 1941 
 1942 /*
 1943  *              thread_t current_act(void)
 1944  *              thread_t current_thread(void)
 1945  *
 1946  *
 1947  *                      Return the current thread for outside components.
 1948  */
 1949                         .align  5
 1950                         .globl  EXT(current_act)
 1951                         .globl  EXT(current_thread)
 1952 
 1953 LEXT(current_act)
 1954 LEXT(current_thread)
 1955 
 1956                         mfsprg  r3,1
 1957                         blr
 1958 
 1959                         .align  5
 1960                         .globl  EXT(clock_get_uptime)
 1961 LEXT(clock_get_uptime)
 1962 1:                      mftbu   r9
 1963                         mftb    r0
 1964                         mftbu   r11
 1965                         cmpw    r11,r9
 1966                         bne-    1b
 1967                         stw             r0,4(r3)
 1968                         stw             r9,0(r3)
 1969                         blr
 1970 
 1971                 
 1972                         .align  5
 1973                         .globl  EXT(mach_absolute_time)
 1974 LEXT(mach_absolute_time)
 1975 1:                      mftbu   r3
 1976                         mftb    r4
 1977                         mftbu   r0
 1978                         cmpw    r0,r3
 1979                         bne-    1b  
 1980                         blr
 1981 
 1982 /*
 1983 **      ml_sense_nmi()
 1984 **
 1985 */
 1986 ;                       Force a line boundry here
 1987                         .align  5
 1988                         .globl  EXT(ml_sense_nmi)
 1989 
 1990 LEXT(ml_sense_nmi)
 1991 
 1992                         blr                                                                             ; Leave...
 1993 
 1994 /*
 1995 **      ml_set_processor_speed()
 1996 **
 1997 */
 1998 ;                       Force a line boundry here
 1999                         .align  5
 2000                         .globl  EXT(ml_set_processor_speed)
 2001 
 2002 LEXT(ml_set_processor_speed)
 2003                         mfsprg  r5, 0                                                           ; Get the per_proc_info
 2004 
 2005                         cmpli   cr0, r3, 0                                                      ; Turn off BTIC before low speed
 2006                         beq     sps1
 2007                         mfspr   r4, hid0                                                        ; Get the current hid0 value
 2008                         rlwinm  r4, r4, 0, btic+1, btic-1                                       ; Clear the BTIC bit
 2009                         sync
 2010                         mtspr   hid0, r4                                                        ; Set the new hid0 value
 2011                         isync
 2012                         sync
 2013 
 2014 sps1:
 2015                         mfspr   r4, hid1                                                        ; Get the current PLL settings
 2016                         rlwimi  r4, r3, 31-hid1ps, hid1ps, hid1ps                               ; Copy the PLL Select bit
 2017                         stw     r4, pfHID1(r5)                                                  ; Save the new hid1 value
 2018                         mtspr   hid1, r4                                                        ; Select desired PLL
 2019 
 2020                         cmpli   cr0, r3, 0                                                      ; Restore BTIC after high speed
 2021                         bne     sps2
 2022                         lwz     r4, pfHID0(r5)                                                  ; Load the hid0 value
 2023                         sync
 2024                         mtspr   hid0, r4                                                        ; Set the hid0 value
 2025                         isync
 2026                         sync
 2027 
 2028 sps2:
 2029                         blr
 2030 
 2031 /*
 2032 **      ml_set_processor_voltage()
 2033 **
 2034 */
 2035 ;                       Force a line boundry here
 2036                         .align  5
 2037                         .globl  EXT(ml_set_processor_voltage)
 2038 
 2039 LEXT(ml_set_processor_voltage)
 2040                         mfspr   r4, hid2                                                        ; Get HID2 value
 2041                         rlwimi  r4, r3, 31-hid2vmin, hid2vmin, hid2vmin                         ; Insert the voltage mode bit
 2042                         mtspr   hid2, r4                                                        ; Set the voltage mode
 2043                         sync                                                                    ; Make sure it is done
 2044                         blr

Cache object: 36e45271b7ceb591f21371b2afff3056


[ 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.