at v2.6.21 4.0 kB view raw
1/* $Id: cache.h,v 1.9 1999/08/14 03:51:58 anton Exp $ 2 * cache.h: Cache specific code for the Sparc. These include flushing 3 * and direct tag/data line access. 4 * 5 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 6 */ 7 8#ifndef _SPARC_CACHE_H 9#define _SPARC_CACHE_H 10 11#include <asm/asi.h> 12 13#define L1_CACHE_SHIFT 5 14#define L1_CACHE_BYTES 32 15#define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) 16 17#define SMP_CACHE_BYTES 32 18 19/* Direct access to the instruction cache is provided through and 20 * alternate address space. The IDC bit must be off in the ICCR on 21 * HyperSparcs for these accesses to work. The code below does not do 22 * any checking, the caller must do so. These routines are for 23 * diagnostics only, but could end up being useful. Use with care. 24 * Also, you are asking for trouble if you execute these in one of the 25 * three instructions following a %asr/%psr access or modification. 26 */ 27 28/* First, cache-tag access. */ 29static inline unsigned int get_icache_tag(int setnum, int tagnum) 30{ 31 unsigned int vaddr, retval; 32 33 vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); 34 __asm__ __volatile__("lda [%1] %2, %0\n\t" : 35 "=r" (retval) : 36 "r" (vaddr), "i" (ASI_M_TXTC_TAG)); 37 return retval; 38} 39 40static inline void put_icache_tag(int setnum, int tagnum, unsigned int entry) 41{ 42 unsigned int vaddr; 43 44 vaddr = ((setnum&1) << 12) | ((tagnum&0x7f) << 5); 45 __asm__ __volatile__("sta %0, [%1] %2\n\t" : : 46 "r" (entry), "r" (vaddr), "i" (ASI_M_TXTC_TAG) : 47 "memory"); 48} 49 50/* Second cache-data access. The data is returned two-32bit quantities 51 * at a time. 52 */ 53static inline void get_icache_data(int setnum, int tagnum, int subblock, 54 unsigned int *data) 55{ 56 unsigned int value1, value2, vaddr; 57 58 vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | 59 ((subblock&0x3) << 3); 60 __asm__ __volatile__("ldda [%2] %3, %%g2\n\t" 61 "or %%g0, %%g2, %0\n\t" 62 "or %%g0, %%g3, %1\n\t" : 63 "=r" (value1), "=r" (value2) : 64 "r" (vaddr), "i" (ASI_M_TXTC_DATA) : 65 "g2", "g3"); 66 data[0] = value1; data[1] = value2; 67} 68 69static inline void put_icache_data(int setnum, int tagnum, int subblock, 70 unsigned int *data) 71{ 72 unsigned int value1, value2, vaddr; 73 74 vaddr = ((setnum&0x1) << 12) | ((tagnum&0x7f) << 5) | 75 ((subblock&0x3) << 3); 76 value1 = data[0]; value2 = data[1]; 77 __asm__ __volatile__("or %%g0, %0, %%g2\n\t" 78 "or %%g0, %1, %%g3\n\t" 79 "stda %%g2, [%2] %3\n\t" : : 80 "r" (value1), "r" (value2), 81 "r" (vaddr), "i" (ASI_M_TXTC_DATA) : 82 "g2", "g3", "memory" /* no joke */); 83} 84 85/* Different types of flushes with the ICACHE. Some of the flushes 86 * affect both the ICACHE and the external cache. Others only clear 87 * the ICACHE entries on the cpu itself. V8's (most) allow 88 * granularity of flushes on the packet (element in line), whole line, 89 * and entire cache (ie. all lines) level. The ICACHE only flushes are 90 * ROSS HyperSparc specific and are in ross.h 91 */ 92 93/* Flushes which clear out both the on-chip and external caches */ 94static inline void flush_ei_page(unsigned int addr) 95{ 96 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : 97 "r" (addr), "i" (ASI_M_FLUSH_PAGE) : 98 "memory"); 99} 100 101static inline void flush_ei_seg(unsigned int addr) 102{ 103 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : 104 "r" (addr), "i" (ASI_M_FLUSH_SEG) : 105 "memory"); 106} 107 108static inline void flush_ei_region(unsigned int addr) 109{ 110 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : 111 "r" (addr), "i" (ASI_M_FLUSH_REGION) : 112 "memory"); 113} 114 115static inline void flush_ei_ctx(unsigned int addr) 116{ 117 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : 118 "r" (addr), "i" (ASI_M_FLUSH_CTX) : 119 "memory"); 120} 121 122static inline void flush_ei_user(unsigned int addr) 123{ 124 __asm__ __volatile__("sta %%g0, [%0] %1\n\t" : : 125 "r" (addr), "i" (ASI_M_FLUSH_USER) : 126 "memory"); 127} 128 129#endif /* !(_SPARC_CACHE_H) */