Home | History | Annotate | Line # | Download | only in mips
cache_octeon.c revision 1.1
      1  1.1  hikaru /*	$NetBSD: cache_octeon.c,v 1.1 2015/04/29 08:32:00 hikaru Exp $	*/
      2  1.1  hikaru 
      3  1.1  hikaru #include <sys/cdefs.h>
      4  1.1  hikaru __KERNEL_RCSID(0, "$NetBSD: cache_octeon.c,v 1.1 2015/04/29 08:32:00 hikaru Exp $");
      5  1.1  hikaru 
      6  1.1  hikaru #include <sys/param.h>
      7  1.1  hikaru #include <sys/systm.h>
      8  1.1  hikaru 
      9  1.1  hikaru #include <mips/cache.h>
     10  1.1  hikaru #include <mips/cache_octeon.h>
     11  1.1  hikaru 
     12  1.1  hikaru #define	SYNC	__asm volatile("sync")
     13  1.1  hikaru 
     14  1.1  hikaru __asm(".set mips3");
     15  1.1  hikaru 
     16  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     17  1.1  hikaru int octeon_cache_debug;
     18  1.1  hikaru #endif
     19  1.1  hikaru 
     20  1.1  hikaru void
     21  1.1  hikaru octeon_icache_sync_all(void)
     22  1.1  hikaru {
     23  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     24  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     25  1.1  hikaru 		printf("%s\n", __func__);
     26  1.1  hikaru #endif
     27  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_I);
     28  1.1  hikaru 	SYNC;
     29  1.1  hikaru }
     30  1.1  hikaru void
     31  1.1  hikaru octeon_icache_sync_range(vaddr_t va, vsize_t size)
     32  1.1  hikaru {
     33  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     34  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     35  1.1  hikaru 		printf("%s: va=0x%08x, size=0x%08x\n", __func__, (int)va, (int)size);
     36  1.1  hikaru #endif
     37  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_I);
     38  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_I);
     39  1.1  hikaru 	SYNC;
     40  1.1  hikaru }
     41  1.1  hikaru void
     42  1.1  hikaru octeon_icache_sync_range_index(vaddr_t va, vsize_t size)
     43  1.1  hikaru {
     44  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     45  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     46  1.1  hikaru 		printf("%s: va=0x%08x, size=0x%08x\n", __func__, (int)va, (int)size);
     47  1.1  hikaru #endif
     48  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_I);
     49  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_I);
     50  1.1  hikaru }
     51  1.1  hikaru void
     52  1.1  hikaru octeon_pdcache_inv_all(void)
     53  1.1  hikaru {
     54  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     55  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     56  1.1  hikaru 		printf("%s\n", __func__);
     57  1.1  hikaru #endif
     58  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_D);
     59  1.1  hikaru 	SYNC;
     60  1.1  hikaru }
     61  1.1  hikaru void
     62  1.1  hikaru octeon_pdcache_inv_range(vaddr_t va, vsize_t size)
     63  1.1  hikaru {
     64  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     65  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     66  1.1  hikaru 		printf("%s: va=0x%08x, size=0x%08x\n", __func__, (int)va, (int)size);
     67  1.1  hikaru #endif
     68  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_D);
     69  1.1  hikaru 	SYNC;
     70  1.1  hikaru }
     71  1.1  hikaru void
     72  1.1  hikaru octeon_pdcache_inv_range_index(vaddr_t va, vsize_t size)
     73  1.1  hikaru {
     74  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     75  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     76  1.1  hikaru 		printf("%s: va=0x%08x, size=0x%08x\n", __func__, (int)va, (int)size);
     77  1.1  hikaru #endif
     78  1.1  hikaru 	cache_octeon_invalidate(CACHEOP_OCTEON_INV_ALL | CACHE_OCTEON_D);
     79  1.1  hikaru }
     80  1.1  hikaru void
     81  1.1  hikaru octeon_pdcache_wb_range(vaddr_t va, vsize_t size)
     82  1.1  hikaru {
     83  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     84  1.1  hikaru 	if (__predict_false(octeon_cache_debug != 0))
     85  1.1  hikaru 		printf("%s: va=0x%08x, size=0x%08x\n", __func__, (int)va, (int)size);
     86  1.1  hikaru #endif
     87  1.1  hikaru }
     88  1.1  hikaru 
     89  1.1  hikaru /* ---- debug dump */
     90  1.1  hikaru 
     91  1.1  hikaru #ifdef OCTEON_ICACHE_DEBUG
     92  1.1  hikaru 
     93  1.1  hikaru #ifndef __BIT
     94  1.1  hikaru /* __BIT(n): nth bit, where __BIT(0) == 0x1. */
     95  1.1  hikaru #define __BIT(__n)	\
     96  1.1  hikaru 	(((__n) >= NBBY * sizeof(uintmax_t)) ? 0 : ((uintmax_t)1 << (__n)))
     97  1.1  hikaru 
     98  1.1  hikaru /* __BITS(m, n): bits m through n, m < n. */
     99  1.1  hikaru #define __BITS(__m, __n)	\
    100  1.1  hikaru 	((__BIT(MAX((__m), (__n)) + 1) - 1) ^ (__BIT(MIN((__m), (__n))) - 1))
    101  1.1  hikaru #endif
    102  1.1  hikaru 
    103  1.1  hikaru /* icache: 16KB, 2ways */
    104  1.1  hikaru 
    105  1.1  hikaru #define	OCTEON_ICACHE_VA_WAY(_va)		(((_va) & __BITS(14, 13)) >> 13)
    106  1.1  hikaru #define	OCTEON_ICACHE_VA_INDEX(_va)		(((_va) & __BITS(12,  7)) >>  7)
    107  1.1  hikaru #define	OCTEON_ICACHE_VA_WORD(_va)		(((_va) & __BITS( 6,  3)) >>  3)
    108  1.1  hikaru 
    109  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_R(_taglo)		(((_taglo) & __BITS(63, 62)) >> 62)
    110  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_ASID(_taglo)	(((_taglo) & __BITS(59, 52)) >> 52)
    111  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_TAG(_taglo)		(((_taglo) & __BITS(48, 13)) >> 13)
    112  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_INDEX(_taglo)	(((_taglo) & __BITS(12,  7)) >>  7)
    113  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_G(_taglo)		(((_taglo) & __BITS( 1,  1)) >>  1)
    114  1.1  hikaru #define	OCTEON_ICACHE_TAGLO_VALID(_taglo)	(((_taglo) & __BITS( 0,  0)) >>  0)
    115  1.1  hikaru 
    116  1.1  hikaru /* dcache: 8KB, 64ways */
    117  1.1  hikaru 
    118  1.1  hikaru #define	OCTEON_DCACHE_VA_WAY(_va)		(((_va) & __BITS(12,  7)) >>  7)
    119  1.1  hikaru #define	OCTEON_DCACHE_VA_WORD(_va)		(((_va) & __BITS( 6,  3)) >>  3)
    120  1.1  hikaru 
    121  1.1  hikaru #define	OCTEON_DCACHE_TAGLO_R(_taglo)		(((_taglo) & __BITS(63, 62)) >> 62)
    122  1.1  hikaru #define	OCTEON_DCACHE_TAGLO_ASID(_taglo)	(((_taglo) & __BITS(59, 52)) >> 52)
    123  1.1  hikaru #define	OCTEON_DCACHE_TAGLO_TAG(_taglo)		(((_taglo) & __BITS(48,  7)) >>  7)
    124  1.1  hikaru #define	OCTEON_DCACHE_TAGLO_G(_taglo)		(((_taglo) & __BITS( 1,  1)) >>  1)
    125  1.1  hikaru #define	OCTEON_DCACHE_TAGLO_VALID(_taglo)	(((_taglo) & __BITS( 0,  0)) >>  0)
    126  1.1  hikaru 
    127  1.1  hikaru #define	OCTEON_DCACHE_TAGHI_PTAG(_taghi)	(((_taghi) & __BITS(35,  7)) >>  7)
    128  1.1  hikaru #define	OCTEON_DCACHE_TAGHI_VALID(_taghi)	(((_taghi) & __BITS( 0,  0)) >>  0)
    129  1.1  hikaru 
    130  1.1  hikaru void		octeon_icache_dump_all(void);
    131  1.1  hikaru void		octeon_icache_dump_way(int);
    132  1.1  hikaru void		octeon_icache_dump_index(int, int);
    133  1.1  hikaru void		octeon_icache_dump_va(vaddr_t);
    134  1.1  hikaru void		octeon_dcache_dump_all(void);
    135  1.1  hikaru void		octeon_dcache_dump_way(int);
    136  1.1  hikaru void		octeon_dcache_dump_index(int, int);
    137  1.1  hikaru void		octeon_dcache_dump_va(vaddr_t);
    138  1.1  hikaru 
    139  1.1  hikaru void
    140  1.1  hikaru octeon_icache_dump_all(void)
    141  1.1  hikaru {
    142  1.1  hikaru 	/* way = (0 .. 3) */
    143  1.1  hikaru 	const int maxway = 2;		/* XXX 2 << (14 - 13 + 1) == 4? */
    144  1.1  hikaru 	int way;
    145  1.1  hikaru 
    146  1.1  hikaru 	for (way = 0; way < maxway; way++)
    147  1.1  hikaru 		octeon_icache_dump_way(way);
    148  1.1  hikaru }
    149  1.1  hikaru 
    150  1.1  hikaru void
    151  1.1  hikaru octeon_icache_dump_way(int way)
    152  1.1  hikaru {
    153  1.1  hikaru 	/* index = (0 .. 127) */
    154  1.1  hikaru 	const int maxindex = 64;	/* XXX 2 << (12 - 7 + 1) == 128? */;
    155  1.1  hikaru 	int index;
    156  1.1  hikaru 
    157  1.1  hikaru 	for (index = 0; index < maxindex; index++)
    158  1.1  hikaru 		octeon_icache_dump_index(way, index);
    159  1.1  hikaru }
    160  1.1  hikaru 
    161  1.1  hikaru void
    162  1.1  hikaru octeon_icache_dump_index(int way, int index)
    163  1.1  hikaru {
    164  1.1  hikaru 	const vaddr_t va = (way << 13) | (index << 7);
    165  1.1  hikaru 
    166  1.1  hikaru 	octeon_icache_dump_va(va);
    167  1.1  hikaru }
    168  1.1  hikaru 
    169  1.1  hikaru void
    170  1.1  hikaru octeon_icache_dump_va(vaddr_t va)
    171  1.1  hikaru {
    172  1.1  hikaru 	uint64_t taglo, datalo, datahi;
    173  1.1  hikaru 
    174  1.1  hikaru 	/* icache */
    175  1.1  hikaru 	__asm __volatile (
    176  1.1  hikaru 		"	.set	push			\n"
    177  1.1  hikaru 		"	.set	noreorder		\n"
    178  1.1  hikaru 		"	.set	arch=octeon		\n"
    179  1.1  hikaru 		"	cache	4, 0(%[va])		\n"
    180  1.1  hikaru 		"	dmfc0	%[taglo], $28, 0	\n"
    181  1.1  hikaru 		"	dmfc0	%[datalo], $28, 1	\n"
    182  1.1  hikaru 		"	dmfc0	%[datahi], $29, 1	\n"
    183  1.1  hikaru 		"	.set	pop			\n"
    184  1.1  hikaru 		: [taglo] "=r" (taglo),
    185  1.1  hikaru 		  [datalo] "=r" (datalo),
    186  1.1  hikaru 		  [datahi] "=r" (datahi)
    187  1.1  hikaru 		: [va] "r" (va));
    188  1.1  hikaru 
    189  1.1  hikaru 	printf("%s: va=%08x "
    190  1.1  hikaru 	    "(way=%01x, index=%02x"/* ", word=%01d" */"), "
    191  1.1  hikaru 	    "taglo=%016"PRIx64" "
    192  1.1  hikaru 	    "(R=%01"PRIx64", asid=%02"PRIx64", tag=%09"PRIx64", index=%02"PRIx64", G=%01"PRIx64", valid=%01"PRIx64"), "
    193  1.1  hikaru 	    "datahi=%01"PRIx64", datalo=%016"PRIx64""
    194  1.1  hikaru 	    "\n",
    195  1.1  hikaru 	    __func__,
    196  1.1  hikaru 	    (int)((taglo) & __BITS(48, 7)),	/* (int)va */
    197  1.1  hikaru 	    (int)OCTEON_ICACHE_VA_WAY(va),
    198  1.1  hikaru 	    (int)OCTEON_ICACHE_VA_INDEX(va),
    199  1.1  hikaru 	    /* (int)OCTEON_ICACHE_VA_WORD(va), */
    200  1.1  hikaru 	    taglo,
    201  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_R(taglo),
    202  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_ASID(taglo),
    203  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_TAG(taglo),
    204  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_INDEX(taglo),
    205  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_G(taglo),
    206  1.1  hikaru 	    OCTEON_ICACHE_TAGLO_VALID(taglo),
    207  1.1  hikaru 	    datahi, datalo);
    208  1.1  hikaru }
    209  1.1  hikaru 
    210  1.1  hikaru void
    211  1.1  hikaru octeon_dcache_dump_all(void)
    212  1.1  hikaru {
    213  1.1  hikaru 	/* way = (0 .. 63) */
    214  1.1  hikaru 	const int maxway = 64;
    215  1.1  hikaru 	int way;
    216  1.1  hikaru 
    217  1.1  hikaru 	for (way = 0; way < maxway; way++)
    218  1.1  hikaru 		octeon_dcache_dump_way(way);
    219  1.1  hikaru }
    220  1.1  hikaru 
    221  1.1  hikaru void
    222  1.1  hikaru octeon_dcache_dump_way(int way)
    223  1.1  hikaru {
    224  1.1  hikaru 	/* index = (0 .. 0) */
    225  1.1  hikaru 	const int maxindex = 1;
    226  1.1  hikaru 	int index;
    227  1.1  hikaru 
    228  1.1  hikaru 	for (index = 0; index < maxindex; index++)
    229  1.1  hikaru 		octeon_dcache_dump_index(way, index);
    230  1.1  hikaru }
    231  1.1  hikaru 
    232  1.1  hikaru void
    233  1.1  hikaru octeon_dcache_dump_index(int way, int index)
    234  1.1  hikaru {
    235  1.1  hikaru 	const vaddr_t va = (way << 7);	/* no index in dcache */
    236  1.1  hikaru 
    237  1.1  hikaru 	octeon_dcache_dump_va(va);
    238  1.1  hikaru }
    239  1.1  hikaru 
    240  1.1  hikaru void
    241  1.1  hikaru octeon_dcache_dump_va(vaddr_t va)
    242  1.1  hikaru {
    243  1.1  hikaru 	uint64_t taglo, taghi, datalo, datahi;
    244  1.1  hikaru 
    245  1.1  hikaru 	/* dcache */
    246  1.1  hikaru 	__asm __volatile (
    247  1.1  hikaru 		"	.set	push			\n"
    248  1.1  hikaru 		"	.set	noreorder		\n"
    249  1.1  hikaru 		"	.set	arch=octeon		\n"
    250  1.1  hikaru 		"	cache	5, 0(%[va])		\n"
    251  1.1  hikaru 		"	dmfc0	%[taglo], $28, 2	\n"
    252  1.1  hikaru 		"	dmfc0	%[taghi], $29, 2	\n"
    253  1.1  hikaru 		"	dmfc0	%[datalo], $28, 3	\n"
    254  1.1  hikaru 		"	dmfc0	%[datahi], $29, 3	\n"
    255  1.1  hikaru 		"	.set	pop			\n"
    256  1.1  hikaru 		: [taglo] "=r" (taglo),
    257  1.1  hikaru 		  [taghi] "=r" (taghi),
    258  1.1  hikaru 		  [datalo] "=r" (datalo),
    259  1.1  hikaru 		  [datahi] "=r" (datahi)
    260  1.1  hikaru 		: [va] "r" (va));
    261  1.1  hikaru 
    262  1.1  hikaru 	printf("%s: va=%08x "
    263  1.1  hikaru 	    "(way=%02x"/* ", word=%01d" */"), "
    264  1.1  hikaru 	    "taglo=%016"PRIx64" "
    265  1.1  hikaru 	    "(R=%01"PRIx64", asid=%02"PRIx64", tag=%09"PRIx64", G=%01"PRIx64", valid=%01"PRIx64"), "
    266  1.1  hikaru 	    "taghi=%016"PRIx64" "
    267  1.1  hikaru 	    "(ptag=%08"PRIx64", valid=%01"PRIx64"), "
    268  1.1  hikaru 	    "datahi=%02"PRIx64", datalo=%016"PRIx64""
    269  1.1  hikaru 	    "\n",
    270  1.1  hikaru 	    __func__,
    271  1.1  hikaru 	    (int)((taglo) & __BITS(48, 13)),	/* (int)va */
    272  1.1  hikaru 	    (int)OCTEON_DCACHE_VA_WAY(va),
    273  1.1  hikaru 	    /* (int)OCTEON_DCACHE_VA_WORD(va), */
    274  1.1  hikaru 	    taglo,
    275  1.1  hikaru 	    OCTEON_DCACHE_TAGLO_R(taglo),
    276  1.1  hikaru 	    OCTEON_DCACHE_TAGLO_ASID(taglo),
    277  1.1  hikaru 	    OCTEON_DCACHE_TAGLO_TAG(taglo),
    278  1.1  hikaru 	    OCTEON_DCACHE_TAGLO_G(taglo),
    279  1.1  hikaru 	    OCTEON_DCACHE_TAGLO_VALID(taglo),
    280  1.1  hikaru 	    taghi,
    281  1.1  hikaru 	    OCTEON_DCACHE_TAGHI_PTAG(taghi),
    282  1.1  hikaru 	    OCTEON_DCACHE_TAGHI_VALID(taghi),
    283  1.1  hikaru 	    datahi, datalo);
    284  1.1  hikaru }
    285  1.1  hikaru 
    286  1.1  hikaru #endif	/* OCTEON_ICACHE_DEBUG */
    287