1 /* $Id: sparc.h,v 1.3 2010/06/05 19:37:56 fredette Exp $ */ 2 3 /* tme/ic/sparc.h - public header file for SPARC emulation */ 4 5 /* 6 * Copyright (c) 2005 Matt Fredette 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by Matt Fredette. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 #ifndef _TME_IC_SPARC_H 37 #define _TME_IC_SPARC_H 38 39 #include <tme/common.h> 40 _TME_RCSID("$Id: sparc.h,v 1.3 2010/06/05 19:37:56 fredette Exp $"); 41 42 /* includes: */ 43 #include <tme/element.h> 44 #include <tme/generic/bus.h> 45 46 /* macros: */ 47 48 /* the sparc32 address spaces: */ 49 #define TME_SPARC32_ASI_UI (0x08) 50 #define TME_SPARC32_ASI_SI (0x09) 51 #define TME_SPARC32_ASI_UD (0x0A) 52 #define TME_SPARC32_ASI_SD (0x0B) 53 54 /* common sparc64 address space identifier flags: */ 55 #define TME_SPARC64_ASI_FLAG_SECONDARY (0x01) 56 #define TME_SPARC64_ASI_FLAG_NO_FAULT (0x02) 57 #define TME_SPARC64_ASI_FLAG_LITTLE (0x08) 58 #define TME_SPARC64_ASI_FLAG_UNRESTRICTED (0x80) 59 60 /* the sparc address space masks: */ 61 /* bits 24 through 31 must be zero - except when 62 TME_SPARC_ASI_MASK_FLAG_UNDEF is set, which is what makes an ASI 63 mask undefined. 64 65 bits 16 through 23 are the original ASI. 66 67 ASIs are divided into two categories: special and normal. an 68 address space mask from a special ASI never matches an address 69 space mask from a normal ASI, and vice-versa. 70 71 if bit 15 is set, the ASI is special. an address space mask from a 72 special ASI never matches an address space mask from a different 73 ASI. 74 75 if bit 15 is clear, the ASI is normal. an address space mask from 76 a normal ASI may match address space masks from different normal 77 ASIs. 78 79 each of the bits eight through 14 identifies an address 80 translation. an address translation is usually the combination of 81 an address space with privilege. 82 83 an address space mask generated by a memory instruction has exactly 84 one of these bits set, since the instruction's ASI+privilege 85 combination can translate addresses in only one way. an address 86 space mask generated from an MMU mapping has at least one of these 87 bits set, for the ASI+privilege from the instruction that caused 88 the mapping lookup. if the same mapping is also valid for other 89 ASI+privilege combinations that can be added to the address space 90 mask, the bits for their address translations can also be set. 91 92 the meanings of the address translation bits must be consistent 93 across all normal ASIs, since these bits are the only ones that are 94 significant when address masks from two normal ASIs are compared. 95 since an address mask from a special ASI can never match an address 96 mask from a different ASI, the address translation bits for a 97 special ASI are effectively unique to that ASI, and so there are 98 only two of them - privileged and nonprivileged. 99 100 bits zero through seven are available for ASI-specific use, and 101 they never affect ASI mask comparison: */ 102 #define TME_SPARC_ASI_MASK_FLAG_SPECIAL TME_BIT(15) 103 #define TME_SPARC_ASI_MASK_FLAG_UNDEF TME_BIT(24) 104 #define TME_SPARC_ASI_MASK_RAW(asi) \ 105 (((tme_uint32_t) (asi)) \ 106 * (TME_SPARC_ASI_MASK_FLAG_SPECIAL * 2)) 107 #define TME_SPARC_ASI_MASK(asi, xlat) \ 108 (TME_SPARC_ASI_MASK_RAW(asi) \ 109 + TME_BIT(8 + (xlat))) 110 #define TME_SPARC_ASI_MASK_SPECIAL(asi, priv) \ 111 (TME_SPARC_ASI_MASK(asi, (priv) != 0) \ 112 + TME_SPARC_ASI_MASK_FLAG_SPECIAL) 113 #define TME_SPARC_ASI_MASK_WHICH(asi_mask) \ 114 ((asi_mask) \ 115 / (TME_SPARC_ASI_MASK_FLAG_SPECIAL * 2)) 116 #define TME_SPARC_ASI_MASK_FLAGS_AVAIL \ 117 (TME_SPARC_ASI_MASK(0, 0) - 1) 118 119 /* this evaluates to nonzero iff the two ASI masks overlap: */ 120 /* NB: asi_mask0 must be a single ASI mask from a memory instruction 121 (in other words, it must have exactly one address translation bit 122 set), and it may also have TME_SPARC_ASI_MASK_FLAG_UNDEF set. . 123 if asi_mask1 is a binary-OR of multiple ASI masks, either all of 124 them must be for normal ASIs, or all of them must be for the same 125 special ASI. asi_mask1 must not have TME_SPARC_ASI_MASK_FLAG_UNDEF 126 set: */ 127 #define TME_SPARC_ASI_MASK_OVERLAP(asi_mask0, asi_mask1) \ 128 ((((asi_mask0) \ 129 ^ (asi_mask1)) \ 130 & ((((tme_uint32_t) \ 131 (tme_int32_t) \ 132 (tme_int16_t) \ 133 (asi_mask0)) \ 134 | TME_SPARC_ASI_MASK_FLAG_SPECIAL \ 135 | TME_SPARC_ASI_MASK_FLAG_UNDEF) \ 136 & (0 - TME_SPARC_ASI_MASK(0, 0)))) == 0) 137 138 /* this evaluates to nonzero iff this TLB entry allows access to an 139 ASI, given by mask: */ 140 #define TME_SPARC_TLB_ASI_MASK_OK(tlb, asi_mask) \ 141 TME_SPARC_ASI_MASK_OVERLAP(asi_mask, (tlb)->tme_sparc_tlb_asi_mask) 142 143 /* sparc32 has four required address translations, corresponding to 144 the four required ASIs: supervisor data, supervisor instruction, 145 user data, user instruction. all normal ASIs must use one of these 146 address translations, and so you must specify one of the required 147 ASIs to build an address space mask for a normal ASI: */ 148 /* NB: this assumes that the four required ASIs are dense, and start 149 with TME_SPARC32_ASI_UI: */ 150 #define TME_SPARC32_ASI_MASK(asi, asi_required) \ 151 TME_SPARC_ASI_MASK(asi, (asi_required) - TME_SPARC32_ASI_UI) 152 153 /* sparc32 address space mask flags: */ 154 #define TME_SPARC32_ASI_MASK_FLAG_SPECIAL (0x01) 155 156 /* for convenience we also provide the address space masks for the 157 sparc32 required ASIs here: */ 158 #define TME_SPARC32_ASI_MASK_UI TME_SPARC32_ASI_MASK(TME_SPARC32_ASI_UI, TME_SPARC32_ASI_UI) 159 #define TME_SPARC32_ASI_MASK_SI TME_SPARC32_ASI_MASK(TME_SPARC32_ASI_SI, TME_SPARC32_ASI_SI) 160 #define TME_SPARC32_ASI_MASK_UD TME_SPARC32_ASI_MASK(TME_SPARC32_ASI_UD, TME_SPARC32_ASI_UD) 161 #define TME_SPARC32_ASI_MASK_SD TME_SPARC32_ASI_MASK(TME_SPARC32_ASI_SD, TME_SPARC32_ASI_SD) 162 163 /* sparc64 address space masks use the common sparc64 address space 164 identifier flags for address space mask flags, plus these other 165 address space mask flags. these other flags can't conflict with 166 the common flags (which are essentially architected), and the same 167 flag value (common or other) may have different names and meanings 168 in an ASI mask from an instruction and one from a TLB entry: */ 169 #define TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS (0x04) 170 #define TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER (0x10) 171 #define TME_SPARC64_ASI_MASK_FLAG_SPECIAL (0x20) 172 #define TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS (0x40) 173 #define TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE (TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS) 174 175 /* sparc64 has five architected address translations: privileged 176 primary, privileged secondary, nonprivileged primary, nonprivileged 177 secondary, and nucleus. all of these are required, except for 178 nucleus. all normal ASIs must use one of these translations. 179 180 however, note that sparc64 address translation, by itself, doesn't 181 depend on privilege - the architected mapping from ASI to context 182 doesn't consider it. only address protection depends on privilege. 183 (this isn't necessarily true on sparc32 - a sparc32 without a 184 reference MMU could translate addresses completely differently for 185 its different architected ASIs.) 186 187 this means that a sparc64 normal ASI's address translation check 188 will be done completely by the context comparison, leaving only 189 privilege to be represented as generic sparc address space mask 190 address translations: */ 191 #define TME_SPARC64_ASI_MASK_USER TME_SPARC_ASI_MASK(0 /* asi */, 0) 192 #define TME_SPARC64_ASI_MASK_PRIV TME_SPARC_ASI_MASK(0 /* asi */, 1) 193 #define TME_SPARC64_ASI_MASK(asi, asi_mask_flags) \ 194 ((asi_mask_flags) \ 195 + TME_SPARC_ASI_MASK(asi, \ 196 (((asi_mask_flags) \ 197 & TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER) == 0))) 198 199 /* for convenience, we provide macros to build address space masks for 200 the architected ASIs given ASI mask flags here: */ 201 #define TME_SPARC64_ASI_MASK_NUCLEUS(asi_flag_little) \ 202 TME_SPARC64_ASI_MASK(0x04 + (asi_flag_little), \ 203 (TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS + (asi_flag_little))) 204 #define TME_SPARC64_ASI_MASK_REQUIRED_UNRESTRICTED(asi_flags) \ 205 TME_SPARC64_ASI_MASK(TME_SPARC64_ASI_FLAG_UNRESTRICTED \ 206 + ((asi_flags) \ 207 & (TME_SPARC64_ASI_FLAG_SECONDARY \ 208 + TME_SPARC64_ASI_FLAG_NO_FAULT \ 209 + TME_SPARC64_ASI_FLAG_LITTLE)), \ 210 asi_flags) 211 212 /* these busy and unbusy a TLB entry: */ 213 #define tme_sparc_tlb_busy(tlb) \ 214 tme_bus_tlb_busy(&(tlb)->tme_sparc_tlb_bus_tlb) 215 #define tme_sparc_tlb_unbusy(tlb) \ 216 tme_bus_tlb_unbusy(&(tlb)->tme_sparc_tlb_bus_tlb) 217 218 /* the minimum and maximum IPL levels: */ 219 #define TME_SPARC_IPL_NONE (0) 220 #define TME_SPARC_IPL_MIN (1) 221 #define TME_SPARC_IPL_MAX (15) 222 #define TME_SPARC_IPL_NMI (15) 223 224 /* this indexes an sparc bus router array for an sparc with a port size 225 of 8 * (2 ^ siz_lg2) bits: */ 226 #define TME_SPARC_BUS_ROUTER_INDEX(siz_lg2, cycle_size, address)\ 227 ((( \ 228 /* by the maximum cycle size: */ \ 229 ((cycle_size) - 1) \ 230 \ 231 /* by the address alignment: */ \ 232 << siz_lg2) \ 233 + ((address) & ((1 << (siz_lg2)) - 1))) \ 234 \ 235 /* factor in the size of the generic bus router array: */ \ 236 * TME_BUS_ROUTER_SIZE(siz_lg2)) 237 238 /* this gives the number of entries that must be in a generic bus 239 router array for a device with a bus size of 8 * (2 ^ siz_lg2) 240 bits: */ 241 #define TME_SPARC_BUS_ROUTER_SIZE(siz_lg2) \ 242 TME_SPARC_BUS_ROUTER_INDEX(siz_lg2, (1 << (siz_lg2)) + 1, 0) 243 244 /* structures: */ 245 246 /* an sparc TLB entry: */ 247 struct tme_sparc_tlb { 248 249 /* the generic bus TLB associated with this TLB entry: */ 250 struct tme_bus_tlb tme_sparc_tlb_bus_tlb; 251 #define tme_sparc_tlb_addr_first tme_sparc_tlb_bus_tlb.tme_bus_tlb_addr_first 252 #define tme_sparc_tlb_addr_last tme_sparc_tlb_bus_tlb.tme_bus_tlb_addr_last 253 #define tme_sparc_tlb_bus_rwlock tme_sparc_tlb_bus_tlb.tme_bus_tlb_rwlock 254 #define tme_sparc_tlb_cycles_ok tme_sparc_tlb_bus_tlb.tme_bus_tlb_cycles_ok 255 #define tme_sparc_tlb_addr_offset tme_sparc_tlb_bus_tlb.tme_bus_tlb_addr_offset 256 #define tme_sparc_tlb_addr_shift tme_sparc_tlb_bus_tlb.tme_bus_tlb_addr_shift 257 #define tme_sparc_tlb_emulator_off_read tme_sparc_tlb_bus_tlb.tme_bus_tlb_emulator_off_read 258 #define tme_sparc_tlb_emulator_off_write tme_sparc_tlb_bus_tlb.tme_bus_tlb_emulator_off_write 259 260 /* any link for this TLB entry: */ 261 tme_uint32_t tme_sparc_tlb_link; 262 263 /* the context for this TLB entry: */ 264 tme_bus_context_t tme_sparc_tlb_context; 265 266 /* an ASI mask: */ 267 tme_uint32_t tme_sparc_tlb_asi_mask; 268 }; 269 270 /* an sparc bus connection: */ 271 struct tme_sparc_bus_connection { 272 273 /* a generic bus connection: */ 274 struct tme_bus_connection tme_sparc_bus_connection; 275 276 /* the sparc interrupt function: */ 277 int (*tme_sparc_bus_interrupt) _TME_P((struct tme_sparc_bus_connection *, unsigned int)); 278 279 /* the sparc TLB entry filler: */ 280 int (*tme_sparc_bus_tlb_fill) _TME_P((struct tme_sparc_bus_connection *, struct tme_sparc_tlb *, 281 tme_uint32_t, tme_bus_addr_t, unsigned int)); 282 283 /* the sparc FPU strict-compliance enabler: */ 284 void (*tme_sparc_bus_fpu_strict) _TME_P((struct tme_sparc_bus_connection *, unsigned int)); 285 }; 286 287 /* globals: */ 288 extern _tme_const tme_bus_lane_t tme_sparc_router_32[]; 289 290 #endif /* !_TME_IC_SPARC_H */ 291