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 #pragma ident   "%Z%%M% %I%     %E% SMI"
  28 
  29 /*
  30  * Assembly language support for px driver
  31  */
  32  
  33 #include <sys/asm_linkage.h>
  34 #include <sys/machthread.h>
  35 #include <sys/privregs.h>
  36 
  37 /*LINTLIBRARY*/
  38 
  39 #if defined(lint)
  40 
  41 /*ARGSUSED*/
  42 int
  43 px_phys_peek_4u(size_t size, uint64_t paddr, uint64_t *value, int type)
  44 { return (0); }
  45 
  46 /*ARGSUSED*/
  47 int
  48 px_phys_poke_4u(size_t size, uint64_t paddr, uint64_t *value, int type)
  49 { return (0); }
  50 
  51 #else /* lint */
  52 
  53 ! px_phys_peek_4u: Do physical address read.
  54 !
  55 ! %o0 is size in bytes - Must be 8, 4, 2 or 1.  Invalid sizes default to 1.
  56 ! %o1 is address to read
  57 ! %o2 is address to save value into
  58 ! %o3 is 0 for little endian, non-zero for big endian
  59 !
  60 ! To be called from an on_trap environment.
  61 ! Interrupts will be disabled for the duration of the read, to prevent
  62 ! an interrupt from raising the trap level to 1 and then a possible
  63 ! data access exception being delivered while the trap level > 0.
  64 !
  65 ! Always returns success (0) in %o0
  66 !
  67 ! Assumes alignment is correct and that on_trap handling has been installed
  68 
  69         ENTRY(px_phys_peek_4u)
  70 
  71         rdpr    %pstate, %o4            ! Disable interrupts if not already
  72         andcc   %o4, PSTATE_IE, %g2     ! Save original state first
  73         bz      .peek_ints_disabled
  74         nop
  75         wrpr    %o4, PSTATE_IE, %pstate
  76 .peek_ints_disabled:
  77 
  78         tst     %o3                     ! Set up %asi with modifier for
  79         movz    %xcc, ASI_IOL, %g1      ! Big/little endian physical space
  80         movnz   %xcc, ASI_IO, %g1
  81         mov     %g1, %asi
  82 
  83         cmp     %o0, 8                  ! 64-bit?
  84         bne     .peek_int
  85         cmp     %o0, 4                  ! 32-bit?
  86         ldxa    [%o1]%asi, %g1
  87         ba      .peekdone
  88         stx     %g1, [%o2]
  89 
  90 .peek_int:
  91         bne     .peek_half
  92         cmp     %o0, 2                  ! 16-bit?
  93         lduwa   [%o1]%asi, %g1
  94         ba      .peekdone
  95         stuw    %g1, [%o2]
  96         
  97 .peek_half:
  98         bne     .peek_byte
  99         nop
 100         lduha   [%o1]%asi, %g1
 101         ba      .peekdone
 102         stuh    %g1, [%o2]
 103 
 104 .peek_byte:
 105         lduba   [%o1]%asi, %g1  ! 8-bit!
 106         stub    %g1, [%o2]
 107  
 108 .peekdone:
 109         membar  #Sync                   ! Make sure the loads take
 110         tst     %g2                     ! No need to reenable interrupts
 111         bz      .peek_ints_done         !       if not enabled at entry
 112         rdpr    %pstate, %o4
 113         wrpr    %o4, PSTATE_IE, %pstate
 114 .peek_ints_done:
 115         mov     %g0, %o0
 116         retl
 117         nop
 118         SET_SIZE(px_phys_peek_4u)
 119 
 120 
 121 ! px_phys_poke_4u: Do physical address write.
 122 !
 123 ! %o0 is size in bytes - Must be 8, 4, 2 or 1.  Invalid sizes default to 1.
 124 ! %o1 is address to write to
 125 ! %o2 is address to read from
 126 ! %o3 is 0 for little endian, non-zero for big endian
 127 !
 128 ! Always returns success (0) in %o0
 129 !
 130 ! Assumes alignment is correct and that on_trap handling has been installed
 131 
 132         ENTRY(px_phys_poke_4u)
 133 
 134         tst     %o3
 135         movz    %xcc, ASI_IOL, %g1      ! Big/little endian physical space
 136         movnz   %xcc, ASI_IO, %g1
 137         mov     %g1, %asi
 138 
 139         cmp     %o0, 8                  ! 64 bit?
 140         bne     .poke_int
 141         cmp     %o0, 4                  ! 32-bit?
 142         ldx     [%o2], %g1
 143         ba      .pokedone
 144         stxa    %g1, [%o1]%asi
 145 
 146 .poke_int:
 147         bne     .poke_half
 148         cmp     %o0, 2                  ! 16-bit?
 149         lduw    [%o2], %g1
 150         ba      .pokedone
 151         stuwa   %g1, [%o1]%asi
 152 
 153 .poke_half:
 154         bne     .poke_byte
 155         nop
 156         lduh    [%o2], %g1
 157         ba      .pokedone
 158         stuha   %g1, [%o1]%asi
 159 
 160 .poke_byte:
 161         ldub    [%o2], %g1              ! 8-bit!
 162         stuba   %g1, [%o1]%asi
 163 
 164 .pokedone:
 165         membar  #Sync
 166         retl
 167         mov     %g0, %o0
 168         SET_SIZE(px_phys_poke_4u)
 169  
 170 #endif