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