1/* $NetBSD: ctlreg.h,v 1.71 2024/03/10 17:34:47 rillig Exp $ */ 2 3/* 4 * Copyright (c) 1996-2002 Eduardo Horvath 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 13 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 14 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 15 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE 16 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 18 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 19 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 20 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 22 * SUCH DAMAGE. 23 * 24 */ 25 26#ifndef _SPARC_CTLREG_H_ 27#define _SPARC_CTLREG_H_ 28 29/* 30 * Sun 4u control registers. (includes address space definitions 31 * and some registers in control space). 32 */ 33 34/* 35 * The Alternate address spaces. 36 * 37 * 0x00-0x7f are privileged 38 * 0x80-0xff can be used by users 39 */ 40 41#define ASI_LITTLE 0x08 /* This bit should make an ASI little endian */ 42 43#define ASI_NUCLEUS 0x04 /* [4u] kernel address space */ 44#define ASI_NUCLEUS_LITTLE 0x0c /* [4u] kernel address space, little endian */ 45 46#define ASI_AS_IF_USER_PRIMARY 0x10 /* [4u] primary user address space */ 47#define ASI_AS_IF_USER_SECONDARY 0x11 /* [4u] secondary user address space */ 48 49#define ASI_PHYS_CACHED 0x14 /* [4u] MMU bypass to main memory */ 50#define ASI_PHYS_NON_CACHED 0x15 /* [4u] MMU bypass to I/O location */ 51 52#define ASI_AS_IF_USER_PRIMARY_LITTLE 0x18 /* [4u] primary user address space, little endian */ 53#define ASI_AS_IF_USER_SECONDARY_LITTLE 0x19 /* [4u] secondary user address space, little endian */ 54 55#define ASI_PHYS_CACHED_LITTLE 0x1c /* [4u] MMU bypass to main memory, little endian */ 56#define ASI_PHYS_NON_CACHED_LITTLE 0x1d /* [4u] MMU bypass to I/O location, little endian */ 57 58#define ASI_MMU_CONTEXTID 0x21 /* [4v] MMU context control - both IMMU and DMMU */ 59 60#define ASI_NUCLEUS_QUAD_LDD 0x24 /* [4u] use w/LDDA to load 128-bit item */ 61#define ASI_QUEUE 0x25 /* [4v] interrupt queue registers */ 62#define ASI_NUCLEUS_QUAD_LDD_LITTLE 0x2c /* [4u] use w/LDDA to load 128-bit item, little endian */ 63 64#define ASI_FLUSH_D_PAGE_PRIMARY 0x38 /* [4u] flush D-cache page using primary context */ 65#define ASI_FLUSH_D_PAGE_SECONDARY 0x39 /* [4u] flush D-cache page using secondary context */ 66#define ASI_FLUSH_D_CTX_PRIMARY 0x3a /* [4u] flush D-cache context using primary context */ 67#define ASI_FLUSH_D_CTX_SECONDARY 0x3b /* [4u] flush D-cache context using secondary context */ 68 69#define ASI_DCACHE_INVALIDATE 0x42 /* [III] invalidate D-cache */ 70#define ASI_DCACHE_UTAG 0x43 /* [III] diagnostic access to D-cache micro tag */ 71#define ASI_DCACHE_SNOOP_TAG 0x44 /* [III] diagnostic access to D-cache snoop tag RAM */ 72 73#define ASI_LSU_CONTROL_REGISTER 0x45 /* [4u] load/store unit control register */ 74 75#define ASI_DCACHE_DATA 0x46 /* [4u] diagnostic access to D-cache data RAM */ 76#define ASI_DCACHE_TAG 0x47 /* [4u] diagnostic access to D-cache tag RAM */ 77 78#define ASI_INTR_DISPATCH_STATUS 0x48 /* [4u] interrupt dispatch status register */ 79#define ASI_INTR_RECEIVE 0x49 /* [4u] interrupt receive status register */ 80#define ASI_MID_REG 0x4a /* [4u] hardware config and MID */ 81#define ASI_ERROR_EN_REG 0x4b /* [4u] asynchronous error enables */ 82#define ASI_AFSR 0x4c /* [4u] asynchronous fault status register */ 83#define ASI_AFAR 0x4d /* [4u] asynchronous fault address register */ 84 85#define ASI_ICACHE_DATA 0x66 /* [4u] diagnostic access to I-cache data RAM */ 86#define ASI_ICACHE_TAG 0x67 /* [4u] diagnostic access to I-cache tag RAM */ 87#define ASI_FLUSH_I_PAGE_PRIMARY 0x68 /* [4u] flush I-cache page using primary context */ 88#define ASI_FLUSH_I_PAGE_SECONDARY 0x69 /* [4u] flush I-cache page using secondary context */ 89#define ASI_FLUSH_I_CTX_PRIMARY 0x6a /* [4u] flush I-cache context using primary context */ 90#define ASI_FLUSH_I_CTX_SECONDARY 0x6b /* [4u] flush I-cache context using secondary context */ 91 92#define ASI_BLOCK_AS_IF_USER_PRIMARY 0x70 /* [4u] primary user address space, block loads/stores */ 93#define ASI_BLOCK_AS_IF_USER_SECONDARY 0x71 /* [4u] secondary user address space, block loads/stores */ 94 95#define ASI_ECACHE_DIAG 0x76 /* [4u] diag access to E-cache tag and data */ 96#define ASI_DATAPATH_ERR_REG_WRITE 0x77 /* [4u] ASI is reused */ 97 98#define ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 0x78 /* [4u] primary user address space, block loads/stores */ 99#define ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 0x79 /* [4u] secondary user address space, block loads/stores */ 100 101#define ASI_INTERRUPT_RECEIVE_DATA 0x7f /* [4u] interrupt receive data registers {0,1,2} */ 102#define ASI_DATAPATH_ERR_REG_READ 0x7f /* [4u] read access to datapath error registers (ASI reused) */ 103 104#define ASI_PRIMARY 0x80 /* [4u] primary address space */ 105#define ASI_SECONDARY 0x81 /* [4u] secondary address space */ 106#define ASI_PRIMARY_NOFAULT 0x82 /* [4u] primary address space, no fault */ 107#define ASI_SECONDARY_NOFAULT 0x83 /* [4u] secondary address space, no fault */ 108 109#define ASI_PRIMARY_LITTLE 0x88 /* [4u] primary address space, little endian */ 110#define ASI_SECONDARY_LITTLE 0x89 /* [4u] secondary address space, little endian */ 111#define ASI_PRIMARY_NOFAULT_LITTLE 0x8a /* [4u] primary address space, no fault, little endian */ 112#define ASI_SECONDARY_NOFAULT_LITTLE 0x8b /* [4u] secondary address space, no fault, little endian */ 113 114#define ASI_PST8_PRIMARY 0xc0 /* [VIS] Eight 8-bit partial store, primary */ 115#define ASI_PST8_SECONDARY 0xc1 /* [VIS] Eight 8-bit partial store, secondary */ 116#define ASI_PST16_PRIMARY 0xc2 /* [VIS] Four 16-bit partial store, primary */ 117#define ASI_PST16_SECONDARY 0xc3 /* [VIS] Fout 16-bit partial store, secondary */ 118#define ASI_PST32_PRIMARY 0xc4 /* [VIS] Two 32-bit partial store, primary */ 119#define ASI_PST32_SECONDARY 0xc5 /* [VIS] Two 32-bit partial store, secondary */ 120 121#define ASI_PST8_PRIMARY_LITTLE 0xc8 /* [VIS] Eight 8-bit partial store, primary, little endian */ 122#define ASI_PST8_SECONDARY_LITTLE 0xc9 /* [VIS] Eight 8-bit partial store, secondary, little endian */ 123#define ASI_PST16_PRIMARY_LITTLE 0xca /* [VIS] Four 16-bit partial store, primary, little endian */ 124#define ASI_PST16_SECONDARY_LITTLE 0xcb /* [VIS] Fout 16-bit partial store, secondary, little endian */ 125#define ASI_PST32_PRIMARY_LITTLE 0xcc /* [VIS] Two 32-bit partial store, primary, little endian */ 126#define ASI_PST32_SECONDARY_LITTLE 0xcd /* [VIS] Two 32-bit partial store, secondary, little endian */ 127 128#define ASI_FL8_PRIMARY 0xd0 /* [VIS] One 8-bit load/store floating, primary */ 129#define ASI_FL8_SECONDARY 0xd1 /* [VIS] One 8-bit load/store floating, secondary */ 130#define ASI_FL16_PRIMARY 0xd2 /* [VIS] One 16-bit load/store floating, primary */ 131#define ASI_FL16_SECONDARY 0xd3 /* [VIS] One 16-bit load/store floating, secondary */ 132 133#define ASI_FL8_PRIMARY_LITTLE 0xd8 /* [VIS] One 8-bit load/store floating, primary, little endian */ 134#define ASI_FL8_SECONDARY_LITTLE 0xd9 /* [VIS] One 8-bit load/store floating, secondary, little endian */ 135#define ASI_FL16_PRIMARY_LITTLE 0xda /* [VIS] One 16-bit load/store floating, primary, little endian */ 136#define ASI_FL16_SECONDARY_LITTLE 0xdb /* [VIS] One 16-bit load/store floating, secondary, little endian */ 137 138#define ASI_BLOCK_COMMIT_PRIMARY 0xe0 /* [4u] block store with commit, primary */ 139#define ASI_BLOCK_COMMIT_SECONDARY 0xe1 /* [4u] block store with commit, secondary */ 140#define ASI_BLOCK_PRIMARY 0xf0 /* [4u] block load/store, primary */ 141#define ASI_BLOCK_SECONDARY 0xf1 /* [4u] block load/store, secondary */ 142#define ASI_BLOCK_PRIMARY_LITTLE 0xf8 /* [4u] block load/store, primary, little endian */ 143#define ASI_BLOCK_SECONDARY_LITTLE 0xf9 /* [4u] block load/store, secondary, little endian */ 144 145 146/* 147 * These are the shorter names used by Solaris 148 */ 149 150#define ASI_N ASI_NUCLEUS 151#define ASI_NL ASI_NUCLEUS_LITTLE 152#define ASI_AIUP ASI_AS_IF_USER_PRIMARY 153#define ASI_AIUS ASI_AS_IF_USER_SECONDARY 154#define ASI_AIUPL ASI_AS_IF_USER_PRIMARY_LITTLE 155#define ASI_AIUSL ASI_AS_IF_USER_SECONDARY_LITTLE 156#define ASI_P ASI_PRIMARY 157#define ASI_S ASI_SECONDARY 158#define ASI_PNF ASI_PRIMARY_NOFAULT 159#define ASI_SNF ASI_SECONDARY_NOFAULT 160#define ASI_PL ASI_PRIMARY_LITTLE 161#define ASI_SL ASI_SECONDARY_LITTLE 162#define ASI_PNFL ASI_PRIMARY_NOFAULT_LITTLE 163#define ASI_SNFL ASI_SECONDARY_NOFAULT_LITTLE 164#define ASI_FL8_P ASI_FL8_PRIMARY 165#define ASI_FL8_S ASI_FL8_SECONDARY 166#define ASI_FL16_P ASI_FL16_PRIMARY 167#define ASI_FL16_S ASI_FL16_SECONDARY 168#define ASI_FL8_PL ASI_FL8_PRIMARY_LITTLE 169#define ASI_FL8_SL ASI_FL8_SECONDARY_LITTLE 170#define ASI_FL16_PL ASI_FL16_PRIMARY_LITTLE 171#define ASI_FL16_SL ASI_FL16_SECONDARY_LITTLE 172#define ASI_BLK_AIUP ASI_BLOCK_AS_IF_USER_PRIMARY 173#define ASI_BLK_AIUPL ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE 174#define ASI_BLK_AIUS ASI_BLOCK_AS_IF_USER_SECONDARY 175#define ASI_BLK_AIUSL ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE 176#define ASI_BLK_COMMIT_P ASI_BLOCK_COMMIT_PRIMARY 177#define ASI_BLK_COMMIT_PRIMARY ASI_BLOCK_COMMIT_PRIMARY 178#define ASI_BLK_COMMIT_S ASI_BLOCK_COMMIT_SECONDARY 179#define ASI_BLK_COMMIT_SECONDARY ASI_BLOCK_COMMIT_SECONDARY 180#define ASI_BLK_P ASI_BLOCK_PRIMARY 181#define ASI_BLK_PL ASI_BLOCK_PRIMARY_LITTLE 182#define ASI_BLK_S ASI_BLOCK_SECONDARY 183#define ASI_BLK_SL ASI_BLOCK_SECONDARY_LITTLE 184 185/* Alternative spellings */ 186#define ASI_PRIMARY_NO_FAULT ASI_PRIMARY_NOFAULT 187#define ASI_PRIMARY_NO_FAULT_LITTLE ASI_PRIMARY_NOFAULT_LITTLE 188#define ASI_SECONDARY_NO_FAULT ASI_SECONDARY_NOFAULT 189#define ASI_SECONDARY_NO_FAULT_LITTLE ASI_SECONDARY_NOFAULT_LITTLE 190 191#define PHYS_ASI(x) (((x) | 0x09) == 0x1d) 192#define LITTLE_ASI(x) ((x) & ASI_LITTLE) 193 194/* 195 * The following are 4u control registers 196 */ 197 198/* Get the CPU's UPAID */ 199#define UPA_CR_MID_SHIFT (17) 200#define UPA_CR_MID_SIZE (5) 201#define UPA_CR_MID_MASK \ 202 (((1 << UPA_CR_MID_SIZE) - 1) << UPA_CR_MID_SHIFT) 203 204#define UPA_CR_MID(x) (((x)>>UPA_CR_MID_SHIFT)&((1 << UPA_CR_MID_SIZE) - 1)) 205 206#ifdef _LOCORE 207 208#define UPA_GET_MID(r1) \ 209 ldxa [%g0] ASI_MID_REG, r1 ; \ 210 srlx r1, UPA_CR_MID_SHIFT, r1 ; \ 211 and r1, (1 << UPA_CR_MID_SIZE) - 1, r1 212 213#else 214#define CPU_UPAID UPA_CR_MID(ldxa(0, ASI_MID_REG)) 215#endif 216 217/* Get the CPU's Fireplane agent ID */ 218#define FIREPLANE_CR_AID(x) (((x) >> 17) & 0x3ff) 219#define CPU_FIREPLANEID FIREPLANE_CR_AID(ldxa(0, ASI_MID_REG)) 220 221/* Get the CPU's Jupiter Bus interrupt target ID */ 222#define JUPITER_CR_ITID(x) ((x) & 0x3ff) 223#define CPU_JUPITERID JUPITER_CR_ITID(ldxa(0, ASI_MID_REG)) 224 225/* 226 * [4u] MMU and Cache Control Register (MCCR) 227 * use ASI = 0x45 228 */ 229#define ASI_MCCR ASI_LSU_CONTROL_REGISTER 230#define MCCR 0x00 231 232/* MCCR Bits and their meanings */ 233#define MCCR_DMMU_EN 0x08 234#define MCCR_IMMU_EN 0x04 235#define MCCR_DCACHE_EN 0x02 236#define MCCR_ICACHE_EN 0x01 237#define MCCR_RAW_EN 0x400000000000 238 239 240/* 241 * MMU control registers 242 */ 243 244/* Choose an MMU */ 245#define ASI_DMMU 0x58 246#define ASI_IMMU 0x50 247 248/* Other assorted MMU ASIs */ 249#define ASI_IMMU_8KPTR 0x51 250#define ASI_IMMU_64KPTR 0x52 251#define ASI_IMMU_DATA_IN 0x54 252#define ASI_IMMU_TLB_DATA 0x55 253#define ASI_IMMU_TLB_TAG 0x56 254#define ASI_DMMU_8KPTR 0x59 255#define ASI_DMMU_64KPTR 0x5a 256#define ASI_DMMU_DATA_IN 0x5c 257#define ASI_DMMU_TLB_DATA 0x5d 258#define ASI_DMMU_TLB_TAG 0x5e 259 260/* 261 * The following are the control registers 262 * They work on both MMUs unless noted. 263 * III = cheetah only 264 * 265 * Register contents are defined later on individual registers. 266 */ 267#define TSB_TAG_TARGET 0x0 268#define TLB_DATA_IN 0x0 269#define CTX_PRIMARY 0x08 /* primary context -- DMMU only */ 270#define CTX_SECONDARY 0x10 /* secondary context -- DMMU only */ 271#define SFSR 0x18 272#define SFAR 0x20 /* fault address -- DMMU only */ 273#define TSB 0x28 274#define TLB_TAG_ACCESS 0x30 275#define VIRTUAL_WATCHPOINT 0x38 276#define PHYSICAL_WATCHPOINT 0x40 277#define TSB_PEXT 0x48 /* III primary ext */ 278#define TSB_SEXT 0x50 /* III 2ndary ext -- DMMU only */ 279#define TSB_NEXT 0x58 /* III nucleus ext */ 280 281/* Tag Target bits */ 282#define TAG_TARGET_VA_MASK 0x03ffffffffffffffffLL 283#define TAG_TARGET_VA(x) (((x)<<22)&TAG_TARGET_VA_MASK) 284#define TAG_TARGET_CONTEXT(x) ((x)>>48) 285#define TAG_TARGET(c,v) ((((uint64_t)c)<<48)|(((uint64_t)v)&TAG_TARGET_VA_MASK)) 286 287/* SFSR bits for both D_SFSR and I_SFSR */ 288#define SFSR_ASI(x) ((x)>>16) 289#define SFSR_FT_VA_OOR_2 0x02000 /* IMMU: jumpl or return to unsupported VA */ 290#define SFSR_FT_VA_OOR_1 0x01000 /* fault at unsupported VA */ 291#define SFSR_FT_NFO 0x00800 /* DMMU: Access to page marked NFO */ 292#define SFSR_ILL_ASI 0x00400 /* DMMU: Illegal (unsupported) ASI */ 293#define SFSR_FT_IO_ATOMIC 0x00200 /* DMMU: Atomic access to noncacheable page */ 294#define SFSR_FT_ILL_NF 0x00100 /* DMMU: NF load or flush to page marked E (has side effects) */ 295#define SFSR_FT_PRIV 0x00080 /* Privilege violation */ 296#define SFSR_FT_E 0x00040 /* DMMU: value of E bit associated address */ 297#define SFSR_CTXT(x) (((x)>>4)&0x3) 298#define SFSR_CTXT_IS_PRIM(x) (SFSR_CTXT(x)==0x00) 299#define SFSR_CTXT_IS_SECOND(x) (SFSR_CTXT(x)==0x01) 300#define SFSR_CTXT_IS_NUCLEUS(x) (SFSR_CTXT(x)==0x02) 301#define SFSR_PRIV 0x00008 /* value of PSTATE.PRIV for faulting access */ 302#define SFSR_W 0x00004 /* DMMU: attempted write */ 303#define SFSR_OW 0x00002 /* Overwrite; prev vault was still valid */ 304#define SFSR_FV 0x00001 /* Fault is valid */ 305#define SFSR_FT (SFSR_FT_VA_OOR_2|SFSR_FT_VA_OOR_1|SFSR_FT_NFO| \ 306 SFSR_ILL_ASI|SFSR_FT_IO_ATOMIC|SFSR_FT_ILL_NF|SFSR_FT_PRIV) 307 308#define SFSR_BITS "\177\20" \ 309 "f\20\30ASI\0" "b\15VAT\0" "b\14VAD\0" \ 310 "b\13NFO\0" "b\12ASI\0" "b\11A\0" "b\10NF\0" \ 311 "b\07PRIV\0" "b\06E\0" "b\05NUCLEUS\0" "b\04SECONDCTX\0" \ 312 "b\03PRIV\0" "b\02W\0" "b\01OW\0" "b\00FV\0" 313 314/* ASFR bits */ 315#define ASFR_ME 0x100000000LL 316#define ASFR_PRIV 0x080000000LL 317#define ASFR_ISAP 0x040000000LL 318#define ASFR_ETP 0x020000000LL 319#define ASFR_IVUE 0x010000000LL 320#define ASFR_TO 0x008000000LL 321#define ASFR_BERR 0x004000000LL 322#define ASFR_LDP 0x002000000LL 323#define ASFR_CP 0x001000000LL 324#define ASFR_WP 0x000800000LL 325#define ASFR_EDP 0x000400000LL 326#define ASFR_UE 0x000200000LL 327#define ASFR_CE 0x000100000LL 328#define ASFR_ETS 0x0000f0000LL 329#define ASFT_P_SYND 0x00000ffffLL 330 331#define AFSR_BITS "\177\20" \ 332 "b\40ME\0" "b\37PRIV\0" "b\36ISAP\0" "b\35ETP\0" \ 333 "b\34IVUE\0" "b\33TO\0" "b\32BERR\0" "b\31LDP\0" \ 334 "b\30CP\0" "b\27WP\0" "b\26EDP\0" "b\25UE\0" \ 335 "b\24CE\0" "f\20\4ETS\0" "f\0\20P_SYND\0" 336 337/* 338 * Here's the spitfire TSB control register bits. 339 * 340 * Each TSB entry is 16-bytes wide. The TSB must be size aligned 341 */ 342#define TSB_SIZE_512 0x0 /* 8kB, etc. */ 343#define TSB_SIZE_1K 0x01 344#define TSB_SIZE_2K 0x02 345#define TSB_SIZE_4K 0x03 346#define TSB_SIZE_8K 0x04 347#define TSB_SIZE_16K 0x05 348#define TSB_SIZE_32K 0x06 349#define TSB_SIZE_64K 0x07 350#define TSB_SPLIT 0x1000 351#define TSB_BASE 0xffffffffffffe000 352 353/* TLB Tag Access bits */ 354#define TLB_TAG_ACCESS_VA 0xffffffffffffe000 355#define TLB_TAG_ACCESS_CTX 0x0000000000001fff 356 357/* 358 * TLB demap registers. TTEs are defined in v9pte.h 359 * 360 * Use the address space to select between IMMU and DMMU. 361 * The address of the register selects which context register 362 * to read the ASI from. 363 * 364 * The data stored in the register is interpreted as the VA to 365 * use. The DEMAP_CTX_<> registers ignore the address and demap the 366 * entire ASI. 367 * 368 */ 369#define ASI_IMMU_DEMAP 0x57 /* [4u] IMMU TLB demap */ 370#define ASI_DMMU_DEMAP 0x5f /* [4u] IMMU TLB demap */ 371 372#define DEMAP_PAGE_NUCLEUS ((0x02)<<4) /* Demap page from kernel AS */ 373#define DEMAP_PAGE_PRIMARY ((0x00)<<4) /* Demap a page from primary CTXT */ 374#define DEMAP_PAGE_SECONDARY ((0x01)<<4) /* Demap page from secondary CTXT (DMMU only) */ 375#define DEMAP_CTX_NUCLEUS ((0x06)<<4) /* Demap all of kernel CTXT */ 376#define DEMAP_CTX_PRIMARY ((0x04)<<4) /* Demap all of primary CTXT */ 377#define DEMAP_CTX_SECONDARY ((0x05)<<4) /* Demap all of secondary CTXT */ 378#define DEMAP_ALL ((0x08)<<4) /* Demap all non-locked TLB entries [USIII] */ 379 380/* 381 * These define the sizes of the TLB in various CPUs. 382 * They're mostly not necessary except for diagnostic code. 383 */ 384#define TLB_SIZE_SPITFIRE 64 385#define TLB_SIZE_CHEETAH_I16 16 386#define TLB_SIZE_CHEETAH_I128 128 387#define TLB_SIZE_CHEETAH_D16 16 388#define TLB_SIZE_CHEETAH_D512_0 512 389#define TLB_SIZE_CHEETAH_D512_1 512 390#define TLB_CHEETAH_I16 (0 << 16) 391#define TLB_CHEETAH_I128 (2 << 16) 392#define TLB_CHEETAH_D16 (0 << 16) 393#define TLB_CHEETAH_D512_0 (2 << 16) 394#define TLB_CHEETAH_D512_1 (3 << 16) 395 396/* 397 * Interrupt registers. This really gets hairy. 398 */ 399 400/* IRSR -- Interrupt Receive Status Register */ 401#define ASI_IRSR 0x49 402#define IRSR 0x00 403#define IRSR_BUSY 0x020 404#define IRSR_MID(x) (x&0x1f) 405 406/* IRDR -- Interrupt Receive Data Registers */ 407#define ASI_IRDR 0x7f 408#define IRDR_0H 0x40 409#define IRDR_0L 0x48 /* unimplemented */ 410#define IRDR_1H 0x50 411#define IRDR_1L 0x58 /* unimplemented */ 412#define IRDR_2H 0x60 413#define IRDR_2L 0x68 /* unimplemented */ 414#define IRDR_3H 0x70 /* unimplemented */ 415#define IRDR_3L 0x78 /* unimplemented */ 416 417/* Interrupt Dispatch -- usually reserved for cross-calls */ 418#define ASI_IDSR 0x48 /* Interrupt dispatch status reg */ 419#define IDSR 0x00 420#define IDSR_NACK 0x02 421#define IDSR_BUSY 0x01 422 423#define ASI_INTERRUPT_DISPATCH 0x77 /* [4u] spitfire interrupt dispatch regs */ 424 425/* Interrupt delivery initiation */ 426#define IDCR(x) ((((uint64_t)(x)) << 14) | 0x70) 427 428#define IDDR_0H 0x40 /* Store data to send in these regs */ 429#define IDDR_0L 0x48 /* unimplemented */ 430#define IDDR_1H 0x50 431#define IDDR_1L 0x58 /* unimplemented */ 432#define IDDR_2H 0x60 433#define IDDR_2L 0x68 /* unimplemented */ 434#define IDDR_3H 0x70 /* unimplemented */ 435#define IDDR_3L 0x78 /* unimplemented */ 436 437/* 438 * Error registers 439 */ 440 441/* Since we won't try to fix async errs, we don't care about the bits in the regs */ 442#define ASI_AFAR 0x4d /* Asynchronous fault address register */ 443#define AFAR 0x00 444#define ASI_AFSR 0x4c /* Asynchronous fault status register */ 445#define AFSR 0x00 446 447#define ASI_P_EER 0x4b /* Error enable register */ 448#define P_EER 0x00 449#define P_EER_ISAPEN 0x04 /* Enable fatal on ISAP */ 450#define P_EER_NCEEN 0x02 /* Enable trap on uncorrectable errs */ 451#define P_EER_CEEN 0x01 /* Enable trap on correctable errs */ 452 453#define ASI_DATAPATH_READ 0x7f /* Read the regs */ 454#define ASI_DATAPATH_WRITE 0x77 /* Write to the regs */ 455#define P_DPER_0 0x00 /* Datapath err reg 0 */ 456#define P_DPER_1 0x18 /* Datapath err reg 1 */ 457#define P_DCR_0 0x20 /* Datapath control reg 0 */ 458#define P_DCR_1 0x38 /* Datapath control reg 0 */ 459 460 461/* From sparc64/asm.h which I think I'll deprecate since it makes bus.h a pain. */ 462 463#ifndef _LOCORE 464/* 465 * GCC __asm constructs for doing assembly stuff. 466 */ 467 468/* 469 * ``Routines'' to load and store from/to alternate address space. 470 * The location can be a variable, the asi value (address space indicator) 471 * must be a constant. 472 * 473 * N.B.: You can put as many special functions here as you like, since 474 * they cost no kernel space or time if they are not used. 475 * 476 * These were static inline functions, but gcc screws up the constraints 477 * on the address space identifiers (the "n"umeric value part) because 478 * it inlines too late, so we have to use the funny valued-macro syntax. 479 */ 480 481/* 482 * Apparently the definition of bypass ASIs is that they all use the 483 * D$ so we need to flush the D$ to make sure we don't get data pollution. 484 */ 485 486#ifdef __arch64__ 487 488/* 64-bit kernel, non-constant */ 489#define SPARC64_LD_NONCONST(ld) \ 490 __asm volatile( \ 491 "wr %2,%%g0,%%asi; " \ 492 #ld " [%1]%%asi,%0 " \ 493 : "=r" (_v) \ 494 : "r" ((__uintptr_t)(loc)), "r" (asi)) 495 496#if defined(__GNUC__) && defined(__OPTIMIZE__) 497#define SPARC64_LD_DEF(ld, type, vtype) \ 498static __inline type ld(paddr_t loc, int asi) \ 499{ \ 500 vtype _v; \ 501 if (__builtin_constant_p(asi)) \ 502 __asm volatile( \ 503 #ld " [%1]%2,%0 " \ 504 : "=r" (_v) \ 505 : "r" ((__uintptr_t)(loc)), "n" (asi)); \ 506 else \ 507 SPARC64_LD_NONCONST(ld); \ 508 return _v; \ 509} 510#else 511#define SPARC64_LD_DEF(ld, type, vtype) \ 512static __inline type ld(paddr_t loc, int asi) \ 513{ \ 514 vtype _v; \ 515 SPARC64_LD_NONCONST(ld); \ 516 return _v; \ 517} 518#endif 519#define SPARC64_LD_DEF64(ld, type) SPARC64_LD_DEF(ld, type, uint64_t) 520 521#else /* __arch64__ */ 522 523/* 32-bit kernel, MMU bypass, non-constant */ 524#define SPARC64_LD_PHYS_NONCONST(ld) \ 525 __asm volatile( \ 526 "clruw %2; " \ 527 "rdpr %%pstate,%1; " \ 528 "sllx %3,32,%0; " \ 529 "wrpr %1,8,%%pstate; " \ 530 "or %0,%2,%0; " \ 531 "wr %4,%%g0,%%asi; " \ 532 #ld " [%0]%%asi,%0; " \ 533 "wrpr %1,0,%%pstate " \ 534 : "=&r" (_v), "=&r" (_pstate) \ 535 : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi)) 536/* 32-bit kernel, non-constant */ 537#define SPARC64_LD_NONCONST(ld) \ 538 __asm volatile( \ 539 "wr %2,%%g0,%%asi; " \ 540 #ld " [%1]%%asi,%0 " \ 541 : "=&r" (_v) \ 542 : "r" ((uint32_t)(loc)), "r" (asi)) 543/* 32-bit kernel, MMU bypass, non-constant, 64-bit value */ 544#define SPARC64_LD_PHYS_NONCONST64(ld) \ 545 __asm volatile( \ 546 "clruw %2; " \ 547 "rdpr %%pstate,%1; " \ 548 "sllx %3,32,%0; " \ 549 "wrpr %1,8,%%pstate; " \ 550 "or %0,%2,%0; " \ 551 "wr %4,%%g0,%%asi; " \ 552 #ld " [%0]%%asi,%0; " \ 553 "wrpr %1,0,%%pstate; " \ 554 "srlx %0,32,%1; " \ 555 "srl %0,0,%0 " \ 556 : "=&r" (_vlo), "=&r" (_vhi) \ 557 : "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi)) 558/* 32-bit kernel, non-constant, 64-bit value */ 559#define SPARC64_LD_NONCONST64(ld) \ 560 __asm volatile( \ 561 "wr %3,%%g0,%%asi; " \ 562 #ld " [%2]%%asi,%0; " \ 563 "srlx %0,32,%1; " \ 564 "srl %0,0,%0 " \ 565 : "=&r" (_vlo), "=&r" (_vhi) \ 566 : "r" ((uint32_t)(loc)), "r" (asi)) 567 568#if defined(__GNUC__) && defined(__OPTIMIZE__) 569#define SPARC64_LD_DEF(ld, type, vtype) \ 570static __inline type ld(paddr_t loc, int asi) \ 571{ \ 572 vtype _v; \ 573 uint32_t _hi, _pstate; \ 574 if (PHYS_ASI(asi)) { \ 575 _hi = (uint64_t)(loc) >> 32; \ 576 if (__builtin_constant_p(asi)) \ 577 __asm volatile( \ 578 "clruw %2; " \ 579 "rdpr %%pstate,%1; " \ 580 "sllx %3,32,%0; " \ 581 "wrpr %1,8,%%pstate; " \ 582 "or %0,%2,%0; " \ 583 #ld " [%0]%4,%0; " \ 584 "wrpr %1,0,%%pstate; " \ 585 : "=&r" (_v), "=&r" (_pstate) \ 586 : "r" ((uint32_t)(loc)), "r" (_hi), \ 587 "n" (asi)); \ 588 else \ 589 SPARC64_LD_PHYS_NONCONST(ld); \ 590 } else { \ 591 if (__builtin_constant_p(asi)) \ 592 __asm volatile( \ 593 #ld " [%1]%2,%0 " \ 594 : "=&r" (_v) \ 595 : "r" ((uint32_t)(loc)), "n" (asi)); \ 596 else \ 597 SPARC64_LD_NONCONST(ld); \ 598 } \ 599 return _v; \ 600} 601#define SPARC64_LD_DEF64(ld, type) \ 602static __inline type ld(paddr_t loc, int asi) \ 603{ \ 604 uint32_t _vlo, _vhi, _hi; \ 605 if (PHYS_ASI(asi)) { \ 606 _hi = (uint64_t)(loc) >> 32; \ 607 if (__builtin_constant_p(asi)) \ 608 __asm volatile( \ 609 "clruw %2; " \ 610 "rdpr %%pstate,%1; " \ 611 "sllx %3,32,%0; " \ 612 "wrpr %1,8,%%pstate; " \ 613 "or %0,%2,%0; " \ 614 #ld " [%0]%4,%0; " \ 615 "wrpr %1,0,%%pstate; " \ 616 "srlx %0,32,%1; " \ 617 "srl %0,0,%0 " \ 618 : "=&r" (_vlo), "=&r" (_vhi) \ 619 : "r" ((uint32_t)(loc)), "r" (_hi), \ 620 "n" (asi)); \ 621 else \ 622 SPARC64_LD_PHYS_NONCONST64(ld); \ 623 } else { \ 624 if (__builtin_constant_p(asi)) \ 625 __asm volatile( \ 626 #ld " [%2]%3,%0; " \ 627 "srlx %0,32,%1; " \ 628 "srl %0,0,%0 " \ 629 : "=&r" (_vlo), "=&r" (_vhi) \ 630 : "r" ((uint32_t)(loc)), "n" (asi)); \ 631 else \ 632 SPARC64_LD_NONCONST64(ld); \ 633 } \ 634 return ((uint64_t)_vhi << 32) | _vlo; \ 635} 636#else 637#define SPARC64_LD_DEF(ld, type, vtype) \ 638static __inline type ld(paddr_t loc, int asi) \ 639{ \ 640 vtype _v; \ 641 uint32_t _hi, _pstate; \ 642 if (PHYS_ASI(asi)) { \ 643 _hi = (uint64_t)(loc) >> 32; \ 644 SPARC64_LD_PHYS_NONCONST(ld); \ 645 } else \ 646 SPARC64_LD_NONCONST(ld); \ 647 return _v; \ 648} 649#define SPARC64_LD_DEF64(ld, type) \ 650static __inline type ld(paddr_t loc, int asi) \ 651{ \ 652 uint32_t _vlo, _vhi, _hi; \ 653 if (PHYS_ASI(asi)) { \ 654 _hi = (uint64_t)(loc) >> 32; \ 655 SPARC64_LD_PHYS_NONCONST64(ld); \ 656 } else \ 657 SPARC64_LD_NONCONST64(ld); \ 658 return ((uint64_t)_vhi << 32) | _vlo; \ 659} 660#endif 661 662#endif /* __arch64__ */ 663 664/* load byte from alternate address space */ 665SPARC64_LD_DEF(lduba, uint8_t, uint32_t) 666/* load half-word from alternate address space */ 667SPARC64_LD_DEF(lduha, uint16_t, uint32_t) 668/* load unsigned int from alternate address space */ 669SPARC64_LD_DEF(lda, uint32_t, uint32_t) 670/* load unsigned word from alternate address space */ 671SPARC64_LD_DEF(lduwa, uint32_t, uint32_t) 672/* load signed int from alternate address space */ 673SPARC64_LD_DEF(ldswa, int, int) 674/* load 64-bit unsigned int from alternate address space */ 675SPARC64_LD_DEF64(ldxa, uint64_t) 676 677 678#ifdef __arch64__ 679 680/* 64-bit kernel, non-constant */ 681#define SPARC64_ST_NONCONST(st) \ 682 __asm volatile( \ 683 "wr %2,%%g0,%%asi; " \ 684 #st " %0,[%1]%%asi " \ 685 : : "r" (value), "r" ((__uintptr_t)(loc)), \ 686 "r" (asi)) 687 688#if defined(__GNUC__) && defined(__OPTIMIZE__) 689#define SPARC64_ST_DEF(st, type) \ 690static __inline void st(paddr_t loc, int asi, type value) \ 691{ \ 692 if (__builtin_constant_p(asi)) \ 693 __asm volatile( \ 694 #st " %0,[%1]%2 " \ 695 : : "r" (value), "r" ((__uintptr_t)(loc)), \ 696 "n" (asi)); \ 697 else \ 698 SPARC64_ST_NONCONST(st); \ 699} 700#else 701#define SPARC64_ST_DEF(st, type) \ 702static __inline void st(paddr_t loc, int asi, type value) \ 703{ \ 704 SPARC64_ST_NONCONST(st); \ 705} 706#endif 707#define SPARC64_ST_DEF64(st, type) SPARC64_ST_DEF(st, type) 708 709#else /* __arch64__ */ 710 711/* 32-bit kernel, MMU bypass, non-constant */ 712#define SPARC64_ST_PHYS_NONCONST(st) \ 713 __asm volatile( \ 714 "clruw %3; " \ 715 "rdpr %%pstate,%1; " \ 716 "sllx %4,32,%0; " \ 717 "wrpr %1,8,%%pstate; " \ 718 "or %0,%3,%0; " \ 719 "wr %5,%%g0,%%asi; " \ 720 #st " %2,[%0]%%asi; " \ 721 "wrpr %1,0,%%pstate " \ 722 : "=&r" (_hi), "=&r" (_pstate) \ 723 : "r" (value), "r" ((uint32_t)(loc)), \ 724 "r" (_hi), "r" (asi)) 725/* 32-bit kernel, non-constant */ 726#define SPARC64_ST_NONCONST(st) \ 727 __asm volatile( \ 728 "wr %2,%%g0,%%asi; " \ 729 #st " %0,[%1]%%asi " \ 730 : : "r" (value), "r" ((uint32_t)(loc)), "r" (asi)) 731/* 32-bit kernel, MMU bypass, non-constant, 64-bit value */ 732#define SPARC64_ST_PHYS_NONCONST64(st) \ 733 __asm volatile( \ 734 "clruw %3; " \ 735 "clruw %5; " \ 736 "sllx %4,32,%1; " \ 737 "sllx %6,32,%0; " \ 738 "rdpr %%pstate,%2; " \ 739 "or %1,%3,%1; " \ 740 "wrpr %2,8,%%pstate; " \ 741 "or %0,%5,%0; " \ 742 "wr %7,%%g0,%%asi; " \ 743 #st " %1,[%0]%%asi; " \ 744 "wrpr %2,0,%%pstate " \ 745 : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo) \ 746 : "r" (_vlo), "r" (_vhi), \ 747 "r" ((uint32_t)(loc)), "r" (_hi), "r" (asi)) 748/* 32-bit kernel, non-constant, 64-bit value */ 749#define SPARC64_ST_NONCONST64(st) \ 750 __asm volatile( \ 751 "clruw %1; " \ 752 "sllx %2,32,%0; " \ 753 "or %0,%1,%0; " \ 754 "wr %4,%%g0,%%asi; " \ 755 #st " %0,[%3]%%asi " \ 756 : "=&r" (_vhi) \ 757 : "r" (_vlo), "r" (_vhi), \ 758 "r" ((uint32_t)(loc)), "r" (asi)) 759 760#if defined(__GNUC__) && defined(__OPTIMIZE__) 761#define SPARC64_ST_DEF(st, type) \ 762static __inline void st(paddr_t loc, int asi, type value) \ 763{ \ 764 uint32_t _hi, _pstate; \ 765 if (PHYS_ASI(asi)) { \ 766 _hi = (uint64_t)(loc) >> 32; \ 767 if (__builtin_constant_p(asi)) \ 768 __asm volatile( \ 769 "clruw %3; " \ 770 "sllx %4,32,%0; " \ 771 "rdpr %%pstate,%1; " \ 772 "or %0,%3,%0; " \ 773 "wrpr %1,8,%%pstate; " \ 774 #st " %2,[%0]%5; " \ 775 "wrpr %1,0,%%pstate " \ 776 : "=&r" (_hi), "=&r" (_pstate) \ 777 : "r" (value), "r" ((uint32_t)(loc)), \ 778 "r" (_hi), "n" (asi)); \ 779 else \ 780 SPARC64_ST_PHYS_NONCONST(st); \ 781 } else { \ 782 if (__builtin_constant_p(asi)) \ 783 __asm volatile( \ 784 #st " %0,[%1]%2 " \ 785 : : "r" (value), "r" ((uint32_t)(loc)), \ 786 "n" (asi)); \ 787 else \ 788 SPARC64_ST_NONCONST(st); \ 789 } \ 790} 791#define SPARC64_ST_DEF64(st, type) \ 792static __inline void st(paddr_t loc, int asi, type value) \ 793{ \ 794 uint32_t _vlo, _vhi, _hi; \ 795 _vlo = value; \ 796 _vhi = (uint64_t)(value) >> 32; \ 797 if (PHYS_ASI(asi)) { \ 798 _hi = (uint64_t)(loc) >> 32; \ 799 if (__builtin_constant_p(asi)) \ 800 __asm volatile( \ 801 "clruw %3; " \ 802 "clruw %5; " \ 803 "sllx %4,32,%1; " \ 804 "sllx %6,32,%0; " \ 805 "rdpr %%pstate,%2; " \ 806 "or %1,%3,%1; " \ 807 "or %0,%5,%0; " \ 808 "wrpr %2,8,%%pstate; " \ 809 #st " %1,[%0]%7; " \ 810 "wrpr %2,0,%%pstate " \ 811 : "=&r" (_hi), "=&r" (_vhi), "=&r" (_vlo) \ 812 : "r" (_vlo), "r" (_vhi), \ 813 "r" ((uint32_t)(loc)), "r" (_hi), \ 814 "n" (asi)); \ 815 else \ 816 SPARC64_ST_PHYS_NONCONST64(st); \ 817 } else { \ 818 if (__builtin_constant_p(asi)) \ 819 __asm volatile( \ 820 "clruw %1; " \ 821 "sllx %2,32,%0; " \ 822 "or %0,%1,%0; " \ 823 #st " %0,[%3]%4 " \ 824 : "=&r" (_vhi) \ 825 : "r" (_vlo), "r" (_vhi), \ 826 "r" ((uint32_t)(loc)), "n" (asi)); \ 827 else \ 828 SPARC64_ST_NONCONST64(st); \ 829 } \ 830} 831#else 832#define SPARC64_ST_DEF(st, type) \ 833static __inline void st(paddr_t loc, int asi, type value) \ 834{ \ 835 uint32_t _hi, _pstate; \ 836 if (PHYS_ASI(asi)) { \ 837 _hi = (uint64_t)(loc) >> 32; \ 838 SPARC64_ST_PHYS_NONCONST(st); \ 839 } else \ 840 SPARC64_ST_NONCONST(st); \ 841} 842#define SPARC64_ST_DEF64(st, type) \ 843static __inline void st(paddr_t loc, int asi, type value) \ 844{ \ 845 uint32_t _vlo, _vhi, _hi; \ 846 _vlo = value; \ 847 _vhi = (uint64_t)(value) >> 32; \ 848 if (PHYS_ASI(asi)) { \ 849 _hi = (uint64_t)(loc) >> 32; \ 850 SPARC64_ST_PHYS_NONCONST64(st); \ 851 } else \ 852 SPARC64_ST_NONCONST64(st); \ 853} 854#endif 855 856#endif /* __arch64__ */ 857 858/* store byte to alternate address space */ 859SPARC64_ST_DEF(stba, uint8_t) 860/* store half-word to alternate address space */ 861SPARC64_ST_DEF(stha, uint16_t) 862/* store unsigned int to alternate address space */ 863SPARC64_ST_DEF(sta, uint32_t) 864/* store 64-bit unsigned int to alternate address space */ 865SPARC64_ST_DEF64(stxa, uint64_t) 866 867 868 869/* flush address from cache */ 870#define sparc_flush_icache(loc) __asm \ 871 volatile("flush %0" : : "r" ((__uintptr_t)(loc))) 872 873/* 874 * SPARC V9 memory barrier instructions. 875 */ 876/* Make all stores complete before next store */ 877#define membar_StoreStore() __asm volatile("membar #StoreStore" : :) 878/* Make all loads complete before next store */ 879#define membar_LoadStore() __asm volatile("membar #LoadStore" : :) 880/* Make all stores complete before next load */ 881#define membar_StoreLoad() __asm volatile("membar #StoreLoad" : :) 882/* Make all loads complete before next load */ 883#define membar_LoadLoad() __asm volatile("membar #LoadLoad" : :) 884/* Complete all outstanding memory operations and exceptions */ 885#define membar_Sync() __asm volatile("membar #Sync" : :) 886/* Complete all outstanding memory operations */ 887#define membar_MemIssue() __asm volatile("membar #MemIssue" : :) 888/* Complete all outstanding stores before any new loads */ 889#define membar_Lookaside() __asm volatile("membar #Lookaside" : :) 890 891#define membar_Load() __asm volatile("membar #LoadLoad | #LoadStore" : :) 892#define membar_Store() __asm volatile("membar #LoadStore | #StoreStore" : :) 893 894#endif 895 896#endif /* _SPARC_CTLREG_H_ */ 897