| /* Copyright (C) 1992-2024 Free Software Foundation, Inc. |
| |
| This file is part of GDB. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #include "target-dcache.h" |
| #include "progspace.h" |
| #include "cli/cli-cmds.h" |
| |
| /* The target dcache is kept per-address-space. This key lets us |
| associate the cache with the address space. */ |
| |
| static const registry<address_space>::key<DCACHE, dcache_deleter> |
| target_dcache_aspace_key; |
| |
| /* Target dcache is initialized or not. */ |
| |
| int |
| target_dcache_init_p (address_space_ref_ptr aspace) |
| { |
| DCACHE *dcache |
| = target_dcache_aspace_key.get (aspace.get ()); |
| |
| return (dcache != NULL); |
| } |
| |
| /* Invalidate the target dcache. */ |
| |
| void |
| target_dcache_invalidate (address_space_ref_ptr aspace) |
| { |
| DCACHE *dcache |
| = target_dcache_aspace_key.get (aspace.get ()); |
| |
| if (dcache != NULL) |
| dcache_invalidate (dcache); |
| } |
| |
| /* Return the target dcache. Return NULL if target dcache is not |
| initialized yet. */ |
| |
| DCACHE * |
| target_dcache_get (address_space_ref_ptr aspace) |
| { |
| return target_dcache_aspace_key.get (aspace.get ()); |
| } |
| |
| /* Return the target dcache. If it is not initialized yet, initialize |
| it. */ |
| |
| DCACHE * |
| target_dcache_get_or_init (address_space_ref_ptr aspace) |
| { |
| DCACHE *dcache |
| = target_dcache_aspace_key.get (aspace.get ()); |
| |
| if (dcache == NULL) |
| { |
| dcache = dcache_init (); |
| target_dcache_aspace_key.set (aspace.get (), dcache); |
| } |
| |
| return dcache; |
| } |
| |
| /* The option sets this. */ |
| static bool stack_cache_enabled_1 = true; |
| /* And set_stack_cache updates this. |
| The reason for the separation is so that we don't flush the cache for |
| on->on transitions. */ |
| static int stack_cache_enabled = 1; |
| |
| /* This is called *after* the stack-cache has been set. |
| Flush the cache for off->on and on->off transitions. |
| There's no real need to flush the cache for on->off transitions, |
| except cleanliness. */ |
| |
| static void |
| set_stack_cache (const char *args, int from_tty, struct cmd_list_element *c) |
| { |
| if (stack_cache_enabled != stack_cache_enabled_1) |
| target_dcache_invalidate (current_program_space->aspace); |
| |
| stack_cache_enabled = stack_cache_enabled_1; |
| } |
| |
| static void |
| show_stack_cache (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, _("Cache use for stack accesses is %s.\n"), value); |
| } |
| |
| /* Return true if "stack cache" is enabled, otherwise, return false. */ |
| |
| int |
| stack_cache_enabled_p (void) |
| { |
| return stack_cache_enabled; |
| } |
| |
| /* The option sets this. */ |
| |
| static bool code_cache_enabled_1 = true; |
| |
| /* And set_code_cache updates this. |
| The reason for the separation is so that we don't flush the cache for |
| on->on transitions. */ |
| static int code_cache_enabled = 1; |
| |
| /* This is called *after* the code-cache has been set. |
| Flush the cache for off->on and on->off transitions. |
| There's no real need to flush the cache for on->off transitions, |
| except cleanliness. */ |
| |
| static void |
| set_code_cache (const char *args, int from_tty, struct cmd_list_element *c) |
| { |
| if (code_cache_enabled != code_cache_enabled_1) |
| target_dcache_invalidate (current_program_space->aspace); |
| |
| code_cache_enabled = code_cache_enabled_1; |
| } |
| |
| /* Show option "code-cache". */ |
| |
| static void |
| show_code_cache (struct ui_file *file, int from_tty, |
| struct cmd_list_element *c, const char *value) |
| { |
| gdb_printf (file, _("Cache use for code accesses is %s.\n"), value); |
| } |
| |
| /* Return true if "code cache" is enabled, otherwise, return false. */ |
| |
| int |
| code_cache_enabled_p (void) |
| { |
| return code_cache_enabled; |
| } |
| |
| /* Implement the 'maint flush dcache' command. */ |
| |
| static void |
| maint_flush_dcache_command (const char *command, int from_tty) |
| { |
| target_dcache_invalidate (current_program_space->aspace); |
| if (from_tty) |
| gdb_printf (_("The dcache was flushed.\n")); |
| } |
| |
| void _initialize_target_dcache (); |
| void |
| _initialize_target_dcache () |
| { |
| add_setshow_boolean_cmd ("stack-cache", class_support, |
| &stack_cache_enabled_1, _("\ |
| Set cache use for stack access."), _("\ |
| Show cache use for stack access."), _("\ |
| When on, use the target memory cache for all stack access, regardless of any\n\ |
| configured memory regions. This improves remote performance significantly.\n\ |
| By default, caching for stack access is on."), |
| set_stack_cache, |
| show_stack_cache, |
| &setlist, &showlist); |
| |
| add_setshow_boolean_cmd ("code-cache", class_support, |
| &code_cache_enabled_1, _("\ |
| Set cache use for code segment access."), _("\ |
| Show cache use for code segment access."), _("\ |
| When on, use the target memory cache for all code segment accesses,\n\ |
| regardless of any configured memory regions. This improves remote\n\ |
| performance significantly. By default, caching for code segment\n\ |
| access is on."), |
| set_code_cache, |
| show_code_cache, |
| &setlist, &showlist); |
| |
| add_cmd ("dcache", class_maintenance, maint_flush_dcache_command, |
| _("\ |
| Force gdb to flush its target memory data cache.\n\ |
| \n\ |
| The dcache caches all target memory accesses where possible, this\n\ |
| includes the stack-cache and the code-cache."), |
| &maintenanceflushlist); |
| } |