1 /*
2  * Copyright (C) 2014 Imagination Technologies Ltd.
3  * Author: Yann Le Du <ledu@kymasys.com>
4  *
5  * This file incorporates work covered by the following copyright notice:
6  */
7 
8 /**
9  * \file
10  * \brief  Cache functions
11  */
12 /*
13  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
14  *     economic rights: Technische Universität Dresden (Germany)
15  *
16  * This file is part of TUD:OS and distributed under the terms of the
17  * GNU General Public License 2.
18  * Please see the COPYING-GPL-2 file for details.
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  */
29 #ifndef __L4SYS__INCLUDE__ARCH_MIPS__CACHE_H__
30 #define __L4SYS__INCLUDE__ARCH_MIPS__CACHE_H__
31 
32 #include_next <l4/sys/cache.h>
33 #include <l4/sys/ipc.h>
34 #include <l4/sys/consts.h>
35 #include <l4/sys/compiler.h>
36 
37 EXTERN_C void syncICache(unsigned long start, unsigned long size);
38 
39 L4_INLINE int
l4_cache_clean_data(unsigned long start,unsigned long end)40 l4_cache_clean_data(unsigned long start,
41                     unsigned long end) L4_NOTHROW
42 {
43   l4_utcb_t *u = l4_utcb();
44   l4_msg_regs_t *mr = l4_utcb_mr_u(u);
45   mr->mr[0] = 0x21;
46   mr->mr[1] = start;
47   mr->mr[2] = end;
48   return l4_error_u(l4_ipc_call(L4_INVALID_CAP, u,
49                                 l4_msgtag(L4_PROTO_THREAD, 3, 0, 0),
50                                 L4_IPC_NEVER), u);
51 }
52 
53 L4_INLINE int
l4_cache_flush_data(unsigned long start,unsigned long end)54 l4_cache_flush_data(unsigned long start,
55                     unsigned long end) L4_NOTHROW
56 {
57   l4_utcb_t *u = l4_utcb();
58   l4_msg_regs_t *mr = l4_utcb_mr_u(u);
59   mr->mr[0] = 0x20;
60   mr->mr[1] = start;
61   mr->mr[2] = end;
62   return l4_error_u(l4_ipc_call(L4_INVALID_CAP, u,
63                                 l4_msgtag(L4_PROTO_THREAD, 3, 0, 0),
64                                 L4_IPC_NEVER), u);
65 }
66 
67 L4_INLINE int
l4_cache_inv_data(unsigned long start,unsigned long end)68 l4_cache_inv_data(unsigned long start,
69                   unsigned long end) L4_NOTHROW
70 {
71   l4_utcb_t *u = l4_utcb();
72   l4_msg_regs_t *mr = l4_utcb_mr_u(u);
73   mr->mr[0] = 0x22;
74   mr->mr[1] = start;
75   mr->mr[2] = end;
76   return l4_error_u(l4_ipc_call(L4_INVALID_CAP, u,
77                                 l4_msgtag(L4_PROTO_THREAD, 3, 0, 0),
78                                 L4_IPC_NEVER), u);
79 }
80 
81 L4_INLINE int
l4_cache_coherent(unsigned long start,unsigned long end)82 l4_cache_coherent(unsigned long start,
83                   unsigned long end) L4_NOTHROW
84 {
85   unsigned long step;
86   unsigned long i;
87   asm volatile ("rdhwr %0, $1" : "=r"(step));
88 
89   // step may be 0 when instruction caches are disabled
90   if (L4_LIKELY(step > 0))
91     for (i = start & ~(step - 1); i < end; i += step)
92       asm volatile ("synci (%0)" : : "r"(i));
93 
94   asm volatile ("sync");
95   asm volatile (".set push; .set noat; .set noreorder\n"
96 #if (_MIPS_SZLONG == 64)
97                 "dla $1, 1f\n"
98 #else
99                 "la $1, 1f\n"
100 #endif
101                 "jr.hb $1\n"
102                 "  nop\n"
103                 "1: .set pop");
104   return 0;
105 }
106 
107 L4_INLINE int
l4_cache_dma_coherent(unsigned long start,unsigned long end)108 l4_cache_dma_coherent(unsigned long start,
109                       unsigned long end) L4_NOTHROW
110 {
111   (void)start; (void)end;
112   return 0;
113 }
114 
115 L4_INLINE int
l4_cache_dma_coherent_full(void)116 l4_cache_dma_coherent_full(void) L4_NOTHROW
117 {
118   return 0;
119 }
120 
121 #endif /* ! __L4SYS__INCLUDE__ARCH_MIPS__CACHE_H__ */
122