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