| 1 | /*	$OpenBSD: ctlreg.h,v 1.33 2025/07/16 07:15:42 jsg Exp $	*/ |
| 2 | /*	$NetBSD: ctlreg.h,v 1.28 2001/08/06 23:55:34 eeh Exp $ */ |
| 3 | |
| 4 | /* |
| 5 | * Copyright (c) 1996-2001 Eduardo Horvath |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND |
| 14 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 16 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE |
| 17 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 18 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 19 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 20 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 21 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 22 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 23 | * SUCH DAMAGE. |
| 24 | * |
| 25 | */ |
| 26 | /* |
| 27 | * Copyright (c) 2001 Jake Burkholder. |
| 28 | * All rights reserved. |
| 29 | * |
| 30 | * Redistribution and use in source and binary forms, with or without |
| 31 | * modification, are permitted provided that the following conditions |
| 32 | * are met: |
| 33 | * 1. Redistributions of source code must retain the above copyright |
| 34 | * notice, this list of conditions and the following disclaimer. |
| 35 | * 2. Redistributions in binary form must reproduce the above copyright |
| 36 | * notice, this list of conditions and the following disclaimer in the |
| 37 | * documentation and/or other materials provided with the distribution. |
| 38 | * |
| 39 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 40 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 42 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 43 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 44 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 45 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 46 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 47 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 48 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 49 | * SUCH DAMAGE. |
| 50 | */ |
| 51 | |
| 52 | #ifndef _SPARC64_CTLREG_ |
| 53 | #define _SPARC64_CTLREG_ |
| 54 | |
| 55 | /* |
| 56 | * Sun 4u control registers. (includes address space definitions |
| 57 | * and some registers in control space). |
| 58 | */ |
| 59 | |
| 60 | /* |
| 61 | * The Alternate address spaces. |
| 62 | * |
| 63 | * 0x00-0x7f are privileged |
| 64 | * 0x80-0xff can be used by users |
| 65 | */ |
| 66 | |
| 67 | #define	ASI_LITTLE	0x08		/* This bit should make an ASI little endian */ |
| 68 | |
| 69 | #define	ASI_NUCLEUS			0x04	/* [4u] kernel address space */ |
| 70 | #define	ASI_NUCLEUS_LITTLE		0x0c	/* [4u] kernel address space, little endian */ |
| 71 | |
| 72 | #define	ASI_AS_IF_USER_PRIMARY		0x10	/* [4u] primary user address space */ |
| 73 | #define	ASI_AS_IF_USER_SECONDARY	0x11	/* [4u] secondary user address space */ |
| 74 | |
| 75 | #define	ASI_PHYS_CACHED			0x14	/* [4u] MMU bypass to main memory */ |
| 76 | #define	ASI_PHYS_NON_CACHED		0x15	/* [4u] MMU bypass to I/O location */ |
| 77 | |
| 78 | #define	ASI_AS_IF_USER_PRIMARY_LITTLE	0x18	/* [4u] primary user address space, little endian */ |
| 79 | #define	ASI_AS_IF_USER_SECONDARY_LITTIE	0x19	/* [4u] secondary user address space, little endian */ |
| 80 | |
| 81 | #define	ASI_PHYS_CACHED_LITTLE		0x1c	/* [4u] MMU bypass to main memory, little endian */ |
| 82 | #define	ASI_PHYS_NON_CACHED_LITTLE	0x1d	/* [4u] MMU bypass to I/O location, little endian */ |
| 83 | |
| 84 | #define	ASI_SCRATCHPAD			0x20	/* [4v] scratchpad registers */ |
| 85 | #define	ASI_MMU_CONTEXTID		0x21	/* [4v] MMU context */ |
| 86 | |
| 87 | #define	ASI_NUCLEUS_QUAD_LDD		0x24	/* [4u] use w/LDDA to load 128-bit item */ |
| 88 | #define	ASI_QUEUE			0x25	/* [4v] interrupt queue registers */ |
| 89 | #define	ASI_NUCLEUS_QUAD_LDD_LITTLE	0x2c	/* [4u] use w/LDDA to load 128-bit item, little endian */ |
| 90 | |
| 91 | #define	ASI_FLUSH_D_PAGE_PRIMARY	0x38	/* [4u] flush D-cache page using primary context */ |
| 92 | #define	ASI_FLUSH_D_PAGE_SECONDARY	0x39	/* [4u] flush D-cache page using secondary context */ |
| 93 | #define	ASI_FLUSH_D_CTX_PRIMARY		0x3a	/* [4u] flush D-cache context using primary context */ |
| 94 | #define	ASI_FLUSH_D_CTX_SECONDARY	0x3b	/* [4u] flush D-cache context using secondary context */ |
| 95 | |
| 96 | #define ASI_DCACHE_INVALIDATE		0x42	/* [III] invalidate D-cache */ |
| 97 | #define ASI_DCACHE_UTAG			0x43	/* [III] diagnostic access to D-cache micro tag */ |
| 98 | #define ASI_DCACHE_SNOOP_TAG		0x44	/* [III] diagnostic access to D-cache snoop tag RAM */ |
| 99 | |
| 100 | #define	ASI_LSU_CONTROL_REGISTER	0x45	/* [4u] load/store unit control register */ |
| 101 | |
| 102 | #define	ASI_DCACHE_DATA			0x46	/* [4u] diagnostic access to D-cache data RAM */ |
| 103 | #define	ASI_DCACHE_TAG			0x47	/* [4u] diagnostic access to D-cache tag RAM */ |
| 104 | |
| 105 | #define	ASI_INTR_DISPATCH_STATUS	0x48	/* [4u] interrupt dispatch status register */ |
| 106 | #define	ASI_INTR_RECEIVE		0x49	/* [4u] interrupt receive status register */ |
| 107 | #define	ASI_MID_REG			0x4a	/* [4u] hardware config and MID */ |
| 108 | #define	ASI_ERROR_EN_REG		0x4b	/* [4u] asynchronous error enables */ |
| 109 | #define	ASI_AFSR			0x4c	/* [4u] asynchronous fault status register */ |
| 110 | #define	ASI_AFAR			0x4d	/* [4u] asynchronous fault address register */ |
| 111 | |
| 112 | #define	ASI_SCRATCH			0x4f	/* [VI] scratch registers */ |
| 113 | |
| 114 | #define	ASI_ICACHE_DATA			0x66	/* [4u] diagnostic access to D-cache data RAM */ |
| 115 | #define	ASI_ICACHE_TAG			0x67	/* [4u] diagnostic access to D-cache tag RAM */ |
| 116 | #define	ASI_FLUSH_I_PAGE_PRIMARY	0x68	/* [4u] flush D-cache page using primary context */ |
| 117 | #define	ASI_FLUSH_I_PAGE_SECONDARY	0x69	/* [4u] flush D-cache page using secondary context */ |
| 118 | #define	ASI_FLUSH_I_CTX_PRIMARY		0x6a	/* [4u] flush D-cache context using primary context */ |
| 119 | #define	ASI_FLUSH_I_CTX_SECONDARY	0x6b	/* [4u] flush D-cache context using secondary context */ |
| 120 | |
| 121 | #define	ASI_BLOCK_AS_IF_USER_PRIMARY	0x70	/* [4u] primary user address space, block loads/stores */ |
| 122 | #define	ASI_BLOCK_AS_IF_USER_SECONDARY	0x71	/* [4u] secondary user address space, block loads/stores */ |
| 123 | |
| 124 | #define	ASI_ECACHE_DIAG			0x76	/* [4u] diag access to E-cache tag and data */ |
| 125 | #define	ASI_DATAPATH_ERR_REG_WRITE	0x77	/* [4u] ASI is reused */ |
| 126 | |
| 127 | #define	ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE	0x78	/* [4u] primary user address space, block loads/stores */ |
| 128 | #define	ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE	0x79	/* [4u] secondary user address space, block loads/stores */ |
| 129 | |
| 130 | #define	ASI_INTERRUPT_RECEIVE_DATA	0x7f	/* [4u] interrupt receive data registers {0,1,2} */ |
| 131 | #define	ASI_DATAPATH_ERR_REG_READ	0x7f	/* [4u] read access to datapath error registers (ASI reused) */ |
| 132 | |
| 133 | #define	ASI_PRIMARY			0x80	/* [4u] primary address space */ |
| 134 | #define	ASI_SECONDARY			0x81	/* [4u] secondary address space */ |
| 135 | #define	ASI_PRIMARY_NOFAULT		0x82	/* [4u] primary address space, no fault */ |
| 136 | #define	ASI_SECONDARY_NOFAULT		0x83	/* [4u] secondary address space, no fault */ |
| 137 | |
| 138 | #define	ASI_PRIMARY_LITTLE		0x88	/* [4u] primary address space, little endian */ |
| 139 | #define	ASI_SECONDARY_LITTLE		0x89	/* [4u] secondary address space, little endian */ |
| 140 | #define	ASI_PRIMARY_NOFAULT_LITTLE	0x8a	/* [4u] primary address space, no fault, little endian */ |
| 141 | #define	ASI_SECONDARY_NOFAULT_LITTLE	0x8b	/* [4u] secondary address space, no fault, little endian */ |
| 142 | |
| 143 | #define	ASI_PST8_PRIMARY		0xc0	/* [VIS] Eight 8-bit partial store, primary */ |
| 144 | #define	ASI_PST8_SECONDARY		0xc1	/* [VIS] Eight 8-bit partial store, secondary */ |
| 145 | #define	ASI_PST16_PRIMARY		0xc2	/* [VIS] Four 16-bit partial store, primary */ |
| 146 | #define	ASI_PST16_SECONDARY		0xc3	/* [VIS] Fout 16-bit partial store, secondary */ |
| 147 | #define	ASI_PST32_PRIMARY		0xc4	/* [VIS] Two 32-bit partial store, primary */ |
| 148 | #define	ASI_PST32_SECONDARY		0xc5	/* [VIS] Two 32-bit partial store, secondary */ |
| 149 | |
| 150 | #define	ASI_PST8_PRIMARY_LITTLE		0xc8	/* [VIS] Eight 8-bit partial store, primary, little endian */ |
| 151 | #define	ASI_PST8_SECONDARY_LITTLE	0xc9	/* [VIS] Eight 8-bit partial store, secondary, little endian */ |
| 152 | #define	ASI_PST16_PRIMARY_LITTLE	0xca	/* [VIS] Four 16-bit partial store, primary, little endian */ |
| 153 | #define	ASI_PST16_SECONDARY_LITTLE	0xcb	/* [VIS] Fout 16-bit partial store, secondary, little endian */ |
| 154 | #define	ASI_PST32_PRIMARY_LITTLE	0xcc	/* [VIS] Two 32-bit partial store, primary, little endian */ |
| 155 | #define	ASI_PST32_SECONDARY_LITTLE	0xcd	/* [VIS] Two 32-bit partial store, secondary, little endian */ |
| 156 | |
| 157 | #define	ASI_FL8_PRIMARY			0xd0	/* [VIS] One 8-bit load/store floating, primary */ |
| 158 | #define	ASI_FL8_SECONDARY		0xd1	/* [VIS] One 8-bit load/store floating, secondary */ |
| 159 | #define	ASI_FL16_PRIMARY		0xd2	/* [VIS] One 16-bit load/store floating, primary */ |
| 160 | #define	ASI_FL16_SECONDARY		0xd3	/* [VIS] One 16-bit load/store floating, secondary */ |
| 161 | |
| 162 | #define	ASI_FL8_PRIMARY_LITTLE		0xd8	/* [VIS] One 8-bit load/store floating, primary, little endian */ |
| 163 | #define	ASI_FL8_SECONDARY_LITTLE	0xd9	/* [VIS] One 8-bit load/store floating, secondary, little endian */ |
| 164 | #define	ASI_FL16_PRIMARY_LITTLE		0xda	/* [VIS] One 16-bit load/store floating, primary, little endian */ |
| 165 | #define	ASI_FL16_SECONDARY_LITTLE	0xdb	/* [VIS] One 16-bit load/store floating, secondary, little endian */ |
| 166 | |
| 167 | #define	ASI_BLOCK_COMMIT_PRIMARY	0xe0	/* [4u] block store with commit, primary */ |
| 168 | #define	ASI_BLOCK_COMMIT_SECONDARY	0xe1	/* [4u] block store with commit, secondary */ |
| 169 | #define	ASI_BLOCK_PRIMARY		0xf0	/* [4u] block load/store, primary */ |
| 170 | #define	ASI_BLOCK_SECONDARY		0xf1	/* [4u] block load/store, secondary */ |
| 171 | #define	ASI_BLOCK_PRIMARY_LITTLE	0xf8	/* [4u] block load/store, primary, little endian */ |
| 172 | #define	ASI_BLOCK_SECONDARY_LITTLE	0xf9	/* [4u] block load/store, secondary, little endian */ |
| 173 | |
| 174 | |
| 175 | /* |
| 176 | * These are the shorter names used by Solaris |
| 177 | */ |
| 178 | |
| 179 | #define	ASI_N		ASI_NUCLEUS |
| 180 | #define	ASI_NL		ASI_NUCLEUS_LITTLE |
| 181 | #define	ASI_AIUP	ASI_AS_IF_USER_PRIMARY |
| 182 | #define	ASI_AIUS	ASI_AS_IF_USER_SECONDARY |
| 183 | #define	ASI_AIUPL	ASI_AS_IF_USER_PRIMARY_LITTLE |
| 184 | #define	ASI_AIUSL	ASI_AS_IF_USER_SECONDARY_LITTLE |
| 185 | #define	ASI_P		ASI_PRIMARY |
| 186 | #define	ASI_S		ASI_SECONDARY |
| 187 | #define	ASI_PNF		ASI_PRIMARY_NOFAULT |
| 188 | #define	ASI_SNF		ASI_SECONDARY_NOFAULT |
| 189 | #define	ASI_PL		ASI_PRIMARY_LITTLE |
| 190 | #define	ASI_SL		ASI_SECONDARY_LITTLE |
| 191 | #define	ASI_PNFL	ASI_PRIMARY_NOFAULT_LITTLE |
| 192 | #define	ASI_SNFL	ASI_SECONDARY_NOFAULT_LITTLE |
| 193 | #define	ASI_FL8_P	ASI_FL8_PRIMARY |
| 194 | #define	ASI_FL8_S	ASI_FL8_SECONDARY |
| 195 | #define	ASI_FL16_P	ASI_FL16_PRIMARY |
| 196 | #define	ASI_FL16_S	ASI_FL16_SECONDARY |
| 197 | #define	ASI_FL8_PL	ASI_FL8_PRIMARY_LITTLE |
| 198 | #define	ASI_FL8_SL	ASI_FL8_SECONDARY_LITTLE |
| 199 | #define	ASI_FL16_PL	ASI_FL16_PRIMARY_LITTLE |
| 200 | #define	ASI_FL16_SL	ASI_FL16_SECONDARY_LITTLE |
| 201 | #define	ASI_BLK_AIUP	ASI_BLOCK_AS_IF_USER_PRIMARY |
| 202 | #define	ASI_BLK_AIUPL	ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE |
| 203 | #define	ASI_BLK_AIUS	ASI_BLOCK_AS_IF_USER_SECONDARY |
| 204 | #define	ASI_BLK_AIUSL	ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE |
| 205 | #define	ASI_BLK_COMMIT_P		ASI_BLOCK_COMMIT_PRIMARY |
| 206 | #define	ASI_BLK_COMMIT_PRIMARY		ASI_BLOCK_COMMIT_PRIMARY |
| 207 | #define	ASI_BLK_COMMIT_S		ASI_BLOCK_COMMIT_SECONDARY |
| 208 | #define	ASI_BLK_COMMIT_SECONDARY	ASI_BLOCK_COMMIT_SECONDARY |
| 209 | #define	ASI_BLK_P			ASI_BLOCK_PRIMARY |
| 210 | #define	ASI_BLK_PL			ASI_BLOCK_PRIMARY_LITTLE |
| 211 | #define	ASI_BLK_S			ASI_BLOCK_SECONDARY |
| 212 | #define	ASI_BLK_SL			ASI_BLOCK_SECONDARY_LITTLE |
| 213 | |
| 214 | /* Alternative spellings */ |
| 215 | #define ASI_PRIMARY_NO_FAULT		ASI_PRIMARY_NOFAULT |
| 216 | #define ASI_PRIMARY_NO_FAULT_LITTLE	ASI_PRIMARY_NOFAULT_LITTLE |
| 217 | #define ASI_SECONDARY_NO_FAULT		ASI_SECONDARY_NOFAULT |
| 218 | #define ASI_SECONDARY_NO_FAULT_LITTLE	ASI_SECONDARY_NOFAULT_LITTLE |
| 219 | |
| 220 | #define	PHYS_ASI(x)	(((x) | 0x09) == 0x1d) |
| 221 | #define	LITTLE_ASI(x)	((x) & ASI_LITTLE) |
| 222 | |
| 223 | /* |
| 224 | * %tick: cpu cycle counter |
| 225 | */ |
| 226 | #define	TICK_NPT	0x8000000000000000	/* trap on non priv access */ |
| 227 | #define	TICK_TICKS	0x7fffffffffffffff	/* counter bits */ |
| 228 | |
| 229 | /* |
| 230 | * The following are 4u control registers |
| 231 | */ |
| 232 | |
| 233 | /* Get the CPU's UPA port ID */ |
| 234 | #define	UPA_CR_MID(x)		(((x) >> 17) & 0x1f) |
| 235 | #define	CPU_UPAID		UPA_CR_MID(ldxa(0, ASI_MID_REG)) |
| 236 | |
| 237 | /* Get the CPU's Fireplane agent ID */ |
| 238 | #define FIREPLANE_CR_AID(x)	(((x) >> 17) & 0x3ff) |
| 239 | #define CPU_FIREPLANEID		FIREPLANE_CR_AID(ldxa(0, ASI_MID_REG)) |
| 240 | |
| 241 | /* Get the CPU's Jupiter Bus interrupt target ID */ |
| 242 | #define JUPITER_CR_ITID(x)	((x) & 0x3ff) |
| 243 | #define CPU_JUPITERID		JUPITER_CR_ITID(ldxa(0, ASI_MID_REG)) |
| 244 | |
| 245 | /* |
| 246 | * [4u] MMU and Cache Control Register (MCCR) |
| 247 | * use ASI = 0x45 |
| 248 | */ |
| 249 | #define	ASI_MCCR	ASI_LSU_CONTROL_REGISTER |
| 250 | #define	MCCR		0x00 |
| 251 | |
| 252 | /* MCCR Bits and their meanings */ |
| 253 | #define	MCCR_DMMU_EN	0x08 |
| 254 | #define	MCCR_IMMU_EN	0x04 |
| 255 | #define	MCCR_DCACHE_EN	0x02 |
| 256 | #define	MCCR_ICACHE_EN	0x01 |
| 257 | |
| 258 | |
| 259 | /* |
| 260 | * MMU control registers |
| 261 | */ |
| 262 | |
| 263 | /* Choose an MMU */ |
| 264 | #define	ASI_DMMU		0x58 |
| 265 | #define	ASI_IMMU		0x50 |
| 266 | |
| 267 | /* Other assorted MMU ASIs */ |
| 268 | #define	ASI_IMMU_8KPTR		0x51 |
| 269 | #define	ASI_IMMU_64KPTR		0x52 |
| 270 | #define	ASI_IMMU_DATA_IN	0x54 |
| 271 | #define	ASI_IMMU_TLB_DATA	0x55 |
| 272 | #define	ASI_IMMU_TLB_TAG	0x56 |
| 273 | #define	ASI_DMMU_8KPTR		0x59 |
| 274 | #define	ASI_DMMU_64KPTR		0x5a |
| 275 | #define	ASI_DMMU_DATA_IN	0x5c |
| 276 | #define	ASI_DMMU_TLB_DATA	0x5d |
| 277 | #define	ASI_DMMU_TLB_TAG	0x5e |
| 278 | |
| 279 | /* |
| 280 | * The following are the control registers |
| 281 | * They work on both MMUs unless noted. |
| 282 | * III = cheetah only |
| 283 | * |
| 284 | * Register contents are defined later on individual registers. |
| 285 | */ |
| 286 | #define	TSB_TAG_TARGET		0x0 |
| 287 | #define	TLB_DATA_IN		0x0 |
| 288 | #define	CTX_PRIMARY		0x08	/* primary context -- DMMU only */ |
| 289 | #define	CTX_SECONDARY		0x10	/* secondary context -- DMMU only */ |
| 290 | #define	SFSR			0x18 |
| 291 | #define	SFAR			0x20	/* fault address -- DMMU only */ |
| 292 | #define	TSB			0x28 |
| 293 | #define	TLB_TAG_ACCESS		0x30 |
| 294 | #define	VIRTUAL_WATCHPOINT	0x38 |
| 295 | #define	PHYSICAL_WATCHPOINT	0x40 |
| 296 | #define TSB_PEXT		0x48	/* III primary ext */ |
| 297 | #define TSB_SEXT		0x50	/* III 2ndary ext -- DMMU only */ |
| 298 | #define TSB_NEXT		0x58	/* III nucleus ext */ |
| 299 | |
| 300 | /* Tag Target bits */ |
| 301 | #define	TAG_TARGET_VA_MASK	0x03ffffffffffffffffLL |
| 302 | #define	TAG_TARGET_VA(x)	(((x)<<22)&TAG_TARGET_VA_MASK) |
| 303 | #define	TAG_TARGET_CONTEXT(x)	((x)>>48) |
| 304 | #define	TAG_TARGET(c,v)		((((uint64_t)c)<<48)|(((uint64_t)v)&TAG_TARGET_VA_MASK)) |
| 305 | |
| 306 | /* SFSR bits for both D_SFSR and I_SFSR */ |
| 307 | #define	SFSR_NF			0x1000000	/* Non-faulting load */ |
| 308 | #define	SFSR_ASI(x)		((x)>>16) |
| 309 | #define	SFSR_TM			0x0008000	/* TLB miss */ |
| 310 | #define	SFSR_FT_VA_OOR_2	0x0002000	/* IMMU: jumpl or return to unsupported VA */ |
| 311 | #define	SFSR_FT_VA_OOR_1	0x0001000	/* fault at unsupported VA */ |
| 312 | #define	SFSR_FT_NFO		0x0000800	/* DMMU: Access to page marked NFO */ |
| 313 | #define	SFSR_ILL_ASI		0x0000400	/* DMMU: Illegal (unsupported) ASI */ |
| 314 | #define	SFSR_FT_IO_ATOMIC	0x0000200	/* DMMU: Atomic access to noncacheable page */ |
| 315 | #define	SFSR_FT_ILL_NF		0x0000100	/* DMMU: NF load or flush to page marked E (has side effects) */ |
| 316 | #define	SFSR_FT_PRIV		0x0000080	/* Privilege violation */ |
| 317 | #define	SFSR_FT_E		0x0000040	/* DMUU: value of E bit associated address */ |
| 318 | #define	SFSR_CTXT(x)		(((x)>>4)&0x3) |
| 319 | #define	SFSR_CTXT_IS_PRIM(x)	(SFSR_CTXT(x)==0x00) |
| 320 | #define	SFSR_CTXT_IS_SECOND(x)	(SFSR_CTXT(x)==0x01) |
| 321 | #define	SFSR_CTXT_IS_NUCLEUS(x)	(SFSR_CTXT(x)==0x02) |
| 322 | #define	SFSR_PRIV		0x0000008	/* value of PSTATE.PRIV for faulting access */ |
| 323 | #define	SFSR_W			0x0000004 	/* DMMU: attempted write */ |
| 324 | #define	SFSR_OW			0x0000002 	/* Overwrite; prev fault was still valid */ |
| 325 | #define	SFSR_FV			0x0000001	/* Fault is valid */ |
| 326 | #define	SFSR_FT	(SFSR_FT_VA_OOR_2|SFSR_FT_VA_OOR_1|SFSR_FT_NFO|SFSR_ILL_ASI|SFSR_FT_IO_ATOMIC|SFSR_FT_ILL_NF|SFSR_FT_PRIV) |
| 327 | |
| 328 | #define	SFSR_BITS "\20\31NF\20TM\16VAT\15VAD\14NFO\13ASI\12A\11NF\10PRIV\7E\6NUCLEUS\5SECONDCTX\4PRIV\3W\2OW\1FV" |
| 329 | |
| 330 | /* ASFR bits */ |
| 331 | #define	ASFR_ME			0x100000000LL |
| 332 | #define	ASFR_PRIV		0x080000000LL |
| 333 | #define	ASFR_ISAP		0x040000000LL |
| 334 | #define	ASFR_ETP		0x020000000LL |
| 335 | #define	ASFR_IVUE		0x010000000LL |
| 336 | #define	ASFR_TO			0x008000000LL |
| 337 | #define	ASFR_BERR		0x004000000LL |
| 338 | #define	ASFR_LDP		0x002000000LL |
| 339 | #define	ASFR_CP			0x001000000LL |
| 340 | #define	ASFR_WP			0x000800000LL |
| 341 | #define	ASFR_EDP		0x000400000LL |
| 342 | #define	ASFR_UE			0x000200000LL |
| 343 | #define	ASFR_CE			0x000100000LL |
| 344 | #define	ASFR_ETS		0x0000f0000LL |
| 345 | #define	ASFT_P_SYND		0x00000ffffLL |
| 346 | |
| 347 | #define	AFSR_BITS "\20" \ |
| 348 | "\20ME\37PRIV\36ISAP\35ETP\34IVUE\33TO\32BERR\31LDP\30CP\27WP\26EDP" \ |
| 349 | "\25UE\24CE" |
| 350 | |
| 351 | /* |
| 352 | * Here's the spitfire TSB control register bits. |
| 353 | * |
| 354 | * Each TSB entry is 16-bytes wide. The TSB must be size aligned |
| 355 | */ |
| 356 | #define	TSB_SIZE_512		0x0	/* 8kB, etc. */	 |
| 357 | #define	TSB_SIZE_1K		0x01 |
| 358 | #define	TSB_SIZE_2K		0x02	 |
| 359 | #define	TSB_SIZE_4K		0x03	 |
| 360 | #define	TSB_SIZE_8K		0x04 |
| 361 | #define	TSB_SIZE_16K		0x05 |
| 362 | #define	TSB_SIZE_32K		0x06 |
| 363 | #define	TSB_SIZE_64K		0x07 |
| 364 | #define	TSB_SPLIT		0x1000 |
| 365 | #define	TSB_BASE		0xffffffffffffe000 |
| 366 | |
| 367 | /* TLB Tag Access bits */ |
| 368 | #define	TLB_TAG_ACCESS_VA	0xffffffffffffe000 |
| 369 | #define	TLB_TAG_ACCESS_CTX	0x0000000000001fff |
| 370 | |
| 371 | /* |
| 372 | * TLB demap registers. TTEs are defined in v9pte.h |
| 373 | * |
| 374 | * Use the address space to select between IMMU and DMMU. |
| 375 | * The address of the register selects which context register |
| 376 | * to read the ASI from. |
| 377 | * |
| 378 | * The data stored in the register is interpreted as the VA to |
| 379 | * use. The DEMAP_CTX_<> registers ignore the address and demap the |
| 380 | * entire ASI. |
| 381 | * |
| 382 | */ |
| 383 | #define	ASI_IMMU_DEMAP			0x57	/* [4u] IMMU TLB demap */ |
| 384 | #define	ASI_DMMU_DEMAP			0x5f	/* [4u] IMMU TLB demap */ |
| 385 | |
| 386 | #define	DEMAP_PAGE_NUCLEUS		((0x02)<<4)	/* Demap page from kernel AS */ |
| 387 | #define	DEMAP_PAGE_PRIMARY		((0x00)<<4)	/* Demap a page from primary CTXT */ |
| 388 | #define	DEMAP_PAGE_SECONDARY		((0x01)<<4)	/* Demap page from secondary CTXT (DMMU only) */ |
| 389 | #define	DEMAP_CTX_NUCLEUS		((0x06)<<4)	/* Demap all of kernel CTXT */ |
| 390 | #define	DEMAP_CTX_PRIMARY		((0x04)<<4)	/* Demap all of primary CTXT */ |
| 391 | #define	DEMAP_CTX_SECONDARY		((0x05)<<4)	/* Demap all of secondary CTXT */ |
| 392 | |
| 393 | /* |
| 394 | * Interrupt registers. This really gets hairy. |
| 395 | */ |
| 396 | |
| 397 | /* IRSR -- Interrupt Receive Status Register */ |
| 398 | #define	ASI_IRSR	0x49 |
| 399 | #define	IRSR		0x00 |
| 400 | #define	IRSR_BUSY	0x020 |
| 401 | #define	IRSR_MID(x)	(x&0x1f) |
| 402 | |
| 403 | /* IRDR -- Interrupt Receive Data Registers */ |
| 404 | #define	ASI_IRDR	0x7f |
| 405 | #define	IRDR_0H		0x40 |
| 406 | #define	IRDR_0L		0x48	/* unimplemented */ |
| 407 | #define	IRDR_1H		0x50 |
| 408 | #define	IRDR_1L		0x58	/* unimplemented */ |
| 409 | #define	IRDR_2H		0x60 |
| 410 | #define	IRDR_2L		0x68	/* unimplemented */ |
| 411 | #define	IRDR_3H		0x70	/* unimplemented */ |
| 412 | #define	IRDR_3L		0x78	/* unimplemented */ |
| 413 | |
| 414 | /* SOFTINT ASRs */ |
| 415 | #define	SET_SOFTINT	%asr20	/* Sets these bits */ |
| 416 | #define	CLEAR_SOFTINT	%asr21	/* Clears these bits */ |
| 417 | #define	SOFTINT		%asr22	/* Reads the register */ |
| 418 | #define	TICK_CMPR	%asr23 |
| 419 | |
| 420 | #define	TICK_INT	0x01	/* level-14 clock tick */ |
| 421 | #define	SOFTINT1	(0x1<<1) |
| 422 | #define	SOFTINT2	(0x1<<2) |
| 423 | #define	SOFTINT3	(0x1<<3) |
| 424 | #define	SOFTINT4	(0x1<<4) |
| 425 | #define	SOFTINT5	(0x1<<5) |
| 426 | #define	SOFTINT6	(0x1<<6) |
| 427 | #define	SOFTINT7	(0x1<<7) |
| 428 | #define	SOFTINT8	(0x1<<8) |
| 429 | #define	SOFTINT9	(0x1<<9) |
| 430 | #define	SOFTINT10	(0x1<<10) |
| 431 | #define	SOFTINT11	(0x1<<11) |
| 432 | #define	SOFTINT12	(0x1<<12) |
| 433 | #define	SOFTINT13	(0x1<<13) |
| 434 | #define	SOFTINT14	(0x1<<14) |
| 435 | #define	SOFTINT15	(0x1<<15) |
| 436 | #define	STICK_INT	(0x1<<16) |
| 437 | |
| 438 | /* Interrupt Dispatch -- usually reserved for cross-calls */ |
| 439 | #define	ASR_IDSR	0x48 /* Interrupt dispatch status reg */ |
| 440 | #define	IDSR		0x00 |
| 441 | #define	IDSR_NACK	0x02 |
| 442 | #define	IDSR_BUSY	0x01 |
| 443 | |
| 444 | #define	ASI_INTERRUPT_DISPATCH		0x77	/* [4u] spitfire interrupt dispatch regs */ |
| 445 | |
| 446 | /* Interrupt delivery initiation */ |
| 447 | #define	IDCR(x)		((((u_int64_t)(x)) << 14) | 0x70) |
| 448 | |
| 449 | #define	IDDR_0H		0x40	/* Store data to send in these regs */ |
| 450 | #define	IDDR_0L		0x48	/* unimplemented */ |
| 451 | #define	IDDR_1H		0x50 |
| 452 | #define	IDDR_1L		0x58	/* unimplemented */ |
| 453 | #define	IDDR_2H		0x60 |
| 454 | #define	IDDR_2L		0x68	/* unimplemented */ |
| 455 | #define	IDDR_3H		0x80	/* unimplemented */ |
| 456 | #define	IDDR_3L		0x88	/* unimplemented */ |
| 457 | |
| 458 | /* |
| 459 | * Error registers |
| 460 | */ |
| 461 | |
| 462 | /* Since we won't try to fix async errs, we don't care about the bits in the regs */ |
| 463 | #define	ASI_AFAR	0x4d	/* Asynchronous fault address register */ |
| 464 | #define	AFAR		0x00 |
| 465 | #define	ASI_AFSR	0x4c	/* Asynchronous fault status register */ |
| 466 | #define	AFSR		0x00 |
| 467 | |
| 468 | #define	ASI_P_EER	0x4b	/* Error enable register */ |
| 469 | #define	P_EER		0x00 |
| 470 | #define	P_EER_ISAPEN	0x04	/* Enable fatal on ISAP */ |
| 471 | #define	P_EER_NCEEN	0x02	/* Enable trap on uncorrectable errs */ |
| 472 | #define	P_EER_CEEN	0x01	/* Enable trap on correctable errs */ |
| 473 | |
| 474 | #define	ASI_DATAPATH_READ	0x7f /* Read the regs */ |
| 475 | #define	ASI_DATAPATH_WRITE	0x77 /* Write to the regs */ |
| 476 | #define	P_DPER_0	0x00	/* Datapath err reg 0 */ |
| 477 | #define	P_DPER_1	0x18	/* Datapath err reg 1 */ |
| 478 | #define	P_DCR_0		0x20	/* Datapath control reg 0 */ |
| 479 | #define	P_DCR_1		0x38	/* Datapath control reg 0 */ |
| 480 | |
| 481 | |
| 482 | /* From sparc64/asm.h which I think I'll deprecate since it makes bus.h a pain. */ |
| 483 | |
| 484 | #ifndef _LOCORE |
| 485 | /* |
| 486 | * GCC __asm constructs for doing assembly stuff. |
| 487 | */ |
| 488 | |
| 489 | /* |
| 490 | * ``Routines'' to load and store from/to alternate address space. |
| 491 | * The location can be a variable, the asi value (address space indicator) |
| 492 | * must be a constant. |
| 493 | * |
| 494 | * N.B.: You can put as many special functions here as you like, since |
| 495 | * they cost no kernel space or time if they are not used. |
| 496 | * |
| 497 | * These were static inline functions, but gcc screws up the constraints |
| 498 | * on the address space identifiers (the "n"umeric value part) because |
| 499 | * it inlines too late, so we have to use the funny valued-macro syntax. |
| 500 | */ |
| 501 | |
| 502 | /* |
| 503 | * Apparently the definition of bypass ASIs is that they all use the |
| 504 | * D$ so we need to flush the D$ to make sure we don't get data pollution. |
| 505 | */ |
| 506 | |
| 507 | #define sparc_wr(name, val, xor)					\ |
| 508 | do {									\ |
| 509 | 	if (__builtin_constant_p(xor))					\ |
| 510 | 		__asm volatile("wr %%g0, %0, %%" #name			\ |
| 511 | 		 : : "rI" ((val) ^ (xor)) : "%g0");			\ |
| 512 | 	else								\ |
| 513 | 		__asm volatile("wr %0, %1, %%" #name			\ |
| 514 | 		 : : "r" (val), "rI" (xor) : "%g0");			\ |
| 515 | } while(0) |
| 516 | |
| 517 | #define sparc_wrpr(name, val, xor)					\ |
| 518 | do {									\ |
| 519 | 	if (__builtin_constant_p(xor))					\ |
| 520 | 		__asm volatile("wrpr %%g0, %0, %%" #name		\ |
| 521 | 		 : : "rI" ((val) ^ (xor)) : "%g0");			\ |
| 522 | 	else								\ |
| 523 | 		__asm volatile("wrpr %0, %1, %%" #name			\ |
| 524 | 		 : : "r" (val), "rI" (xor) : "%g0");			\ |
| 525 | 	__asm volatile("" : : : "memory");				\ |
| 526 | } while(0) |
| 527 | |
| 528 | |
| 529 | #define sparc_rd(name) sparc_rd_ ## name() |
| 530 | #define GEN_RD(name)							\ |
| 531 | static inline u_int64_t sparc_rd_ ## name(void);			\ |
| 532 | static inline u_int64_t						\ |
| 533 | sparc_rd_ ## name(void)							\ |
| 534 | {									\ |
| 535 | 	u_int64_t r;							\ |
| 536 | 	__asm volatile("rd %%" #name ", %0" :				\ |
| 537 | 	 "=r" (r) : : "%g0");					\ |
| 538 | 	return (r);							\ |
| 539 | } |
| 540 | |
| 541 | #define sparc_rdpr(name) sparc_rdpr_ ## name() |
| 542 | #define GEN_RDPR(name)							\ |
| 543 | static inline u_int64_t sparc_rdpr_ ## name(void);			\ |
| 544 | static inline u_int64_t						\ |
| 545 | sparc_rdpr_ ## name(void)						\ |
| 546 | {									\ |
| 547 | 	u_int64_t r;							\ |
| 548 | 	__asm volatile("rdpr %%" #name ", %0" :				\ |
| 549 | 	 "=r" (r) : : "%g0");					\ |
| 550 | 	return (r);							\ |
| 551 | } |
| 552 | |
| 553 | GEN_RD(asi); |
| 554 | GEN_RD(fprs); |
| 555 | GEN_RD(asr22); |
| 556 | GEN_RD(sys_tick); |
| 557 | GEN_RD(sys_tick_cmpr); |
| 558 | GEN_RDPR(tick); |
| 559 | GEN_RDPR(tba); |
| 560 | GEN_RDPR(pstate); |
| 561 | GEN_RDPR(pil); |
| 562 | GEN_RDPR(cwp); |
| 563 | GEN_RDPR(cansave); |
| 564 | GEN_RDPR(canrestore); |
| 565 | GEN_RDPR(cleanwin); |
| 566 | GEN_RDPR(otherwin); |
| 567 | GEN_RDPR(wstate); |
| 568 | GEN_RDPR(ver); |
| 569 | /* |
| 570 | * Before adding GEN_RDPRs for other registers, see Errata 50 (E.g,. in |
| 571 | * the US-IIi manual) regarding tstate, pc and npc reads. |
| 572 | */ |
| 573 | |
| 574 | /* Generate ld*a/st*a functions for non-constant ASI's. */ |
| 575 | #define LDNC_GEN(tp, o)							\ |
| 576 | 	static inline tp o ## _asi(paddr_t);				\ |
| 577 | 	static inline tp						\ |
| 578 | 	o ## _asi(paddr_t va)						\ |
| 579 | 	{								\ |
| 580 | 		tp r;							\ |
| 581 | 		__asm volatile(						\ |
| 582 | 		 #o " [%1] %%asi, %0"				\ |
| 583 | 		 : "=r" (r)						\ |
| 584 | 		 : "r" ((volatile tp *)va)				\ |
| 585 | 		 : "%g0");						\ |
| 586 | 		return (r);						\ |
| 587 | 	}								\ |
| 588 | 	static inline tp o ## _nc(paddr_t, int);			\ |
| 589 | 	static inline tp						\ |
| 590 | 	o ## _nc(paddr_t va, int asi)					\ |
| 591 | 	{								\ |
| 592 | 		sparc_wr(asi, asi, 0);					\ |
| 593 | 		return (o ## _asi(va));					\ |
| 594 | 	} |
| 595 | |
| 596 | LDNC_GEN(u_char, lduba); |
| 597 | LDNC_GEN(u_short, lduha); |
| 598 | LDNC_GEN(u_int, lduwa); |
| 599 | LDNC_GEN(u_int64_t, ldxa); |
| 600 | |
| 601 | LDNC_GEN(int, lda); |
| 602 | |
| 603 | #define LDC_GEN(va, asi, op, opa, type) ({				\ |
| 604 | 	type __r ## op ## type;						\ |
| 605 | 	if(asi == ASI_PRIMARY || 					\ |
| 606 | 	 (sizeof(type) == 1 && asi == ASI_PRIMARY_LITTLE))		\ |
| 607 | 		__r ## op ## type = *((volatile type *)va);		\ |
| 608 | 	else								\ |
| 609 | 		__asm volatile(#opa " [%1] " #asi ", %0"		\ |
| 610 | 		 : "=r" (__r ## op ## type)				\ |
| 611 | 		 : "r" ((volatile type *)va)				\ |
| 612 | 		 : "%g0");						\ |
| 613 | 	__r ## op ## type;						\ |
| 614 | }) |
| 615 | |
| 616 | #ifdef __OPTIMIZE__ |
| 617 | #define LD_GENERIC(va, asi, op, type) (__builtin_constant_p(asi) ?	\ |
| 618 | 	LDC_GEN((va), asi, op, op ## a, type) : op ## a_nc((va), asi)) |
| 619 | #else /* __OPTIMIZE */ |
| 620 | #define LD_GENERIC(va, asi, op, type) (op ## a_nc((va), asi)) |
| 621 | #endif /* __OPTIMIZE__ */ |
| 622 | |
| 623 | #define lduba(va, asi)	LD_GENERIC(va, asi, ldub, u_int8_t) |
| 624 | #define lduha(va, asi)	LD_GENERIC(va, asi, lduh, u_int16_t) |
| 625 | #define lduwa(va, asi)	LD_GENERIC(va, asi, lduw, u_int32_t) |
| 626 | #define ldxa(va, asi)	LD_GENERIC(va, asi, ldx, u_int64_t) |
| 627 | |
| 628 | #define STNC_GEN(tp, o)							\ |
| 629 | 	static inline void o ## _asi(paddr_t, tp);			\ |
| 630 | 	static inline void						\ |
| 631 | 	o ## _asi(paddr_t va, tp val)					\ |
| 632 | 	{								\ |
| 633 | 		__asm volatile(						\ |
| 634 | 		 #o " %0, [%1] %%asi"				\ |
| 635 | 		 :							\ |
| 636 | 		 : "r" (val), "r" ((volatile tp *)va)		\ |
| 637 | 		 : "memory");					\ |
| 638 | 	}								\ |
| 639 | 	static inline void o ## _nc(paddr_t, int, tp);		\ |
| 640 | 	static inline void						\ |
| 641 | 	o ## _nc(paddr_t va, int asi, tp val)				\ |
| 642 | 	{								\ |
| 643 | 		sparc_wr(asi, asi, 0);					\ |
| 644 | 		o ## _asi(va, val);					\ |
| 645 | 	} |
| 646 | |
| 647 | STNC_GEN(u_int8_t, stba); |
| 648 | STNC_GEN(u_int16_t, stha); |
| 649 | STNC_GEN(u_int32_t, stwa); |
| 650 | STNC_GEN(u_int64_t, stxa); |
| 651 | |
| 652 | STNC_GEN(u_int, sta); |
| 653 | |
| 654 | #define STC_GEN(va, asi, val, op, opa, type) ({				\ |
| 655 | 	if(asi == ASI_PRIMARY ||					\ |
| 656 | 	 (sizeof(type) == 1 && asi == ASI_PRIMARY_LITTLE))		\ |
| 657 | 		*((volatile type *)va) = val;				\ |
| 658 | 	else								\ |
| 659 | 		__asm volatile(#opa " %0, [%1] " #asi			\ |
| 660 | 		 : : "r" (val), "r" ((volatile type *)va)		\ |
| 661 | 		 : "memory");					\ |
| 662 | 	}) |
| 663 | |
| 664 | #ifdef __OPTIMIZE__ |
| 665 | #define ST_GENERIC(va, asi, val, op, type) (__builtin_constant_p(asi) ?	\ |
| 666 | 	STC_GEN((va), (asi), (val), op, op ## a, type) :		\ |
| 667 | 	op ## a_nc((va), asi, (val))) |
| 668 | #else /* __OPTIMIZE__ */ |
| 669 | #define ST_GENERIC(va, asi, val, op, type) (op ## a_nc((va), asi, (val))) |
| 670 | #endif /* __OPTIMIZE__ */ |
| 671 | |
| 672 | #define stba(va, asi, val)	ST_GENERIC(va, asi, val, stb, u_int8_t) |
| 673 | #define stha(va, asi, val)	ST_GENERIC(va, asi, val, sth, u_int16_t) |
| 674 | #define stwa(va, asi, val)	ST_GENERIC(va, asi, val, stw, u_int32_t) |
| 675 | #define stxa(va, asi, val)	ST_GENERIC(va, asi, val, stx, u_int64_t) |
| 676 | |
| 677 | |
| 678 | static inline void asi_set(int); |
| 679 | static inline void |
| 680 | asi_set(int asi) |
| 681 | { |
| 682 | 	sparc_wr(asi, asi, 0); |
| 683 | } |
| 684 | |
| 685 | static inline u_int8_t asi_get(void); |
| 686 | static inline u_int8_t |
| 687 | asi_get(void) |
| 688 | { |
| 689 | 	return sparc_rd(asi); |
| 690 | } |
| 691 | |
| 692 | /* flush address from instruction cache */ |
| 693 | static inline void flush(void *); |
| 694 | static inline void |
| 695 | flush(void *p) |
| 696 | { |
| 697 | 	__asm volatile("flush %0" |
| 698 | 	 : : "r" (p) |
| 699 | 	 : "memory"); |
| 700 | } |
| 701 | |
| 702 | /* Read 64-bit %tick and %sys_tick registers. */ |
| 703 | #define tick() (sparc_rdpr(tick) & TICK_TICKS) |
| 704 | #define sys_tick() (sparc_rd(sys_tick) & TICK_TICKS) |
| 705 | extern u_int64_t stick(void); |
| 706 | |
| 707 | extern void tick_enable(void); |
| 708 | extern void sys_tick_enable(void); |
| 709 | |
| 710 | extern void tickcmpr_set(u_int64_t); |
| 711 | extern void sys_tickcmpr_set(u_int64_t); |
| 712 | extern void stickcmpr_set(u_int64_t); |
| 713 | |
| 714 | #endif /* _LOCORE */ |
| 715 | #endif /* _SPARC64_CTLREG_ */ |