162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * ross.h: Ross module specific definitions and defines. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _SPARC_ROSS_H 962306a36Sopenharmony_ci#define _SPARC_ROSS_H 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <asm/asi.h> 1262306a36Sopenharmony_ci#include <asm/page.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* Ross made Hypersparcs have a %psr 'impl' field of '0001'. The 'vers' 1562306a36Sopenharmony_ci * field has '1111'. 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/* The MMU control register fields on the HyperSparc. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * ----------------------------------------------------------------- 2162306a36Sopenharmony_ci * |implvers| RSV |CWR|SE|WBE| MID |BM| C|CS|MR|CM|RSV|CE|RSV|NF|ME| 2262306a36Sopenharmony_ci * ----------------------------------------------------------------- 2362306a36Sopenharmony_ci * 31 24 23-22 21 20 19 18-15 14 13 12 11 10 9 8 7-2 1 0 2462306a36Sopenharmony_ci * 2562306a36Sopenharmony_ci * Phew, lots of fields there ;-) 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * CWR: Cache Wrapping Enabled, if one cache wrapping is on. 2862306a36Sopenharmony_ci * SE: Snoop Enable, turns on bus snooping for cache activity if one. 2962306a36Sopenharmony_ci * WBE: Write Buffer Enable, one turns it on. 3062306a36Sopenharmony_ci * MID: The ModuleID of the chip for MBus transactions. 3162306a36Sopenharmony_ci * BM: Boot-Mode. One indicates the MMU is in boot mode. 3262306a36Sopenharmony_ci * C: Indicates whether accesses are cachable while the MMU is 3362306a36Sopenharmony_ci * disabled. 3462306a36Sopenharmony_ci * CS: Cache Size -- 0 = 128k, 1 = 256k 3562306a36Sopenharmony_ci * MR: Memory Reflection, one indicates that the memory bus connected 3662306a36Sopenharmony_ci * to the MBus supports memory reflection. 3762306a36Sopenharmony_ci * CM: Cache Mode -- 0 = write-through, 1 = copy-back 3862306a36Sopenharmony_ci * CE: Cache Enable -- 0 = no caching, 1 = cache is on 3962306a36Sopenharmony_ci * NF: No Fault -- 0 = faults trap the CPU from supervisor mode 4062306a36Sopenharmony_ci * 1 = faults from supervisor mode do not generate traps 4162306a36Sopenharmony_ci * ME: MMU Enable -- 0 = MMU is off, 1 = MMU is on 4262306a36Sopenharmony_ci */ 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci#define HYPERSPARC_CWENABLE 0x00200000 4562306a36Sopenharmony_ci#define HYPERSPARC_SBENABLE 0x00100000 4662306a36Sopenharmony_ci#define HYPERSPARC_WBENABLE 0x00080000 4762306a36Sopenharmony_ci#define HYPERSPARC_MIDMASK 0x00078000 4862306a36Sopenharmony_ci#define HYPERSPARC_BMODE 0x00004000 4962306a36Sopenharmony_ci#define HYPERSPARC_ACENABLE 0x00002000 5062306a36Sopenharmony_ci#define HYPERSPARC_CSIZE 0x00001000 5162306a36Sopenharmony_ci#define HYPERSPARC_MRFLCT 0x00000800 5262306a36Sopenharmony_ci#define HYPERSPARC_CMODE 0x00000400 5362306a36Sopenharmony_ci#define HYPERSPARC_CENABLE 0x00000100 5462306a36Sopenharmony_ci#define HYPERSPARC_NFAULT 0x00000002 5562306a36Sopenharmony_ci#define HYPERSPARC_MENABLE 0x00000001 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/* The ICCR instruction cache register on the HyperSparc. 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * ----------------------------------------------- 6162306a36Sopenharmony_ci * | | FTD | ICE | 6262306a36Sopenharmony_ci * ----------------------------------------------- 6362306a36Sopenharmony_ci * 31 1 0 6462306a36Sopenharmony_ci * 6562306a36Sopenharmony_ci * This register is accessed using the V8 'wrasr' and 'rdasr' 6662306a36Sopenharmony_ci * opcodes, since not all assemblers understand them and those 6762306a36Sopenharmony_ci * that do use different semantics I will just hard code the 6862306a36Sopenharmony_ci * instruction with a '.word' statement. 6962306a36Sopenharmony_ci * 7062306a36Sopenharmony_ci * FTD: If set to one flush instructions executed during an 7162306a36Sopenharmony_ci * instruction cache hit occurs, the corresponding line 7262306a36Sopenharmony_ci * for said cache-hit is invalidated. If FTD is zero, 7362306a36Sopenharmony_ci * an unimplemented 'flush' trap will occur when any 7462306a36Sopenharmony_ci * flush is executed by the processor. 7562306a36Sopenharmony_ci * 7662306a36Sopenharmony_ci * ICE: If set to one, the instruction cache is enabled. If 7762306a36Sopenharmony_ci * zero, the cache will not be used for instruction fetches. 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * All other bits are read as zeros, and writes to them have no 8062306a36Sopenharmony_ci * effect. 8162306a36Sopenharmony_ci * 8262306a36Sopenharmony_ci * Wheee, not many assemblers understand the %iccr register nor 8362306a36Sopenharmony_ci * the generic asr r/w instructions. 8462306a36Sopenharmony_ci * 8562306a36Sopenharmony_ci * 1000 0011 0100 0111 1100 0000 0000 0000 ! rd %iccr, %g1 8662306a36Sopenharmony_ci * 8762306a36Sopenharmony_ci * 0x 8 3 4 7 c 0 0 0 ! 0x8347c000 8862306a36Sopenharmony_ci * 8962306a36Sopenharmony_ci * 1011 1111 1000 0000 0110 0000 0000 0000 ! wr %g1, 0x0, %iccr 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * 0x b f 8 0 6 0 0 0 ! 0xbf806000 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci#define HYPERSPARC_ICCR_FTD 0x00000002 9662306a36Sopenharmony_ci#define HYPERSPARC_ICCR_ICE 0x00000001 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic inline unsigned int get_ross_icr(void) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci unsigned int icreg; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci __asm__ __volatile__(".word 0x8347c000\n\t" /* rd %iccr, %g1 */ 10562306a36Sopenharmony_ci "mov %%g1, %0\n\t" 10662306a36Sopenharmony_ci : "=r" (icreg) 10762306a36Sopenharmony_ci : /* no inputs */ 10862306a36Sopenharmony_ci : "g1", "memory"); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci return icreg; 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_cistatic inline void put_ross_icr(unsigned int icreg) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci __asm__ __volatile__("or %%g0, %0, %%g1\n\t" 11662306a36Sopenharmony_ci ".word 0xbf806000\n\t" /* wr %g1, 0x0, %iccr */ 11762306a36Sopenharmony_ci "nop\n\t" 11862306a36Sopenharmony_ci "nop\n\t" 11962306a36Sopenharmony_ci "nop\n\t" 12062306a36Sopenharmony_ci : /* no outputs */ 12162306a36Sopenharmony_ci : "r" (icreg) 12262306a36Sopenharmony_ci : "g1", "memory"); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci/* HyperSparc specific cache flushing. */ 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci/* This is for the on-chip instruction cache. */ 13062306a36Sopenharmony_cistatic inline void hyper_flush_whole_icache(void) 13162306a36Sopenharmony_ci{ 13262306a36Sopenharmony_ci __asm__ __volatile__("sta %%g0, [%%g0] %0\n\t" 13362306a36Sopenharmony_ci : /* no outputs */ 13462306a36Sopenharmony_ci : "i" (ASI_M_FLUSH_IWHOLE) 13562306a36Sopenharmony_ci : "memory"); 13662306a36Sopenharmony_ci return; 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ciextern int vac_cache_size; 14062306a36Sopenharmony_ciextern int vac_line_size; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic inline void hyper_clear_all_tags(void) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci unsigned long addr; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci for(addr = 0; addr < vac_cache_size; addr += vac_line_size) 14762306a36Sopenharmony_ci __asm__ __volatile__("sta %%g0, [%0] %1\n\t" 14862306a36Sopenharmony_ci : /* no outputs */ 14962306a36Sopenharmony_ci : "r" (addr), "i" (ASI_M_DATAC_TAG) 15062306a36Sopenharmony_ci : "memory"); 15162306a36Sopenharmony_ci} 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_cistatic inline void hyper_flush_unconditional_combined(void) 15462306a36Sopenharmony_ci{ 15562306a36Sopenharmony_ci unsigned long addr; 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci for (addr = 0; addr < vac_cache_size; addr += vac_line_size) 15862306a36Sopenharmony_ci __asm__ __volatile__("sta %%g0, [%0] %1\n\t" 15962306a36Sopenharmony_ci : /* no outputs */ 16062306a36Sopenharmony_ci : "r" (addr), "i" (ASI_M_FLUSH_CTX) 16162306a36Sopenharmony_ci : "memory"); 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic inline void hyper_flush_cache_user(void) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci unsigned long addr; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci for (addr = 0; addr < vac_cache_size; addr += vac_line_size) 16962306a36Sopenharmony_ci __asm__ __volatile__("sta %%g0, [%0] %1\n\t" 17062306a36Sopenharmony_ci : /* no outputs */ 17162306a36Sopenharmony_ci : "r" (addr), "i" (ASI_M_FLUSH_USER) 17262306a36Sopenharmony_ci : "memory"); 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_cistatic inline void hyper_flush_cache_page(unsigned long page) 17662306a36Sopenharmony_ci{ 17762306a36Sopenharmony_ci unsigned long end; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci page &= PAGE_MASK; 18062306a36Sopenharmony_ci end = page + PAGE_SIZE; 18162306a36Sopenharmony_ci while (page < end) { 18262306a36Sopenharmony_ci __asm__ __volatile__("sta %%g0, [%0] %1\n\t" 18362306a36Sopenharmony_ci : /* no outputs */ 18462306a36Sopenharmony_ci : "r" (page), "i" (ASI_M_FLUSH_PAGE) 18562306a36Sopenharmony_ci : "memory"); 18662306a36Sopenharmony_ci page += vac_line_size; 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci#endif /* !(__ASSEMBLY__) */ 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci#endif /* !(_SPARC_ROSS_H) */ 193