Commit | Line | Data |
---|---|---|
3666a048 | 1 | /* Copyright (C) 1992-2021 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" |
ee9812a0 | 22 | #include "cli/cli-cmds.h" |
68c765e2 | 23 | |
b26dfc9a YQ |
24 | /* The target dcache is kept per-address-space. This key lets us |
25 | associate the cache with the address space. */ | |
26 | ||
35632941 TT |
27 | static const struct address_space_key<DCACHE, dcache_deleter> |
28 | target_dcache_aspace_key; | |
68c765e2 YQ |
29 | |
30 | /* Target dcache is initialized or not. */ | |
31 | ||
32 | int | |
33 | target_dcache_init_p (void) | |
34 | { | |
19ba03f4 | 35 | DCACHE *dcache |
35632941 | 36 | = target_dcache_aspace_key.get (current_program_space->aspace); |
b26dfc9a YQ |
37 | |
38 | return (dcache != NULL); | |
68c765e2 YQ |
39 | } |
40 | ||
41 | /* Invalidate the target dcache. */ | |
42 | ||
43 | void | |
44 | target_dcache_invalidate (void) | |
45 | { | |
19ba03f4 | 46 | DCACHE *dcache |
35632941 | 47 | = target_dcache_aspace_key.get (current_program_space->aspace); |
b26dfc9a YQ |
48 | |
49 | if (dcache != NULL) | |
50 | dcache_invalidate (dcache); | |
68c765e2 YQ |
51 | } |
52 | ||
53 | /* Return the target dcache. Return NULL if target dcache is not | |
54 | initialized yet. */ | |
55 | ||
56 | DCACHE * | |
57 | target_dcache_get (void) | |
58 | { | |
35632941 | 59 | return target_dcache_aspace_key.get (current_program_space->aspace); |
68c765e2 YQ |
60 | } |
61 | ||
62 | /* Return the target dcache. If it is not initialized yet, initialize | |
63 | it. */ | |
64 | ||
65 | DCACHE * | |
66 | target_dcache_get_or_init (void) | |
67 | { | |
19ba03f4 | 68 | DCACHE *dcache |
35632941 | 69 | = target_dcache_aspace_key.get (current_program_space->aspace); |
68c765e2 | 70 | |
b26dfc9a | 71 | if (dcache == NULL) |
6b1141e3 YQ |
72 | { |
73 | dcache = dcache_init (); | |
35632941 | 74 | target_dcache_aspace_key.set (current_program_space->aspace, dcache); |
6b1141e3 | 75 | } |
b26dfc9a YQ |
76 | |
77 | return dcache; | |
68c765e2 YQ |
78 | } |
79 | ||
80 | /* The option sets this. */ | |
491144b5 | 81 | static bool stack_cache_enabled_1 = true; |
0fb14d8f | 82 | /* And set_stack_cache updates this. |
68c765e2 YQ |
83 | The reason for the separation is so that we don't flush the cache for |
84 | on->on transitions. */ | |
0fb14d8f | 85 | static int stack_cache_enabled = 1; |
68c765e2 YQ |
86 | |
87 | /* This is called *after* the stack-cache has been set. | |
88 | Flush the cache for off->on and on->off transitions. | |
89 | There's no real need to flush the cache for on->off transitions, | |
90 | except cleanliness. */ | |
91 | ||
92 | static void | |
eb4c3f4a | 93 | set_stack_cache (const char *args, int from_tty, struct cmd_list_element *c) |
68c765e2 | 94 | { |
0fb14d8f | 95 | if (stack_cache_enabled != stack_cache_enabled_1) |
68c765e2 YQ |
96 | target_dcache_invalidate (); |
97 | ||
0fb14d8f | 98 | stack_cache_enabled = stack_cache_enabled_1; |
68c765e2 YQ |
99 | } |
100 | ||
101 | static void | |
0fb14d8f YQ |
102 | show_stack_cache (struct ui_file *file, int from_tty, |
103 | struct cmd_list_element *c, const char *value) | |
68c765e2 YQ |
104 | { |
105 | fprintf_filtered (file, _("Cache use for stack accesses is %s.\n"), value); | |
106 | } | |
107 | ||
108 | /* Return true if "stack cache" is enabled, otherwise, return false. */ | |
109 | ||
110 | int | |
0fb14d8f | 111 | stack_cache_enabled_p (void) |
68c765e2 | 112 | { |
0fb14d8f | 113 | return stack_cache_enabled; |
68c765e2 YQ |
114 | } |
115 | ||
29453a14 YQ |
116 | /* The option sets this. */ |
117 | ||
491144b5 | 118 | static bool code_cache_enabled_1 = true; |
29453a14 YQ |
119 | |
120 | /* And set_code_cache updates this. | |
121 | The reason for the separation is so that we don't flush the cache for | |
122 | on->on transitions. */ | |
123 | static int code_cache_enabled = 1; | |
124 | ||
125 | /* This is called *after* the code-cache has been set. | |
126 | Flush the cache for off->on and on->off transitions. | |
127 | There's no real need to flush the cache for on->off transitions, | |
128 | except cleanliness. */ | |
129 | ||
130 | static void | |
eb4c3f4a | 131 | set_code_cache (const char *args, int from_tty, struct cmd_list_element *c) |
29453a14 YQ |
132 | { |
133 | if (code_cache_enabled != code_cache_enabled_1) | |
134 | target_dcache_invalidate (); | |
135 | ||
136 | code_cache_enabled = code_cache_enabled_1; | |
137 | } | |
138 | ||
139 | /* Show option "code-cache". */ | |
140 | ||
141 | static void | |
142 | show_code_cache (struct ui_file *file, int from_tty, | |
143 | struct cmd_list_element *c, const char *value) | |
144 | { | |
145 | fprintf_filtered (file, _("Cache use for code accesses is %s.\n"), value); | |
146 | } | |
147 | ||
148 | /* Return true if "code cache" is enabled, otherwise, return false. */ | |
149 | ||
150 | int | |
151 | code_cache_enabled_p (void) | |
152 | { | |
153 | return code_cache_enabled; | |
154 | } | |
155 | ||
ee9812a0 AB |
156 | /* Implement the 'maint flush dcache' command. */ |
157 | ||
158 | static void | |
159 | maint_flush_dcache_command (const char *command, int from_tty) | |
160 | { | |
161 | target_dcache_invalidate (); | |
162 | if (from_tty) | |
163 | printf_filtered (_("The dcache was flushed.\n")); | |
164 | } | |
165 | ||
6c265988 | 166 | void _initialize_target_dcache (); |
68c765e2 | 167 | void |
6c265988 | 168 | _initialize_target_dcache () |
68c765e2 YQ |
169 | { |
170 | add_setshow_boolean_cmd ("stack-cache", class_support, | |
0fb14d8f | 171 | &stack_cache_enabled_1, _("\ |
68c765e2 YQ |
172 | Set cache use for stack access."), _("\ |
173 | Show cache use for stack access."), _("\ | |
0fb14d8f | 174 | When on, use the target memory cache for all stack access, regardless of any\n\ |
68c765e2 YQ |
175 | configured memory regions. This improves remote performance significantly.\n\ |
176 | By default, caching for stack access is on."), | |
0fb14d8f YQ |
177 | set_stack_cache, |
178 | show_stack_cache, | |
68c765e2 | 179 | &setlist, &showlist); |
b26dfc9a | 180 | |
29453a14 YQ |
181 | add_setshow_boolean_cmd ("code-cache", class_support, |
182 | &code_cache_enabled_1, _("\ | |
183 | Set cache use for code segment access."), _("\ | |
184 | Show cache use for code segment access."), _("\ | |
185 | When on, use the target memory cache for all code segment accesses,\n\ | |
186 | regardless of any configured memory regions. This improves remote\n\ | |
187 | performance significantly. By default, caching for code segment\n\ | |
188 | access is on."), | |
189 | set_code_cache, | |
190 | show_code_cache, | |
191 | &setlist, &showlist); | |
ee9812a0 AB |
192 | |
193 | add_cmd ("dcache", class_maintenance, maint_flush_dcache_command, | |
194 | _("\ | |
195 | Force gdb to flush its target memory data cache.\n\ | |
196 | \n\ | |
197 | The dcache caches all target memory accesses where possible, this\n\ | |
198 | includes the stack-cache and the code-cache."), | |
199 | &maintenanceflushlist); | |
68c765e2 | 200 | } |