Commit | Line | Data |
---|---|---|
e2882c85 | 1 | /* Copyright (C) 1992-2018 Free Software Foundation, Inc. |
68c765e2 YQ |
2 | |
3 | This file is part of GDB. | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 3 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
17 | ||
18 | #include "defs.h" | |
19 | #include "target-dcache.h" | |
20 | #include "gdbcmd.h" | |
b26dfc9a | 21 | #include "progspace.h" |
68c765e2 | 22 | |
b26dfc9a YQ |
23 | /* The target dcache is kept per-address-space. This key lets us |
24 | associate the cache with the address space. */ | |
25 | ||
26 | static const struct address_space_data *target_dcache_aspace_key; | |
27 | ||
28 | /* Clean up dcache, represented by ARG, which is associated with | |
29 | ASPACE. */ | |
30 | ||
31 | static void | |
32 | target_dcache_cleanup (struct address_space *aspace, void *arg) | |
33 | { | |
19ba03f4 | 34 | dcache_free ((DCACHE *) arg); |
b26dfc9a | 35 | } |
68c765e2 YQ |
36 | |
37 | /* Target dcache is initialized or not. */ | |
38 | ||
39 | int | |
40 | target_dcache_init_p (void) | |
41 | { | |
19ba03f4 SM |
42 | DCACHE *dcache |
43 | = (DCACHE *) address_space_data (current_program_space->aspace, | |
44 | target_dcache_aspace_key); | |
b26dfc9a YQ |
45 | |
46 | return (dcache != NULL); | |
68c765e2 YQ |
47 | } |
48 | ||
49 | /* Invalidate the target dcache. */ | |
50 | ||
51 | void | |
52 | target_dcache_invalidate (void) | |
53 | { | |
19ba03f4 SM |
54 | DCACHE *dcache |
55 | = (DCACHE *) address_space_data (current_program_space->aspace, | |
56 | target_dcache_aspace_key); | |
b26dfc9a YQ |
57 | |
58 | if (dcache != NULL) | |
59 | dcache_invalidate (dcache); | |
68c765e2 YQ |
60 | } |
61 | ||
62 | /* Return the target dcache. Return NULL if target dcache is not | |
63 | initialized yet. */ | |
64 | ||
65 | DCACHE * | |
66 | target_dcache_get (void) | |
67 | { | |
19ba03f4 SM |
68 | DCACHE *dcache |
69 | = (DCACHE *) address_space_data (current_program_space->aspace, | |
70 | target_dcache_aspace_key); | |
b26dfc9a YQ |
71 | |
72 | return dcache; | |
68c765e2 YQ |
73 | } |
74 | ||
75 | /* Return the target dcache. If it is not initialized yet, initialize | |
76 | it. */ | |
77 | ||
78 | DCACHE * | |
79 | target_dcache_get_or_init (void) | |
80 | { | |
19ba03f4 SM |
81 | DCACHE *dcache |
82 | = (DCACHE *) address_space_data (current_program_space->aspace, | |
83 | target_dcache_aspace_key); | |
68c765e2 | 84 | |
b26dfc9a | 85 | if (dcache == NULL) |
6b1141e3 YQ |
86 | { |
87 | dcache = dcache_init (); | |
88 | set_address_space_data (current_program_space->aspace, | |
89 | target_dcache_aspace_key, dcache); | |
90 | } | |
b26dfc9a YQ |
91 | |
92 | return dcache; | |
68c765e2 YQ |
93 | } |
94 | ||
95 | /* The option sets this. */ | |
0fb14d8f YQ |
96 | static int stack_cache_enabled_1 = 1; |
97 | /* And set_stack_cache updates this. | |
68c765e2 YQ |
98 | The reason for the separation is so that we don't flush the cache for |
99 | on->on transitions. */ | |
0fb14d8f | 100 | static int stack_cache_enabled = 1; |
68c765e2 YQ |
101 | |
102 | /* This is called *after* the stack-cache has been set. | |
103 | Flush the cache for off->on and on->off transitions. | |
104 | There's no real need to flush the cache for on->off transitions, | |
105 | except cleanliness. */ | |
106 | ||
107 | static void | |
eb4c3f4a | 108 | set_stack_cache (const char *args, int from_tty, struct cmd_list_element *c) |
68c765e2 | 109 | { |
0fb14d8f | 110 | if (stack_cache_enabled != stack_cache_enabled_1) |
68c765e2 YQ |
111 | target_dcache_invalidate (); |
112 | ||
0fb14d8f | 113 | stack_cache_enabled = stack_cache_enabled_1; |
68c765e2 YQ |
114 | } |
115 | ||
116 | static void | |
0fb14d8f YQ |
117 | show_stack_cache (struct ui_file *file, int from_tty, |
118 | struct cmd_list_element *c, const char *value) | |
68c765e2 YQ |
119 | { |
120 | fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value); | |
121 | } | |
122 | ||
123 | /* Return true if "stack cache" is enabled, otherwise, return false. */ | |
124 | ||
125 | int | |
0fb14d8f | 126 | stack_cache_enabled_p (void) |
68c765e2 | 127 | { |
0fb14d8f | 128 | return stack_cache_enabled; |
68c765e2 YQ |
129 | } |
130 | ||
29453a14 YQ |
131 | /* The option sets this. */ |
132 | ||
133 | static int code_cache_enabled_1 = 1; | |
134 | ||
135 | /* And set_code_cache updates this. | |
136 | The reason for the separation is so that we don't flush the cache for | |
137 | on->on transitions. */ | |
138 | static int code_cache_enabled = 1; | |
139 | ||
140 | /* This is called *after* the code-cache has been set. | |
141 | Flush the cache for off->on and on->off transitions. | |
142 | There's no real need to flush the cache for on->off transitions, | |
143 | except cleanliness. */ | |
144 | ||
145 | static void | |
eb4c3f4a | 146 | set_code_cache (const char *args, int from_tty, struct cmd_list_element *c) |
29453a14 YQ |
147 | { |
148 | if (code_cache_enabled != code_cache_enabled_1) | |
149 | target_dcache_invalidate (); | |
150 | ||
151 | code_cache_enabled = code_cache_enabled_1; | |
152 | } | |
153 | ||
154 | /* Show option "code-cache". */ | |
155 | ||
156 | static void | |
157 | show_code_cache (struct ui_file *file, int from_tty, | |
158 | struct cmd_list_element *c, const char *value) | |
159 | { | |
160 | fprintf_filtered (file, _("Cache use for code accesses is %s.\n"), value); | |
161 | } | |
162 | ||
163 | /* Return true if "code cache" is enabled, otherwise, return false. */ | |
164 | ||
165 | int | |
166 | code_cache_enabled_p (void) | |
167 | { | |
168 | return code_cache_enabled; | |
169 | } | |
170 | ||
68c765e2 YQ |
171 | void |
172 | _initialize_target_dcache (void) | |
173 | { | |
174 | add_setshow_boolean_cmd ("stack-cache", class_support, | |
0fb14d8f | 175 | &stack_cache_enabled_1, _("\ |
68c765e2 YQ |
176 | Set cache use for stack access."), _("\ |
177 | Show cache use for stack access."), _("\ | |
0fb14d8f | 178 | When on, use the target memory cache for all stack access, regardless of any\n\ |
68c765e2 YQ |
179 | configured memory regions. This improves remote performance significantly.\n\ |
180 | By default, caching for stack access is on."), | |
0fb14d8f YQ |
181 | set_stack_cache, |
182 | show_stack_cache, | |
68c765e2 | 183 | &setlist, &showlist); |
b26dfc9a | 184 | |
29453a14 YQ |
185 | add_setshow_boolean_cmd ("code-cache", class_support, |
186 | &code_cache_enabled_1, _("\ | |
187 | Set cache use for code segment access."), _("\ | |
188 | Show cache use for code segment access."), _("\ | |
189 | When on, use the target memory cache for all code segment accesses,\n\ | |
190 | regardless of any configured memory regions. This improves remote\n\ | |
191 | performance significantly. By default, caching for code segment\n\ | |
192 | access is on."), | |
193 | set_code_cache, | |
194 | show_code_cache, | |
195 | &setlist, &showlist); | |
196 | ||
b26dfc9a YQ |
197 | target_dcache_aspace_key |
198 | = register_address_space_data_with_cleanup (NULL, | |
199 | target_dcache_cleanup); | |
68c765e2 | 200 | } |