1 /*        $NetBSD: cache_octeon.h,v 1.5 2020/07/26 08:08:41 simonb Exp $        */
2 
3 #ifndef _MIPS_CACHE_OCTEON_H_
4 #define   _MIPS_CACHE_OCTEON_H_
5 
6 #define   CACHE_OCTEON_I                          0
7 #define   CACHE_OCTEON_D                          1
8 
9 #define   CACHEOP_OCTEON_INV_ALL                            (0 << 2)  /* I, D */
10 #define   CACHEOP_OCTEON_INDEX_LOAD_TAG           (1 << 2)  /* I, D */
11 #define   CACHEOP_OCTEON_BITMAP_STORE             (3 << 2)  /* I */
12 #define   CACHEOP_OCTEON_VIRTUAL_TAG_INV                    (4 << 2)  /* D */
13 
14 #define   OCTEON_CACHELINE_SIZE                             128
15 
16 /*
17  * Note that for the Dcache the 50XX manual says 1 set per way (Config1
18  * register - DS=0 ("... actual is 1"), p173) as does U-boot sources,
19  * however this only adds up to an 8kB Dcache.  The 50XX manual
20  * elsewhere references a 16kB Dcache as does the CN50XX product brief.
21  * The original NetBSD code, current OpenBSD and Linux code all use 2
22  * sets per way. lmbench's "cache" program also detects a 16kB Dcache.
23  * So we assume that all Octeon 1 and Octeon Plus cores have a 16kB
24  * Dcache.
25  */
26 #define   OCTEON_I_DCACHE_WAYS                              64
27 #define   OCTEON_I_DCACHE_SETS                              2
28 
29 #define   OCTEON_II_DCACHE_SETS                             8
30 #define   OCTEON_II_DCACHE_WAYS                             32
31 #define   OCTEON_II_ICACHE_SETS                             8
32 #define   OCTEON_II_ICACHE_WAYS                             37
33 
34 #define   OCTEON_III_DCACHE_SETS                            8
35 #define   OCTEON_III_DCACHE_WAYS                            32
36 #define   OCTEON_III_ICACHE_SETS                            16
37 #define   OCTEON_III_ICACHE_WAYS                            39
38 
39 #if !defined(_LOCORE)
40 
41 /*
42  * cache_octeon_invalidate:
43  *
44  *        Invalidate all cache blocks.
45  *        Argument "op" must be CACHE_OCTEON_I or CACHE_OCTEON_D.
46  *        In Octeon specification, invalidate instruction works
47  *        all cache blocks.
48  */
49 #define   cache_octeon_invalidate(op)                                           \
50 do {                                                                                      \
51           __asm __volatile(                                                     \
52                     ".set noreorder                                             \n\t"     \
53                     "cache %0, 0($0)                                  \n\t"     \
54                     ".set reorder"                                                        \
55               :                                                                           \
56               : "i" (op)                                                                  \
57               : "memory");                                                      \
58 } while (/*CONSTCOND*/0)
59 
60 /*
61  * cache_octeon_op_line:
62  *
63  *        Perform the specified cache operation on a single line.
64  */
65 #define   cache_op_octeon_line(va, op)                                          \
66 do {                                                                                      \
67           __asm __volatile(                                                     \
68                     ".set noreorder                                             \n\t"     \
69                     "cache %1, 0(%0)                                  \n\t"     \
70                     ".set reorder"                                                        \
71               :                                                                           \
72               : "r" (va), "i" (op)                                              \
73               : "memory");                                                      \
74 } while (/*CONSTCOND*/0)
75 
76 void octeon_icache_sync_all(void);
77 void octeon_icache_sync_range(register_t va, vsize_t size);
78 void octeon_icache_sync_range_index(vaddr_t va, vsize_t size);
79 void octeon_pdcache_inv_all(void);
80 void octeon_pdcache_inv_range(register_t va, vsize_t size);
81 void octeon_pdcache_inv_range_index(vaddr_t va, vsize_t size);
82 void octeon_pdcache_wb_range(register_t va, vsize_t size);
83 
84 #endif /* !_LOCORE */
85 #endif /* _MIPS_CACHE_OCTEON_H_ */
86