1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License, Version 1.0 only
   6  * (the "License").  You may not use this file except in compliance
   7  * with the License.
   8  *
   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Assembly language support for px driver
  29  */
  30  
  31 #include <sys/asm_linkage.h>
  32 #include <sys/machthread.h>
  33 #include <sys/privregs.h>
  34 
  35 /*LINTLIBRARY*/
  36 
  37 ! px_phys_peek_4u: Do physical address read.
  38 !
  39 ! %o0 is size in bytes - Must be 8, 4, 2 or 1.  Invalid sizes default to 1.
  40 ! %o1 is address to read
  41 ! %o2 is address to save value into
  42 ! %o3 is 0 for little endian, non-zero for big endian
  43 !
  44 ! To be called from an on_trap environment.
  45 ! Interrupts will be disabled for the duration of the read, to prevent
  46 ! an interrupt from raising the trap level to 1 and then a possible
  47 ! data access exception being delivered while the trap level > 0.
  48 !
  49 ! Always returns success (0) in %o0
  50 !
  51 ! Assumes alignment is correct and that on_trap handling has been installed
  52 
  53         ENTRY(px_phys_peek_4u)
  54 
  55         rdpr    %pstate, %o4            ! Disable interrupts if not already
  56         andcc   %o4, PSTATE_IE, %g2     ! Save original state first
  57         bz      .peek_ints_disabled
  58         nop
  59         wrpr    %o4, PSTATE_IE, %pstate
  60 .peek_ints_disabled:
  61 
  62         tst     %o3                     ! Set up %asi with modifier for
  63         movz    %xcc, ASI_IOL, %g1      ! Big/little endian physical space
  64         movnz   %xcc, ASI_IO, %g1
  65         mov     %g1, %asi
  66 
  67         cmp     %o0, 8                  ! 64-bit?
  68         bne     .peek_int
  69         cmp     %o0, 4                  ! 32-bit?
  70         ldxa    [%o1]%asi, %g1
  71         ba      .peekdone
  72         stx     %g1, [%o2]
  73 
  74 .peek_int:
  75         bne     .peek_half
  76         cmp     %o0, 2                  ! 16-bit?
  77         lduwa   [%o1]%asi, %g1
  78         ba      .peekdone
  79         stuw    %g1, [%o2]
  80         
  81 .peek_half:
  82         bne     .peek_byte
  83         nop
  84         lduha   [%o1]%asi, %g1
  85         ba      .peekdone
  86         stuh    %g1, [%o2]
  87 
  88 .peek_byte:
  89         lduba   [%o1]%asi, %g1  ! 8-bit!
  90         stub    %g1, [%o2]
  91  
  92 .peekdone:
  93         membar  #Sync                   ! Make sure the loads take
  94         tst     %g2                     ! No need to reenable interrupts
  95         bz      .peek_ints_done         !       if not enabled at entry
  96         rdpr    %pstate, %o4
  97         wrpr    %o4, PSTATE_IE, %pstate
  98 .peek_ints_done:
  99         mov     %g0, %o0
 100         retl
 101         nop
 102         SET_SIZE(px_phys_peek_4u)
 103 
 104 
 105 ! px_phys_poke_4u: Do physical address write.
 106 !
 107 ! %o0 is size in bytes - Must be 8, 4, 2 or 1.  Invalid sizes default to 1.
 108 ! %o1 is address to write to
 109 ! %o2 is address to read from
 110 ! %o3 is 0 for little endian, non-zero for big endian
 111 !
 112 ! Always returns success (0) in %o0
 113 !
 114 ! Assumes alignment is correct and that on_trap handling has been installed
 115 
 116         ENTRY(px_phys_poke_4u)
 117 
 118         tst     %o3
 119         movz    %xcc, ASI_IOL, %g1      ! Big/little endian physical space
 120         movnz   %xcc, ASI_IO, %g1
 121         mov     %g1, %asi
 122 
 123         cmp     %o0, 8                  ! 64 bit?
 124         bne     .poke_int
 125         cmp     %o0, 4                  ! 32-bit?
 126         ldx     [%o2], %g1
 127         ba      .pokedone
 128         stxa    %g1, [%o1]%asi
 129 
 130 .poke_int:
 131         bne     .poke_half
 132         cmp     %o0, 2                  ! 16-bit?
 133         lduw    [%o2], %g1
 134         ba      .pokedone
 135         stuwa   %g1, [%o1]%asi
 136 
 137 .poke_half:
 138         bne     .poke_byte
 139         nop
 140         lduh    [%o2], %g1
 141         ba      .pokedone
 142         stuha   %g1, [%o1]%asi
 143 
 144 .poke_byte:
 145         ldub    [%o2], %g1              ! 8-bit!
 146         stuba   %g1, [%o1]%asi
 147 
 148 .pokedone:
 149         membar  #Sync
 150         retl
 151         mov     %g0, %o0
 152         SET_SIZE(px_phys_poke_4u)
 153