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